From 38b0a796bd1ee3098ac3c1a8a58f87b9e88d07f6 Mon Sep 17 00:00:00 2001 From: "Gerasimos (Makis) Maropoulos" Date: Mon, 6 Jul 2020 19:08:02 +0300 Subject: [PATCH] fix #1552 Former-commit-id: 953df27468e3905e557bb1f6a97ea431cb60f6a6 --- HISTORY.md | 3 ++ _examples/response-writer/sse/main.go | 2 +- .../use-global/main.go | 42 +++++++++++++++++++ .../use-global/main_test.go | 25 +++++++++++ core/router/api_builder.go | 19 +++++---- core/router/router_handlers_order_test.go | 2 + 6 files changed, 85 insertions(+), 8 deletions(-) create mode 100644 _examples/routing/dynamic-path/same-pattern-different-func/use-global/main.go create mode 100644 _examples/routing/dynamic-path/same-pattern-different-func/use-global/main_test.go diff --git a/HISTORY.md b/HISTORY.md index 35b324e6a..a8e85c45b 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -371,6 +371,8 @@ Other Improvements: ![DBUG routes](https://iris-go.com/images/v12.2.0-dbug2.png?v=0) +- Fix [#1552](https://github.com/kataras/iris/issues/1552). + - Proper listing of root directories on `Party.HandleDir` when its `DirOptions.ShowList` was set to true. - Socket Sharding as requested at [#1544](https://github.com/kataras/iris/issues/1544). New `iris.WithSocketSharding` Configurator and `SocketSharding bool` setting. @@ -422,6 +424,7 @@ Other Improvements: New Package-level Variables: - `iris.DirListRich` to override the default look and feel if the `DirOptions.ShowList` was set to true, can be passed to `DirOptions.DirList` field. +- `iris.DirListRichOptions` to pass on `iris.DirListRich` method. - `iris.ErrGzipNotSupported` to export the `context.ErrGzipNotSupported` when trying to write gzip but client does not support. - `iris.GzipReader` middleware to decode gzip requests on next read actions. - `iris.B, KB, MB, GB, TB, PB, EB` for byte units. diff --git a/_examples/response-writer/sse/main.go b/_examples/response-writer/sse/main.go index a07419eb5..7ac0a21da 100644 --- a/_examples/response-writer/sse/main.go +++ b/_examples/response-writer/sse/main.go @@ -95,7 +95,7 @@ func (b *Broker) ServeHTTP(ctx iris.Context) { b.newClients <- messageChan // Listen to connection close and when the entire request handler chain exits(this handler here) and un-register messageChan. - ctx.OnClose(func() { + ctx.OnClose(func(iris.Context) { // Remove this client from the map of connected clients // when this handler exits. b.closingClients <- messageChan diff --git a/_examples/routing/dynamic-path/same-pattern-different-func/use-global/main.go b/_examples/routing/dynamic-path/same-pattern-different-func/use-global/main.go new file mode 100644 index 000000000..2f18f84fa --- /dev/null +++ b/_examples/routing/dynamic-path/same-pattern-different-func/use-global/main.go @@ -0,0 +1,42 @@ +package main // #1552 + +import ( + "github.com/kataras/iris/v12" +) + +func main() { + app := newApp() + app.Listen(":8080") +} + +func newApp() *iris.Application { + app := iris.New() + + app.UseGlobal(middleware("first")) + app.UseGlobal(middleware("second")) + app.DoneGlobal(onDone) + + app.Get("/{name prefix(one)}", handler("first route")) + app.Get("/{name prefix(two)}", handler("second route")) + app.Get("/{name prefix(three)}", handler("third route")) + + return app +} + +func middleware(str string) iris.Handler { + return func(ctx iris.Context) { + ctx.Writef("Called %s middleware\n", str) + ctx.Next() + } +} + +func handler(str string) iris.Handler { + return func(ctx iris.Context) { + ctx.Writef("%s\n", str) + ctx.Next() // or ignroe that and use app.SetRegisterRules. + } +} + +func onDone(ctx iris.Context) { + ctx.Writef("Called done: %s", ctx.Params().Get("name")) +} diff --git a/_examples/routing/dynamic-path/same-pattern-different-func/use-global/main_test.go b/_examples/routing/dynamic-path/same-pattern-different-func/use-global/main_test.go new file mode 100644 index 000000000..6cc2cc58e --- /dev/null +++ b/_examples/routing/dynamic-path/same-pattern-different-func/use-global/main_test.go @@ -0,0 +1,25 @@ +package main + +import ( + "fmt" + "testing" + + "github.com/kataras/iris/v12/httptest" +) + +func TestSamePatternDifferentFuncUseGlobal(t *testing.T) { + app := newApp() + e := httptest.New(t, app) + + expectedResultFmt := "Called first middleware\nCalled second middleware\n%s\nCalled done: %s" + tests := map[string]string{ + "/one-num": "first route", + "/two-num": "second route", + "/three-num": "third route", + } + + for path, mainBody := range tests { + result := fmt.Sprintf(expectedResultFmt, mainBody, path[1:]) + e.GET(path).Expect().Status(httptest.StatusOK).Body().Equal(result) + } +} diff --git a/core/router/api_builder.go b/core/router/api_builder.go index 54a9532f5..38bf2b65e 100644 --- a/core/router/api_builder.go +++ b/core/router/api_builder.go @@ -477,13 +477,14 @@ func (api *APIBuilder) createRoutes(errorCode int, methods []string, relativePat // but dev may change the rules for that child Party, so we have to make clones of them here. var ( - beginHandlers context.Handlers - doneHandlers context.Handlers + // global middleware to error handlers as well. + beginHandlers = api.beginGlobalHandlers + doneHandlers = api.doneGlobalHandlers ) if errorCode == 0 { - beginHandlers = context.JoinHandlers(api.middleware, beginHandlers) - doneHandlers = context.JoinHandlers(api.doneHandlers, doneHandlers) + beginHandlers = context.JoinHandlers(beginHandlers, api.middleware) + doneHandlers = context.JoinHandlers(doneHandlers, api.doneHandlers) } mainHandlers := context.Handlers(handlers) @@ -532,8 +533,8 @@ func (api *APIBuilder) createRoutes(errorCode int, methods []string, relativePat route.SourceLineNumber = mainHandlerFileNumber // Add UseGlobal & DoneGlobal Handlers - route.Use(api.beginGlobalHandlers...) - route.Done(api.doneGlobalHandlers...) + // route.Use(api.beginGlobalHandlers...) + // route.Done(api.doneGlobalHandlers...) routes[i] = route } @@ -771,7 +772,11 @@ func (api *APIBuilder) Use(handlers ...context.Handler) { // It's always a good practise to call it right before the `Application#Run` function. func (api *APIBuilder) UseGlobal(handlers ...context.Handler) { for _, r := range api.routes.routes { - r.Use(handlers...) // prepend the handlers to the existing routes + // r.beginHandlers = append(handlers, r.beginHandlers...) + // ^ this is correct but we act global begin handlers as one chain, so + // if called last more than one time, after all routes registered, we must somehow + // register them by order, so: + r.Use(handlers...) } // set as begin handlers for the next routes as well. api.beginGlobalHandlers = append(api.beginGlobalHandlers, handlers...) diff --git a/core/router/router_handlers_order_test.go b/core/router/router_handlers_order_test.go index d367bd1de..a14fd4ea9 100644 --- a/core/router/router_handlers_order_test.go +++ b/core/router/router_handlers_order_test.go @@ -64,6 +64,8 @@ var ( firstUseResponse + secondUseResponse + mainResponse + firstDoneResponse + secondDoneResponse testResponse = func(t *testing.T, app *iris.Application, path string) { + t.Helper() + e := httptest.New(t, app) e.GET(path).Expect().Status(httptest.StatusOK).Body().Equal(finalResponse) }