From e81e9c6ba6611a05e3c637f55341ef533e1539b4 Mon Sep 17 00:00:00 2001 From: Matthias Neugebauer Date: Mon, 31 Jan 2022 14:22:31 +0100 Subject: [PATCH 1/2] =?UTF-8?q?=F0=9F=94=A5=20Feature:=20Add=20ability=20t?= =?UTF-8?q?o=20restart=20route=20handling?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ctx.go | 8 +++++++ ctx_test.go | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/ctx.go b/ctx.go index af2032ac08..b29a2d8778 100644 --- a/ctx.go +++ b/ctx.go @@ -782,6 +782,14 @@ func (c *Ctx) Next() (err error) { return err } +// RestartRouting instead of going to the next handler. This may be usefull after +// changing the request path. Note that handlers might be executed again. +func (c *Ctx) RestartRouting() error { + c.indexRoute = -1 + _, err := c.app.next(c) + return err +} + // OriginalURL contains the original request URL. // Returned value is only valid within the handler. Do not store any references. // Make copies or use the Immutable setting to use the value outside the Handler. diff --git a/ctx_test.go b/ctx_test.go index f5149dbb02..963946fb0c 100644 --- a/ctx_test.go +++ b/ctx_test.go @@ -2065,6 +2065,69 @@ func Test_Ctx_RenderWithLocalsAndBinding(t *testing.T) { utils.AssertEqual(t, "

Hello, World!

", string(c.Response().Body())) } +// go test -run Test_Ctx_Restart +func Test_Ctx_Restart(t *testing.T) { + app := New() + calls := 0 + app.Get("/", func(c *Ctx) error { + calls++ + if calls < 3 { + return c.RestartRouting() + } + return nil + }) + resp, err := app.Test(httptest.NewRequest(MethodGet, "http://example.com/", nil)) + utils.AssertEqual(t, nil, err, "app.Test(req)") + utils.AssertEqual(t, StatusOK, resp.StatusCode, "Status code") + utils.AssertEqual(t, 3, calls, "Number of calls") +} + +// go test -run Test_Ctx_RestartWithChangedPath +func Test_Ctx_RestartWithChangedPath(t *testing.T) { + app := New() + executedOldHandler := false + executedNewHandler := false + + app.Get("/old", func(c *Ctx) error { + c.Path("/new") + return c.RestartRouting() + }) + app.Get("/old", func(c *Ctx) error { + executedOldHandler = true + return nil + }) + app.Get("/new", func(c *Ctx) error { + executedNewHandler = true + return nil + }) + + resp, err := app.Test(httptest.NewRequest(MethodGet, "http://example.com/old", nil)) + utils.AssertEqual(t, nil, err, "app.Test(req)") + utils.AssertEqual(t, StatusOK, resp.StatusCode, "Status code") + utils.AssertEqual(t, false, executedOldHandler, "Executed old handler") + utils.AssertEqual(t, true, executedNewHandler, "Executed new handler") +} + +// go test -run Test_Ctx_RestartWithChangedPathAnd404 +func Test_Ctx_RestartWithChangedPathAndCatchAll(t *testing.T) { + app := New() + app.Get("/new", func(c *Ctx) error { + return nil + }) + app.Use(func(c *Ctx) error { + c.Path("/new") + // c.Next() would fail this test as a 404 is returned from the next handler + return c.RestartRouting() + }) + app.Use(func(c *Ctx) error { + return ErrNotFound + }) + + resp, err := app.Test(httptest.NewRequest(MethodGet, "http://example.com/old", nil)) + utils.AssertEqual(t, nil, err, "app.Test(req)") + utils.AssertEqual(t, StatusOK, resp.StatusCode, "Status code") +} + type testTemplateEngine struct { templates *template.Template } From 2162405b9e971f7741e97d8687d89901d4df47e8 Mon Sep 17 00:00:00 2001 From: RW Date: Thu, 3 Feb 2022 15:04:52 +0100 Subject: [PATCH 2/2] Change test names --- ctx_test.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ctx_test.go b/ctx_test.go index 963946fb0c..19317fd1ef 100644 --- a/ctx_test.go +++ b/ctx_test.go @@ -2065,8 +2065,8 @@ func Test_Ctx_RenderWithLocalsAndBinding(t *testing.T) { utils.AssertEqual(t, "

Hello, World!

", string(c.Response().Body())) } -// go test -run Test_Ctx_Restart -func Test_Ctx_Restart(t *testing.T) { +// go test -run Test_Ctx_RestartRouting +func Test_Ctx_RestartRouting(t *testing.T) { app := New() calls := 0 app.Get("/", func(c *Ctx) error { @@ -2082,8 +2082,8 @@ func Test_Ctx_Restart(t *testing.T) { utils.AssertEqual(t, 3, calls, "Number of calls") } -// go test -run Test_Ctx_RestartWithChangedPath -func Test_Ctx_RestartWithChangedPath(t *testing.T) { +// go test -run Test_Ctx_RestartRoutingWithChangedPath +func Test_Ctx_RestartRoutingWithChangedPath(t *testing.T) { app := New() executedOldHandler := false executedNewHandler := false @@ -2108,8 +2108,8 @@ func Test_Ctx_RestartWithChangedPath(t *testing.T) { utils.AssertEqual(t, true, executedNewHandler, "Executed new handler") } -// go test -run Test_Ctx_RestartWithChangedPathAnd404 -func Test_Ctx_RestartWithChangedPathAndCatchAll(t *testing.T) { +// go test -run Test_Ctx_RestartRoutingWithChangedPathAnd404 +func Test_Ctx_RestartRoutingWithChangedPathAndCatchAll(t *testing.T) { app := New() app.Get("/new", func(c *Ctx) error { return nil