mirror of https://github.com/mpolden/echoip
74 lines
1.4 KiB
Go
74 lines
1.4 KiB
Go
package http
|
|
|
|
import (
|
|
"net/http"
|
|
"strings"
|
|
)
|
|
|
|
type router struct {
|
|
routes []*route
|
|
}
|
|
|
|
type route struct {
|
|
method string
|
|
path string
|
|
prefix bool
|
|
handler appHandler
|
|
matcherFunc func(*http.Request) bool
|
|
}
|
|
|
|
func NewRouter() *router {
|
|
return &router{}
|
|
}
|
|
|
|
func (r *router) Route(method, path string, handler appHandler) *route {
|
|
route := route{
|
|
method: method,
|
|
path: path,
|
|
handler: handler,
|
|
}
|
|
r.routes = append(r.routes, &route)
|
|
return &route
|
|
}
|
|
|
|
func (r *router) RoutePrefix(method, path string, handler appHandler) *route {
|
|
route := r.Route(method, path, handler)
|
|
route.prefix = true
|
|
return route
|
|
}
|
|
|
|
func (r *router) Handler() http.Handler {
|
|
return appHandler(func(w http.ResponseWriter, req *http.Request) *appError {
|
|
for _, route := range r.routes {
|
|
if route.match(req) {
|
|
return route.handler(w, req)
|
|
}
|
|
}
|
|
return NotFoundHandler(w, req)
|
|
})
|
|
}
|
|
|
|
func (r *route) Header(header, value string) {
|
|
r.MatcherFunc(func(req *http.Request) bool {
|
|
return req.Header.Get(header) == value
|
|
})
|
|
}
|
|
|
|
func (r *route) MatcherFunc(f func(*http.Request) bool) {
|
|
r.matcherFunc = f
|
|
}
|
|
|
|
func (r *route) match(req *http.Request) bool {
|
|
if req.Method != r.method {
|
|
return false
|
|
}
|
|
if r.prefix {
|
|
if !strings.HasPrefix(req.URL.Path, r.path) {
|
|
return false
|
|
}
|
|
} else if r.path != req.URL.Path {
|
|
return false
|
|
}
|
|
return r.matcherFunc == nil || r.matcherFunc(req)
|
|
}
|