trout
trout/route.go
Fix some crashes. When adding a branch, make sure that it has any characters at all before checking if it's a variable. Change the Router methods to be on the *Router pointer. We were having some problems with Router methods not setting properties correctly, but this fixed it. Check that the Endpoint.methods map is set before trying to map methods to Handlers. With these changes, trout is complete enough that it can run the benchmarks.
1.1 --- a/route.go Mon Mar 16 00:10:38 2015 -0400 1.2 +++ b/route.go Mon Mar 16 09:39:10 2015 -0400 1.3 @@ -57,7 +57,7 @@ 1.4 Handle405 http.Handler 1.5 } 1.6 1.7 -func (router Router) serve404(w http.ResponseWriter, r *http.Request, t time.Time) { 1.8 +func (router *Router) serve404(w http.ResponseWriter, r *http.Request, t time.Time) { 1.9 h := default404Handler 1.10 if router.Handle404 != nil { 1.11 h = router.Handle404 1.12 @@ -66,7 +66,7 @@ 1.13 h.ServeHTTP(w, r) 1.14 } 1.15 1.16 -func (router Router) serve405(w http.ResponseWriter, r *http.Request, t time.Time) { 1.17 +func (router *Router) serve405(w http.ResponseWriter, r *http.Request, t time.Time) { 1.18 h := default405Handler 1.19 if router.Handle405 != nil { 1.20 h = router.Handle405 1.21 @@ -79,6 +79,7 @@ 1.22 start := time.Now() 1.23 if router.t == nil { 1.24 router.serve404(w, r, start) 1.25 + return 1.26 } 1.27 pieces := strings.Split(strings.ToLower(strings.Trim(r.URL.Path, "/")), "/") 1.28 router.t.RLock() 1.29 @@ -87,6 +88,7 @@ 1.30 path, ok := router.t.match(pieces) 1.31 if !ok { 1.32 router.serve404(w, r, start) 1.33 + return 1.34 } 1.35 b := router.t.branch 1.36 for i, pos := range path { 1.37 @@ -107,6 +109,7 @@ 1.38 h := b.methods[r.Method] 1.39 if h == nil { 1.40 router.serve405(w, r, start) 1.41 + return 1.42 } 1.43 r.Header.Set("Trout-Timer", strconv.FormatInt(time.Now().Sub(start).Nanoseconds(), 10)) 1.44 h.ServeHTTP(w, r) 1.45 @@ -118,10 +121,13 @@ 1.46 // 1.47 // Parameters are always `/`-separated strings. There is no support for regular expressions or other limitations 1.48 // on what may be in those strings. A parameter is simply defined as "whatever is between these two / characters". 1.49 -func (router Router) Endpoint(e string) *Endpoint { 1.50 +func (router *Router) Endpoint(e string) *Endpoint { 1.51 e = strings.Trim(e, "/") 1.52 e = strings.ToLower(e) 1.53 pieces := strings.Split(e, "/") 1.54 + if router.t == nil { 1.55 + router.t = &trie{} 1.56 + } 1.57 router.t.Lock() 1.58 defer router.t.Unlock() 1.59 if router.t.branch == nil { 1.60 @@ -145,7 +151,7 @@ 1.61 for i := offset; i < len(pieces); i++ { 1.62 piece := pieces[i] 1.63 var isParam bool 1.64 - if piece[0:1] == "{" && piece[len(piece)-1:] == "}" { 1.65 + if len(piece) > 0 && piece[0:1] == "{" && piece[len(piece)-1:] == "}" { 1.66 isParam = true 1.67 piece = piece[1 : len(piece)-1] 1.68 } 1.69 @@ -178,7 +184,7 @@ 1.70 for i := 0; i < num; i++ { 1.71 piece := pieces[i] 1.72 var isParam bool 1.73 - if piece[0:1] == "{" && piece[len(piece)-1:] == "}" { 1.74 + if len(piece) > 0 && piece[0:1] == "{" && piece[len(piece)-1:] == "}" { 1.75 isParam = true 1.76 piece = piece[1 : len(piece)-1] 1.77 }