File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 99 "errors"
1010 "fmt"
1111 "net/http"
12+ "net/url"
1213 "path"
1314 "regexp"
1415)
@@ -174,19 +175,30 @@ func (r *Router) Match(req *http.Request, match *RouteMatch) bool {
174175// mux.Vars(request).
175176func (r * Router ) ServeHTTP (w http.ResponseWriter , req * http.Request ) {
176177 if ! r .skipClean {
177- path := req .URL .Path
178+ urlPath := req .URL .Path
178179 if r .useEncodedPath {
179- path = req .URL .EscapedPath ()
180+ urlPath = req .URL .EscapedPath ()
180181 }
181182 // Clean path to canonical form and redirect.
182- if p := cleanPath (path ); p != path {
183-
183+ if p := cleanPath (urlPath ); p != urlPath {
184184 // Added 3 lines (Philip Schlump) - It was dropping the query string and #whatever from query.
185185 // This matches with fix in go 1.2 r.c. 4 for same problem. Go Issue:
186186 // http://code.google.com/p/go/issues/detail?id=5252
187- url := * req .URL
188- url .Path = p
189- p = url .String ()
187+ reqURL := * req .URL
188+
189+ if r .useEncodedPath {
190+ pURL , err := url .ParseRequestURI (p )
191+ if err != nil {
192+ // This shouldn't be possible, but fall back to old behaviour if some edge case triggers it
193+ reqURL .Path = p
194+ } else {
195+ reqURL .Path = pURL .Path
196+ reqURL .RawPath = pURL .RawPath
197+ }
198+ } else {
199+ reqURL .Path = p
200+ }
201+ p = reqURL .String ()
190202
191203 w .Header ().Set ("Location" , p )
192204 w .WriteHeader (http .StatusMovedPermanently )
Original file line number Diff line number Diff line change @@ -1574,6 +1574,24 @@ func TestUseEncodedPath(t *testing.T) {
15741574 }
15751575}
15761576
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+
15771595func TestWalkSingleDepth (t * testing.T ) {
15781596 r0 := NewRouter ()
15791597 r1 := NewRouter ()
You can’t perform that action at this time.
0 commit comments