File tree 2 files changed +37
-7
lines changed
2 files changed +37
-7
lines changed Original file line number Diff line number Diff line change 9
9
"errors"
10
10
"fmt"
11
11
"net/http"
12
+ "net/url"
12
13
"path"
13
14
"regexp"
14
15
)
@@ -172,19 +173,30 @@ func (r *Router) Match(req *http.Request, match *RouteMatch) bool {
172
173
// mux.Vars(request).
173
174
func (r * Router ) ServeHTTP (w http.ResponseWriter , req * http.Request ) {
174
175
if ! r .skipClean {
175
- path := req .URL .Path
176
+ urlPath := req .URL .Path
176
177
if r .useEncodedPath {
177
- path = req .URL .EscapedPath ()
178
+ urlPath = req .URL .EscapedPath ()
178
179
}
179
180
// Clean path to canonical form and redirect.
180
- if p := cleanPath (path ); p != path {
181
-
181
+ if p := cleanPath (urlPath ); p != urlPath {
182
182
// Added 3 lines (Philip Schlump) - It was dropping the query string and #whatever from query.
183
183
// This matches with fix in go 1.2 r.c. 4 for same problem. Go Issue:
184
184
// http://code.google.com/p/go/issues/detail?id=5252
185
- url := * req .URL
186
- url .Path = p
187
- p = url .String ()
185
+ reqURL := * req .URL
186
+
187
+ if r .useEncodedPath {
188
+ pURL , err := url .ParseRequestURI (p )
189
+ if err != nil {
190
+ // This shouldn't be possible, but fall back to old behaviour if some edge case triggers it
191
+ reqURL .Path = p
192
+ } else {
193
+ reqURL .Path = pURL .Path
194
+ reqURL .RawPath = pURL .RawPath
195
+ }
196
+ } else {
197
+ reqURL .Path = p
198
+ }
199
+ p = reqURL .String ()
188
200
189
201
w .Header ().Set ("Location" , p )
190
202
w .WriteHeader (http .StatusMovedPermanently )
Original file line number Diff line number Diff line change @@ -1574,6 +1574,24 @@ func TestUseEncodedPath(t *testing.T) {
1574
1574
}
1575
1575
}
1576
1576
1577
+ func TestUseEncodedPathEscaping (t * testing.T ) {
1578
+ r := NewRouter ()
1579
+ r .UseEncodedPath ()
1580
+
1581
+ req , _ := http .NewRequest ("GET" , "http://localhost/foo/../bar%25" , nil )
1582
+ res := NewRecorder ()
1583
+ r .ServeHTTP (res , req )
1584
+
1585
+ if len (res .HeaderMap ["Location" ]) != 1 {
1586
+ t .Fatalf ("Expected redirect from path clean" )
1587
+ }
1588
+
1589
+ expected := "http://localhost/bar%25"
1590
+ if res .HeaderMap ["Location" ][0 ] != expected {
1591
+ t .Errorf ("Expected redirect location to %s, found %s" , expected , res .HeaderMap ["Location" ][0 ])
1592
+ }
1593
+ }
1594
+
1577
1595
func TestWalkSingleDepth (t * testing.T ) {
1578
1596
r0 := NewRouter ()
1579
1597
r1 := NewRouter ()
You can’t perform that action at this time.
0 commit comments