Skip to content

Instantly share code, notes, and snippets.

@icholy
Last active February 17, 2018 20:04
Show Gist options
  • Save icholy/d4e911966829725e92faaf53e2fdeb17 to your computer and use it in GitHub Desktop.
Save icholy/d4e911966829725e92faaf53e2fdeb17 to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"net/http"
"net/http/cgi"
"os"
)
type Handler func(http.ResponseWriter, *http.Request)
type Params map[string]string
func (p Params) Matches(req *http.Request) bool {
values := req.URL.Query()
for k, v := range p {
if values.Get(k) != v {
return false
}
}
return true
}
type Route struct {
Method string
Params Params
Handler Handler
}
func (r *Route) Matches(req *http.Request) bool {
if r.Method != "" && r.Method != req.Method {
return false
}
if r.Params != nil {
return r.Params.Matches(req)
}
return true
}
type Router struct {
Routes []Route
NotFound Handler
}
var DefaultNotFound = func(w http.ResponseWriter, _ *http.Request) {
http.Error(w, "not found", http.StatusNotFound)
}
func NewRouter() *Router {
return &Router{NotFound: DefaultNotFound}
}
func (r *Router) Method(name string, h Handler, p Params) {
r.Routes = append(r.Routes, Route{name, p, h})
}
func (r *Router) Get(h Handler, p Params) { r.Method("GET", h) }
func (r *Router) Post(h Handler, p Params) { r.Method("POST", h, p) }
func (r *Router) Put(h Handler, p Params) { r.Method("PUT", h, p) }
func (r *Router) Delete(h Handler, p Params) { r.Method("DELETE", h, p) }
func (r *Router) Any(h Handler, p Params) { r.Method("", h, p) }
func (r *Router) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
for _, rt := range r.Routes {
if rt.Matches(req) {
rt.Handler(rw, req)
return
}
}
r.NotFound(rw, req)
}
func main() {
mux := NewRouter()
mux.Post(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "hello world")
}, Params{"thing": "foo"})
mux.Delete(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "what what in the butt")
}, Params{"thing": "bar"})
mux.Put(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "put it somewhere else")
}, nil)
if err := cgi.Serve(mux); err != nil {
fmt.Println(os.Stderr, err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment