From cf4836c6061cda88ace6721ef5e0113c28e5babd Mon Sep 17 00:00:00 2001 From: ReneWerner87 Date: Thu, 25 Jun 2020 08:44:29 +0200 Subject: [PATCH 1/3] =?UTF-8?q?=F0=9F=9A=80=20Added=20possibility=20to=20w?= =?UTF-8?q?ork=20with=20urlencoded=20special=20characters=20in=20the=20rou?= =?UTF-8?q?te?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app.go | 5 +++++ ctx.go | 8 +++++++- router_test.go | 22 ++++++++++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/app.go b/app.go index 792ac9397d..c2815ef71d 100644 --- a/app.go +++ b/app.go @@ -86,6 +86,11 @@ type Settings struct { // Default: false Immutable bool + // Converts all encoded characters in the route back before setting the path for the context, + // so that the routing can also work with urlencoded special characters + // Default: false + UnescapePath bool + // Enable or disable ETag header generation, since both weak and strong etags are generated // using the same hashing method (CRC-32). Weak ETags are the default when enabled. // Default value false diff --git a/ctx.go b/ctx.go index c6fc63a3e8..e35ab69003 100644 --- a/ctx.go +++ b/ctx.go @@ -987,10 +987,16 @@ func (ctx *Ctx) XHR() bool { // prettifyPath ... func (ctx *Ctx) prettifyPath() { + // If UnescapePath enabled, we decode the path + if ctx.app.Settings.UnescapePath { + pathBytes := getBytes(ctx.path) + pathBytes = fasthttp.AppendUnquotedArg(pathBytes[:0], pathBytes) + ctx.path = getString(pathBytes) + } // If CaseSensitive is disabled, we lowercase the original path if !ctx.app.Settings.CaseSensitive { // We are making a copy here to keep access to the original path - ctx.path = utils.ToLower(ctx.pathOriginal) + ctx.path = utils.ToLower(ctx.path) } // If StrictRouting is disabled, we strip all trailing slashes if !ctx.app.Settings.StrictRouting && len(ctx.path) > 1 && ctx.path[len(ctx.path)-1] == '/' { diff --git a/router_test.go b/router_test.go index b677ecfd9e..9e8f2bca84 100644 --- a/router_test.go +++ b/router_test.go @@ -146,6 +146,28 @@ func Test_Route_Match_Middleware(t *testing.T) { utils.AssertEqual(t, "bar/fasel", getString(body)) } +func Test_Route_Match_UnescapedPath(t *testing.T) { + app := New(&Settings{UnescapePath: true}) + + app.Use("/créer", func(ctx *Ctx) { + ctx.Send("test") + }) + + resp, err := app.Test(httptest.NewRequest(MethodGet, "/cr%C3%A9er", nil)) + utils.AssertEqual(t, nil, err, "app.Test(req)") + utils.AssertEqual(t, StatusOK, resp.StatusCode, "Status code") + + body, err := ioutil.ReadAll(resp.Body) + utils.AssertEqual(t, nil, err, "app.Test(req)") + utils.AssertEqual(t, "test", getString(body)) + + // check deactivated behavior + app.Settings.UnescapePath = false + resp, err = app.Test(httptest.NewRequest(MethodGet, "/cr%C3%A9er", nil)) + utils.AssertEqual(t, nil, err, "app.Test(req)") + utils.AssertEqual(t, StatusNotFound, resp.StatusCode, "Status code") +} + func Test_Route_Match_Middleware_HasPrefix(t *testing.T) { app := New() From eb0b3651118d0d65637a9e8d3abd3f2ec386ee47 Mon Sep 17 00:00:00 2001 From: ReneWerner87 Date: Thu, 25 Jun 2020 15:25:16 +0200 Subject: [PATCH 2/3] =?UTF-8?q?=F0=9F=9A=80=20Added=20possibility=20to=20w?= =?UTF-8?q?ork=20with=20urlencoded=20special=20characters=20in=20the=20rou?= =?UTF-8?q?te?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- router_test.go | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/router_test.go b/router_test.go index 9e8f2bca84..c50bc11c95 100644 --- a/router_test.go +++ b/router_test.go @@ -160,6 +160,10 @@ func Test_Route_Match_UnescapedPath(t *testing.T) { body, err := ioutil.ReadAll(resp.Body) utils.AssertEqual(t, nil, err, "app.Test(req)") utils.AssertEqual(t, "test", getString(body)) + // without special chars + resp, err = app.Test(httptest.NewRequest(MethodGet, "/créer", nil)) + utils.AssertEqual(t, nil, err, "app.Test(req)") + utils.AssertEqual(t, StatusOK, resp.StatusCode, "Status code") // check deactivated behavior app.Settings.UnescapePath = false @@ -427,6 +431,23 @@ func Benchmark_Router_Handler_CaseSensitive(b *testing.B) { } } +// go test -v ./... -run=^$ -bench=Benchmark_Router_Handler_Unescape -benchmem -count=4 +func Benchmark_Router_Handler_Unescape(b *testing.B) { + app := New() + app.Settings.UnescapePath = true + registerDummyRoutes(app) + app.Delete("/créer", func(c *Ctx) {}) + + c := &fasthttp.RequestCtx{} + + c.Request.Header.SetMethod(MethodDelete) + c.URI().SetPath("/cr%C3%A9er") + + for n := 0; n < b.N; n++ { + app.handler(c) + } +} + // go test -v ./... -run=^$ -bench=Benchmark_Router_Handler_StrictRouting -benchmem -count=4 func Benchmark_Router_Handler_StrictRouting(b *testing.B) { app := New() From 0a4f58f8795b8d8a1ac41b60cb7762a841b73379 Mon Sep 17 00:00:00 2001 From: ReneWerner87 Date: Thu, 25 Jun 2020 15:51:08 +0200 Subject: [PATCH 3/3] =?UTF-8?q?=F0=9F=9A=80=20Added=20possibility=20to=20w?= =?UTF-8?q?ork=20with=20urlencoded=20special=20characters=20in=20the=20rou?= =?UTF-8?q?te?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- utils_test.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/utils_test.go b/utils_test.go index 396bdb9e3e..87eac653f1 100644 --- a/utils_test.go +++ b/utils_test.go @@ -116,3 +116,17 @@ func Benchmark_Utils_getGroupPath(b *testing.B) { // func Benchmark_Utils_parseTokenList(b *testing.B) { // // TODO // } + +func Benchmark_Utils_Unescape(b *testing.B) { + unescaped := "" + dst := make([]byte, 0) + + for n := 0; n < b.N; n++ { + source := "/cr%C3%A9er" + pathBytes := getBytes(source) + pathBytes = fasthttp.AppendUnquotedArg(dst[:0], pathBytes) + unescaped = getString(pathBytes) + } + + utils.AssertEqual(b, "/créer", unescaped) +}