diff options
Diffstat (limited to 'vendor/github.com/zenazn/goji/web/bytecode_runner.go')
| -rw-r--r-- | vendor/github.com/zenazn/goji/web/bytecode_runner.go | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/vendor/github.com/zenazn/goji/web/bytecode_runner.go b/vendor/github.com/zenazn/goji/web/bytecode_runner.go new file mode 100644 index 0000000..c32b16a --- /dev/null +++ b/vendor/github.com/zenazn/goji/web/bytecode_runner.go @@ -0,0 +1,83 @@ +package web + +import "net/http" + +type routeMachine struct { + sm stateMachine + routes []route +} + +func matchRoute(route route, m method, ms *method, r *http.Request, c *C) bool { + if !route.pattern.Match(r, c) { + return false + } + *ms |= route.method + + if route.method&m != 0 { + route.pattern.Run(r, c) + return true + } + return false +} + +func (rm routeMachine) route(c *C, w http.ResponseWriter, r *http.Request) (method, *route) { + m := httpMethod(r.Method) + var methods method + p := r.URL.Path + + if len(rm.sm) == 0 { + return methods, nil + } + + var i int + for { + sm := rm.sm[i].mode + if sm&smSetCursor != 0 { + si := rm.sm[i].i + p = r.URL.Path[si:] + i++ + continue + } + + length := int(sm & smLengthMask) + match := false + if length <= len(p) { + bs := rm.sm[i].bs + switch length { + case 3: + if p[2] != bs[2] { + break + } + fallthrough + case 2: + if p[1] != bs[1] { + break + } + fallthrough + case 1: + if p[0] != bs[0] { + break + } + fallthrough + case 0: + p = p[length:] + match = true + } + } + + if match && sm&smRoute != 0 { + si := rm.sm[i].i + if matchRoute(rm.routes[si], m, &methods, r, c) { + return 0, &rm.routes[si] + } + i++ + } else if match != (sm&smJumpOnMatch == 0) { + if sm&smFail != 0 { + return methods, nil + } + i = int(rm.sm[i].i) + } else { + i++ + } + } +} |
