Browse Source

Propagate StrictSlash to subrouters instead of rudely turning it off

Thomas ten Cate 12 years ago
parent
commit
b864f07c53
4 changed files with 24 additions and 11 deletions
  1. +4
    -3
      mux.go
  2. +10
    -0
      mux_test.go
  3. +10
    -7
      regexp.go
  4. +0
    -1
      route.go

+ 4
- 3
mux.go View File

@ -119,9 +119,10 @@ func (r *Router) GetRoute(name string) *Route {
// When false, if the route path is "/path", accessing "/path/" will not match // When false, if the route path is "/path", accessing "/path/" will not match
// this route and vice versa. // 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 { func (r *Router) StrictSlash(value bool) *Router {
r.strictSlash = value r.strictSlash = value
return r return r


+ 10
- 0
mux_test.go View File

@ -660,6 +660,16 @@ func TestStrictSlash(t *testing.T) {
shouldMatch: true, shouldMatch: true,
shouldRedirect: false, 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", title: "Ignore StrictSlash for path prefix",
route: r.NewRoute().PathPrefix("/static/"), route: r.NewRoute().PathPrefix("/static/"),


+ 10
- 7
regexp.go View File

@ -98,12 +98,13 @@ func newRouteRegexp(tpl string, matchHost, matchPrefix, strictSlash bool) (*rout
} }
// Done! // Done!
return &routeRegexp{ 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 }, nil
} }
@ -114,6 +115,8 @@ type routeRegexp struct {
template string template string
// True for host match, false for path match. // True for host match, false for path match.
matchHost bool matchHost bool
// The strictSlash value defined on the route, but disabled if PathPrefix was used.
strictSlash bool
// Expanded regexp. // Expanded regexp.
regexp *regexp.Regexp regexp *regexp.Regexp
// Reverse template. // Reverse template.
@ -216,7 +219,7 @@ func (v *routeRegexpGroup) setMatch(req *http.Request, m *RouteMatch, r *Route)
m.Vars[v] = pathVars[k+1] m.Vars[v] = pathVars[k+1]
} }
// Check if we should redirect. // Check if we should redirect.
if r.strictSlash {
if v.path.strictSlash {
p1 := strings.HasSuffix(req.URL.Path, "/") p1 := strings.HasSuffix(req.URL.Path, "/")
p2 := strings.HasSuffix(v.path.template, "/") p2 := strings.HasSuffix(v.path.template, "/")
if p1 != p2 { if p1 != p2 {


+ 0
- 1
route.go View File

@ -294,7 +294,6 @@ func (r *Route) Path(tpl string) *Route {
// Also note that the setting of Router.StrictSlash() has no effect on routes // Also note that the setting of Router.StrictSlash() has no effect on routes
// with a PathPrefix matcher. // with a PathPrefix matcher.
func (r *Route) PathPrefix(tpl string) *Route { func (r *Route) PathPrefix(tpl string) *Route {
r.strictSlash = false
r.err = r.addRegexpMatcher(tpl, false, true) r.err = r.addRegexpMatcher(tpl, false, true)
return r return r
} }


Loading…
Cancel
Save