Skip to content

Commit f152ebd

Browse files
committed
Don't strip trailing slash if it's escaped
1 parent 0a20a0e commit f152ebd

File tree

2 files changed

+24
-12
lines changed

2 files changed

+24
-12
lines changed

Diff for: middleware/strip.go

+12-12
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package middleware
33
import (
44
"fmt"
55
"net/http"
6+
"strings"
67

78
"github.com/go-chi/chi/v5"
89
)
@@ -12,20 +13,19 @@ import (
1213
// matches, then it will serve the handler.
1314
func StripSlashes(next http.Handler) http.Handler {
1415
fn := func(w http.ResponseWriter, r *http.Request) {
15-
var path string
1616
rctx := chi.RouteContext(r.Context())
17-
if rctx != nil && rctx.RoutePath != "" {
18-
path = rctx.RoutePath
19-
} else {
20-
path = r.URL.Path
21-
}
22-
if len(path) > 1 && path[len(path)-1] == '/' {
23-
newPath := path[:len(path)-1]
24-
if rctx == nil {
25-
r.URL.Path = newPath
26-
} else {
27-
rctx.RoutePath = newPath
17+
18+
if rctx != nil && len(rctx.RoutePath) > 1 {
19+
rctx.RoutePath = strings.TrimSuffix(rctx.RoutePath, "/")
20+
} else if len(r.URL.RawPath) > 1 {
21+
if r.URL.RawPath[len(r.URL.RawPath)-1] == '/' {
22+
// Always update RawPath and Path in sync to make sure
23+
// there are no unexpected mismatches
24+
r.URL.RawPath = strings.TrimSuffix(r.URL.RawPath, "/")
25+
r.URL.Path = strings.TrimSuffix(r.URL.Path, "/")
2826
}
27+
} else if len(r.URL.Path) > 1 {
28+
r.URL.Path = strings.TrimSuffix(r.URL.Path, "/")
2929
}
3030
next.ServeHTTP(w, r)
3131
}

Diff for: middleware/strip_test.go

+12
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,18 @@ func TestStripSlashes(t *testing.T) {
4848
if _, resp := testRequest(t, ts, "GET", "/accounts/admin/", nil); resp != "admin" {
4949
t.Fatal(resp)
5050
}
51+
if _, resp := testRequest(t, ts, "GET", "/accounts/escaped%2F", nil); resp != "escaped%2F" {
52+
t.Fatalf(resp)
53+
}
54+
if _, resp := testRequest(t, ts, "GET", "/accounts/escaped%2F/", nil); resp != "escaped%2F" {
55+
t.Fatalf(resp)
56+
}
5157
if _, resp := testRequest(t, ts, "GET", "/nothing-here", nil); resp != "nothing here" {
5258
t.Fatal(resp)
5359
}
60+
if _, resp := testRequest(t, ts, "GET", "/%2F", nil); resp != "nothing here" {
61+
t.Fatalf(resp)
62+
}
5463
}
5564

5665
func TestStripSlashesInRoute(t *testing.T) {
@@ -97,6 +106,9 @@ func TestStripSlashesInRoute(t *testing.T) {
97106
if _, resp := testRequest(t, ts, "GET", "/accounts/admin/query/", nil); resp != "admin" {
98107
t.Fatal(resp)
99108
}
109+
if _, resp := testRequest(t, ts, "GET", "/accounts/admin/query%2F", nil); resp != "nothing here" {
110+
t.Fatalf(resp)
111+
}
100112
}
101113

102114
func TestRedirectSlashes(t *testing.T) {

0 commit comments

Comments
 (0)