diff --git a/bind.go b/bind.go index 374a2aec5..8009877b4 100644 --- a/bind.go +++ b/bind.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" "net/http" + "net/url" "reflect" "strconv" "strings" @@ -35,7 +36,12 @@ func (b *DefaultBinder) BindPathParams(c Context, i interface{}) error { values := c.ParamValues() params := map[string][]string{} for i, name := range names { - params[name] = []string{values[i]} + escaped, err := url.QueryUnescape(values[i]) + if err != nil { + return err + } + + params[name] = []string{escaped} } if err := b.bindData(i, params, "param"); err != nil { return NewHTTPError(http.StatusBadRequest, err.Error()).SetInternal(err) diff --git a/bind_test.go b/bind_test.go index c35283dcf..6ea2a9734 100644 --- a/bind_test.go +++ b/bind_test.go @@ -468,6 +468,19 @@ func TestBindParam(t *testing.T) { assert.Equal(t, "Jon Snow", u.Name) } + // Bind param with escaped characters + { + c := e.NewContext(req, rec) + c.SetPath("/users/:name") + c.SetParamNames("name") + c.SetParamValues("John%2FSnow") + + err := c.Bind(u) + if assert.NoError(t, err) { + assert.Equal(t, "John/Snow", u.Name) + } + } + // Second test for the absence of a param c2 := e.NewContext(req, rec) c2.SetPath("/users/:id")