Skip to content

Commit ba2999f

Browse files
authored
Merge pull request #32 from bnkamalesh/trailing-slash-fix
[patch] fixed bug where trailing slash config was being ignored when …
2 parents 7f8a116 + c2580b8 commit ba2999f

File tree

3 files changed

+44
-12
lines changed

3 files changed

+44
-12
lines changed

route.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ type Route struct {
1616
// Pattern is the URI pattern to match
1717
Pattern string
1818
// TrailingSlash if set to true, the URI will be matched with or without
19-
// a trailing slash. Note: It does not *do* a redirect.
19+
// a trailing slash. IMPORTANT: It does not redirect.
2020
TrailingSlash bool
2121

2222
// FallThroughPostResponse if enabled will execute all the handlers even if a response was already sent to the client
@@ -44,6 +44,9 @@ func (r *Route) computePatternStr(patternString string, hasWildcard bool, key st
4444
if hasWildcard {
4545
patternKey = fmt.Sprintf(":%s*", key)
4646
regexPattern = urlwildcard
47+
if r.TrailingSlash {
48+
regexPattern = urlwildcardWithTrailslash
49+
}
4750
} else {
4851
patternKey = fmt.Sprintf(":%s", key)
4952
regexPattern = urlchars

router.go

+5-6
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,11 @@ import (
1616
// https://tools.ietf.org/html/rfc3986
1717
// Though the current one allows invalid characters in the URI parameter, it has better performance.
1818
const (
19-
urlchars = `([^/]+)`
20-
urlwildcard = `(.*)`
21-
trailingSlash = `[\/]?`
22-
errMultiHeaderWrite = `http: multiple response.WriteHeader calls`
23-
errMultiWrite = `http: multiple response.Write calls`
24-
errDuplicateKey = `Error: Duplicate URI keys found`
19+
urlchars = `([^/]+)`
20+
urlwildcard = `(.*)[^/]`
21+
urlwildcardWithTrailslash = `(.*)[/]?`
22+
trailingSlash = `[/]?`
23+
errDuplicateKey = `Error: Duplicate URI keys found`
2524
)
2625

2726
var (

router_test.go

+35-5
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,17 @@ func TestRouter_ServeHTTP(t *testing.T) {
3636
url := baseAPI
3737
if l.Path != "" {
3838
switch l.TestType {
39-
case "checkpath", "checkpathnotrailingslash", "chaining", "chaining-nofallthrough":
39+
case "checkpath",
40+
"checkpathnotrailingslash",
41+
"chaining",
42+
"chaining-nofallthrough":
4043
{
4144
url = strings.Join([]string{url, l.Path}, "")
4245
}
43-
case "checkparams":
46+
case "checkparams", "widlcardwithouttrailingslash":
4447
{
4548
for idx, key := range l.ParamKeys {
46-
// in case of wildcard params, they have to replaced first for proper URL construction
49+
// in case of wildcard params, they have to be replaced first for proper URL construction
4750
l.Path = strings.Replace(l.Path, ":"+key+"*", l.Params[idx], 1)
4851
l.Path = strings.Replace(l.Path, ":"+key, l.Params[idx], 1)
4952
}
@@ -60,7 +63,7 @@ func TestRouter_ServeHTTP(t *testing.T) {
6063
router.ServeHTTP(respRec, req)
6164

6265
switch l.TestType {
63-
case "checkpath", "checkpathnotrailingslash":
66+
case "checkpath", "checkpathnotrailingslash", "widlcardwithouttrailingslash":
6467
{
6568
err = checkPath(req, respRec)
6669
}
@@ -99,7 +102,15 @@ func TestRouter_ServeHTTP(t *testing.T) {
99102
)
100103
}
101104
}
105+
} else if err == nil && l.WantErr {
106+
t.Errorf(
107+
"'%s' (%s '%s') expected error, but received nil",
108+
l.Name,
109+
l.Method,
110+
url,
111+
)
102112
}
113+
103114
err = checkMiddleware(req, respRec)
104115
if err != nil {
105116
t.Error(err.Error())
@@ -138,7 +149,7 @@ func getRoutes() []*Route {
138149
},
139150
)
140151
}
141-
case "checkpathnotrailingslash":
152+
case "checkpathnotrailingslash", "widlcardwithouttrailingslash":
142153
{
143154
rr = append(rr,
144155
&Route{
@@ -152,6 +163,7 @@ func getRoutes() []*Route {
152163
)
153164

154165
}
166+
155167
case "chaining":
156168
{
157169
rr = append(
@@ -462,6 +474,24 @@ func testTable() []struct {
462474
Params: []string{"hello/world/hi/there/-/~/./again"},
463475
WantErr: false,
464476
},
477+
{
478+
Name: "Check with wildcard - 3",
479+
TestType: "widlcardwithouttrailingslash",
480+
Path: "/wildcard3/:a*",
481+
Method: http.MethodGet,
482+
ParamKeys: []string{"a"},
483+
Params: []string{"hello/world/hi/there/-/~/./again/"},
484+
WantErr: true,
485+
},
486+
{
487+
Name: "Check with wildcard - 4",
488+
TestType: "widlcardwithouttrailingslash",
489+
Path: "/wildcard3/:a*",
490+
Method: http.MethodGet,
491+
ParamKeys: []string{"a"},
492+
Params: []string{"hello/world/hi/there/-/~/./again"},
493+
WantErr: false,
494+
},
465495
{
466496
Name: "Check not implemented",
467497
TestType: "notimplemented",

0 commit comments

Comments
 (0)