Skip to content

Commit

Permalink
Clean the Request Path early
Browse files Browse the repository at this point in the history
This will reduce the number of times we have todo a redirect.
and allow multiple slashes in path to be routed!
fixes gin-gonic#1644
  • Loading branch information
dmarkham committed Mar 18, 2019
1 parent b40d4c1 commit fdad5ae
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 10 deletions.
1 change: 1 addition & 0 deletions gin.go
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,7 @@ func (engine *Engine) handleHTTPRequest(c *Context) {
rPath = c.Request.URL.RawPath
unescape = engine.UnescapePathValues
}
rPath = cleanPath(rPath)

// Find root of the tree for the given HTTP method
t := engine.trees
Expand Down
52 changes: 42 additions & 10 deletions routes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ type header struct {
}

func performRequest(r http.Handler, method, path string, headers ...header) *httptest.ResponseRecorder {
req, _ := http.NewRequest(method, path, nil)
req := httptest.NewRequest(method, path, nil)
for _, h := range headers {
req.Header.Add(h.Key, h.Value)
}
Expand Down Expand Up @@ -257,6 +257,39 @@ func TestRouteParamsByName(t *testing.T) {
assert.Equal(t, "/is/super/great", wild)
}

// TestContextParamsGet tests that a parameter can be parsed from the URL even with extra slashes.
func TestRouteParamsByNameWithExtraSlash(t *testing.T) {
name := ""
lastName := ""
wild := ""
router := New()
router.GET("/test/:name/:last_name/*wild", func(c *Context) {
name = c.Params.ByName("name")
lastName = c.Params.ByName("last_name")
var ok bool
wild, ok = c.Params.Get("wild")

assert.True(t, ok)
assert.Equal(t, name, c.Param("name"))
assert.Equal(t, name, c.Param("name"))
assert.Equal(t, lastName, c.Param("last_name"))

assert.Empty(t, c.Param("wtf"))
assert.Empty(t, c.Params.ByName("wtf"))

wtf, ok := c.Params.Get("wtf")
assert.Empty(t, wtf)
assert.False(t, ok)
})

w := performRequest(router, "GET", "//test//john//smith//is//super//great")

assert.Equal(t, http.StatusOK, w.Code)
assert.Equal(t, "john", name)
assert.Equal(t, "smith", lastName)
assert.Equal(t, "/is/super/great", wild)
}

// TestHandleStaticFile - ensure the static file handles properly
func TestRouteStaticFile(t *testing.T) {
// SETUP file
Expand Down Expand Up @@ -386,15 +419,14 @@ func TestRouterNotFound(t *testing.T) {
code int
location string
}{
{"/path/", http.StatusMovedPermanently, "/path"}, // TSR -/
{"/dir", http.StatusMovedPermanently, "/dir/"}, // TSR +/
{"", http.StatusMovedPermanently, "/"}, // TSR +/
{"/PATH", http.StatusMovedPermanently, "/path"}, // Fixed Case
{"/DIR/", http.StatusMovedPermanently, "/dir/"}, // Fixed Case
{"/PATH/", http.StatusMovedPermanently, "/path"}, // Fixed Case -/
{"/DIR", http.StatusMovedPermanently, "/dir/"}, // Fixed Case +/
{"/../path", http.StatusMovedPermanently, "/path"}, // CleanPath
{"/nope", http.StatusNotFound, ""}, // NotFound
{"/path/", http.StatusMovedPermanently, "/path"}, // TSR -/
{"/dir", http.StatusMovedPermanently, "/dir/"}, // TSR +/
{"/PATH", http.StatusMovedPermanently, "/path"}, // Fixed Case
{"/DIR/", http.StatusMovedPermanently, "/dir/"}, // Fixed Case
{"/PATH/", http.StatusMovedPermanently, "/path"}, // Fixed Case -/
{"/DIR", http.StatusMovedPermanently, "/dir/"}, // Fixed Case +/
{"/../path", http.StatusOK, ""}, // CleanPath
{"/nope", http.StatusNotFound, ""}, // NotFound
}
for _, tr := range testRoutes {
w := performRequest(router, "GET", tr.route)
Expand Down

0 comments on commit fdad5ae

Please sign in to comment.