diff --git a/HISTORY.md b/HISTORY.md index c11ebb42..ce404469 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -32,7 +32,7 @@ The codebase for Dependency Injection, Internationalization and localization and - Add the ability to [share functions](https://github.com/kataras/iris/tree/master/_examples/routing/writing-a-middleware/share-funcs) between handlers chain and add an [example](https://github.com/kataras/iris/tree/master/_examples/routing/writing-a-middleware/share-services) on sharing Go structures (aka services). - Add the new `Party.UseOnce` method to the `*Route` -- Add a new `*Route.RemoveHandler(interface{}) int`, deletes a handler from begin, main and done handlers based on its name or the handler pc function. Returns the total amount of handlers removed. +- Add a new `*Route.RemoveHandler(...interface{}) int` and `Party.RemoveHandler(...interface{}) Party` methods, delete a handler based on its name or the handler pc function. ```go func middleware(ctx iris.Context) { diff --git a/core/router/api_builder.go b/core/router/api_builder.go index 0826f329..34f3769a 100644 --- a/core/router/api_builder.go +++ b/core/router/api_builder.go @@ -1094,6 +1094,38 @@ func (api *APIBuilder) DoneGlobal(handlers ...context.Handler) { api.doneGlobalHandlers = append(api.doneGlobalHandlers, handlers...) } +// RemoveHandler deletes a handler from begin and done handlers +// based on its name or the handler pc function. +// +// As an exception, if one of the arguments is a pointer to an int, +// then this is used to set the total amount of removed handlers. +// +// Returns the Party itself for chain calls. +// +// Should be called before children routes regitration. +func (api *APIBuilder) RemoveHandler(namesOrHandlers ...interface{}) Party { + var counter *int + + for _, nameOrHandler := range namesOrHandlers { + handlerName := "" + switch h := nameOrHandler.(type) { + case string: + handlerName = h + case context.Handler: + handlerName = context.HandlerName(h) + case *int: + counter = h + default: + panic(fmt.Sprintf("remove handler: unexpected type of %T", h)) + } + + api.middleware = removeHandler(handlerName, api.middleware, counter) + api.doneHandlers = removeHandler(handlerName, api.doneHandlers, counter) + } + + return api +} + // Reset removes all the begin and done handlers that may derived from the parent party via `Use` & `Done`, // and the execution rules. // Note that the `Reset` will not reset the handlers that are registered via `UseGlobal` & `DoneGlobal`. diff --git a/core/router/party.go b/core/router/party.go index 778a9daa..016c6d7e 100644 --- a/core/router/party.go +++ b/core/router/party.go @@ -121,7 +121,16 @@ type Party interface { // Done appends to the very end, Handler(s) to the current Party's routes and child routes. // The difference from .Use is that this/or these Handler(s) are being always running last. Done(handlers ...context.Handler) - + // RemoveHandler deletes a handler from begin and done handlers + // based on its name or the handler pc function. + // + // As an exception, if one of the arguments is a pointer to an int, + // then this is used to set the total amount of removed handlers. + // + // Returns the Party itself for chain calls. + // + // Should be called before children routes regitration. + RemoveHandler(namesOrHandlers ...interface{}) Party // Reset removes all the begin and done handlers that may derived from the parent party via `Use` & `Done`, // and the execution rules. // Note that the `Reset` will not reset the handlers that are registered via `UseGlobal` & `DoneGlobal`. diff --git a/core/router/route.go b/core/router/route.go index 7b0ee433..1208bf5d 100644 --- a/core/router/route.go +++ b/core/router/route.go @@ -150,20 +150,22 @@ func (r *Route) UseOnce(handlers ...context.Handler) { // Returns the total amount of handlers removed. // // Should be called before Application Build. -func (r *Route) RemoveHandler(nameOrHandler interface{}) (count int) { - handlerName := "" - switch h := nameOrHandler.(type) { - case string: - handlerName = h - case context.Handler: - handlerName = context.HandlerName(h) - default: - panic(fmt.Sprintf("remove handler: unexpected type of %T", h)) - } +func (r *Route) RemoveHandler(namesOrHandlers ...interface{}) (count int) { + for _, nameOrHandler := range namesOrHandlers { + handlerName := "" + switch h := nameOrHandler.(type) { + case string: + handlerName = h + case context.Handler: + handlerName = context.HandlerName(h) + default: + panic(fmt.Sprintf("remove handler: unexpected type of %T", h)) + } - r.beginHandlers = removeHandler(handlerName, r.beginHandlers, &count) - r.Handlers = removeHandler(handlerName, r.Handlers, &count) - r.doneHandlers = removeHandler(handlerName, r.doneHandlers, &count) + r.beginHandlers = removeHandler(handlerName, r.beginHandlers, &count) + r.Handlers = removeHandler(handlerName, r.Handlers, &count) + r.doneHandlers = removeHandler(handlerName, r.doneHandlers, &count) + } return }