route.go
package vox
import (
"regexp"
)
// Route will register a new path handler to a given path.
func (app *Application) Route(method string, path string, handler Handler) {
// TODO: support string based path
r := routeToRegexp(path)
app.middlewares = append(app.middlewares, func(ctx *Context, req *Request, res *Response) {
if match(req, method, r) {
handler(ctx, req, res)
return
}
ctx.Next()
})
}
func match(req *Request, method string, path *regexp.Regexp) bool {
if req.Method != method && method != "*" {
// TODO(asaka): ignore case?
return false
}
match := path.FindStringSubmatch(req.URL.Path)
if match == nil {
return false
}
for i, name := range path.SubexpNames() {
if i == 0 || name == "" {
continue
}
req.Params[name] = match[i]
}
return true
}
// Get register a new path handler for GET method.
func (app *Application) Get(path string, handler Handler) {
app.Route("GET", path, handler)
}
// Head register a new path handler for HEAD method.
func (app *Application) Head(path string, handler Handler) {
app.Route("HEAD", path, handler)
}
// Post register a new path handler for POST method.
func (app *Application) Post(path string, handler Handler) {
app.Route("POST", path, handler)
}
// Put register a new path handler for PUT method.
func (app *Application) Put(path string, handler Handler) {
app.Route("PUT", path, handler)
}
// Patch register a new path handler for PATCH method.
func (app *Application) Patch(path string, handler Handler) {
app.Route("PATCH", path, handler)
}
// Delete register a new path handler for DELETE method.
func (app *Application) Delete(path string, handler Handler) {
app.Route("DELETE", path, handler)
}
// Options register a new path handler for OPTIONS method.
func (app *Application) Options(path string, handler Handler) {
app.Route("OPTIONS", path, handler)
}
// Trace register a new path handler for TRACE method.
func (app *Application) Trace(path string, handler Handler) {
app.Route("TRACE", path, handler)
}
func routeToRegexp(path string) *regexp.Regexp {
replaced := regexp.MustCompile(`{(?P<param>\w+)}`).ReplaceAllStringFunc(path, func(s string) string {
return "(?P<" + s[1:len(s)-1] + ">[-_.\\p{Lu}\\p{Ll}0-9]+)"
})
return regexp.MustCompile("^" + replaced + "$")
}