Skip to content

Commit b864f07

Browse files
committed
Propagate StrictSlash to subrouters instead of rudely turning it off
1 parent 3509745 commit b864f07

File tree

4 files changed

+24
-11
lines changed

4 files changed

+24
-11
lines changed

mux.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,10 @@ func (r *Router) GetRoute(name string) *Route {
119119
// When false, if the route path is "/path", accessing "/path/" will not match
120120
// this route and vice versa.
121121
//
122-
// Special case: when a route sets a path prefix, strict slash is
123-
// automatically set to false for that route because the redirect behavior
124-
// can't be determined for prefixes.
122+
// Special case: when a route sets a path prefix using the PathPrefix() method,
123+
// strict slash is ignored for that route because the redirect behavior can't
124+
// be determined from a prefix alone. However, any subrouters created from that
125+
// route inherit the original StrictSlash setting.
125126
func (r *Router) StrictSlash(value bool) *Router {
126127
r.strictSlash = value
127128
return r

mux_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -660,6 +660,16 @@ func TestStrictSlash(t *testing.T) {
660660
shouldMatch: true,
661661
shouldRedirect: false,
662662
},
663+
{
664+
title: "Propagate StrictSlash to subrouters",
665+
route: r.NewRoute().PathPrefix("/static/").Subrouter().Path("/images/"),
666+
request: newRequest("GET", "http://localhost/static/images"),
667+
vars: map[string]string{},
668+
host: "",
669+
path: "/static/images/",
670+
shouldMatch: true,
671+
shouldRedirect: true,
672+
},
663673
{
664674
title: "Ignore StrictSlash for path prefix",
665675
route: r.NewRoute().PathPrefix("/static/"),

regexp.go

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,13 @@ func newRouteRegexp(tpl string, matchHost, matchPrefix, strictSlash bool) (*rout
9898
}
9999
// Done!
100100
return &routeRegexp{
101-
template: template,
102-
matchHost: matchHost,
103-
regexp: reg,
104-
reverse: reverse.String(),
105-
varsN: varsN,
106-
varsR: varsR,
101+
template: template,
102+
matchHost: matchHost,
103+
strictSlash: strictSlash,
104+
regexp: reg,
105+
reverse: reverse.String(),
106+
varsN: varsN,
107+
varsR: varsR,
107108
}, nil
108109
}
109110

@@ -114,6 +115,8 @@ type routeRegexp struct {
114115
template string
115116
// True for host match, false for path match.
116117
matchHost bool
118+
// The strictSlash value defined on the route, but disabled if PathPrefix was used.
119+
strictSlash bool
117120
// Expanded regexp.
118121
regexp *regexp.Regexp
119122
// Reverse template.
@@ -216,7 +219,7 @@ func (v *routeRegexpGroup) setMatch(req *http.Request, m *RouteMatch, r *Route)
216219
m.Vars[v] = pathVars[k+1]
217220
}
218221
// Check if we should redirect.
219-
if r.strictSlash {
222+
if v.path.strictSlash {
220223
p1 := strings.HasSuffix(req.URL.Path, "/")
221224
p2 := strings.HasSuffix(v.path.template, "/")
222225
if p1 != p2 {

route.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,6 @@ func (r *Route) Path(tpl string) *Route {
294294
// Also note that the setting of Router.StrictSlash() has no effect on routes
295295
// with a PathPrefix matcher.
296296
func (r *Route) PathPrefix(tpl string) *Route {
297-
r.strictSlash = false
298297
r.err = r.addRegexpMatcher(tpl, false, true)
299298
return r
300299
}

0 commit comments

Comments
 (0)