From b864f07c539c7abc16652d65350d070d8e2810de Mon Sep 17 00:00:00 2001 From: Thomas ten Cate Date: Wed, 23 Apr 2014 19:53:35 +0200 Subject: [PATCH] Propagate StrictSlash to subrouters instead of rudely turning it off --- mux.go | 7 ++++--- mux_test.go | 10 ++++++++++ regexp.go | 17 ++++++++++------- route.go | 1 - 4 files changed, 24 insertions(+), 11 deletions(-) diff --git a/mux.go b/mux.go index fa12ffa..8b23c39 100644 --- a/mux.go +++ b/mux.go @@ -119,9 +119,10 @@ func (r *Router) GetRoute(name string) *Route { // When false, if the route path is "/path", accessing "/path/" will not match // this route and vice versa. // -// Special case: when a route sets a path prefix, strict slash is -// automatically set to false for that route because the redirect behavior -// can't be determined for prefixes. +// Special case: when a route sets a path prefix using the PathPrefix() method, +// strict slash is ignored for that route because the redirect behavior can't +// be determined from a prefix alone. However, any subrouters created from that +// route inherit the original StrictSlash setting. func (r *Router) StrictSlash(value bool) *Router { r.strictSlash = value return r diff --git a/mux_test.go b/mux_test.go index 63bc491..0e2e480 100644 --- a/mux_test.go +++ b/mux_test.go @@ -660,6 +660,16 @@ func TestStrictSlash(t *testing.T) { shouldMatch: true, shouldRedirect: false, }, + { + title: "Propagate StrictSlash to subrouters", + route: r.NewRoute().PathPrefix("/static/").Subrouter().Path("/images/"), + request: newRequest("GET", "http://localhost/static/images"), + vars: map[string]string{}, + host: "", + path: "/static/images/", + shouldMatch: true, + shouldRedirect: true, + }, { title: "Ignore StrictSlash for path prefix", route: r.NewRoute().PathPrefix("/static/"), diff --git a/regexp.go b/regexp.go index 4c3482b..925f268 100644 --- a/regexp.go +++ b/regexp.go @@ -98,12 +98,13 @@ func newRouteRegexp(tpl string, matchHost, matchPrefix, strictSlash bool) (*rout } // Done! return &routeRegexp{ - template: template, - matchHost: matchHost, - regexp: reg, - reverse: reverse.String(), - varsN: varsN, - varsR: varsR, + template: template, + matchHost: matchHost, + strictSlash: strictSlash, + regexp: reg, + reverse: reverse.String(), + varsN: varsN, + varsR: varsR, }, nil } @@ -114,6 +115,8 @@ type routeRegexp struct { template string // True for host match, false for path match. matchHost bool + // The strictSlash value defined on the route, but disabled if PathPrefix was used. + strictSlash bool // Expanded regexp. regexp *regexp.Regexp // Reverse template. @@ -216,7 +219,7 @@ func (v *routeRegexpGroup) setMatch(req *http.Request, m *RouteMatch, r *Route) m.Vars[v] = pathVars[k+1] } // Check if we should redirect. - if r.strictSlash { + if v.path.strictSlash { p1 := strings.HasSuffix(req.URL.Path, "/") p2 := strings.HasSuffix(v.path.template, "/") if p1 != p2 { diff --git a/route.go b/route.go index 4ce8c82..5cb2526 100644 --- a/route.go +++ b/route.go @@ -294,7 +294,6 @@ func (r *Route) Path(tpl string) *Route { // Also note that the setting of Router.StrictSlash() has no effect on routes // with a PathPrefix matcher. func (r *Route) PathPrefix(tpl string) *Route { - r.strictSlash = false r.err = r.addRegexpMatcher(tpl, false, true) return r }