mirror of
https://github.com/kataras/iris.git
synced 2025-03-15 04:06:25 +01:00
Save
Former-commit-id: 592e9cddf3511fc08e87f19ad39fdaac479b453f
This commit is contained in:
parent
c0e0886cb9
commit
66209cae4f
|
@ -8,7 +8,7 @@ func main() {
|
||||||
app := iris.New()
|
app := iris.New()
|
||||||
|
|
||||||
none := app.None("/invisible/{username}", func(ctx iris.Context) {
|
none := app.None("/invisible/{username}", func(ctx iris.Context) {
|
||||||
ctx.Writef("Hello %s with method: %s", ctx.Values().GetString("username"), ctx.Method())
|
ctx.Writef("Hello %s with method: %s", ctx.Params().Get("username"), ctx.Method())
|
||||||
|
|
||||||
if from := ctx.Values().GetString("from"); from != "" {
|
if from := ctx.Values().GetString("from"); from != "" {
|
||||||
ctx.Writef("\nI see that you're coming from %s", from)
|
ctx.Writef("\nI see that you're coming from %s", from)
|
||||||
|
|
|
@ -90,6 +90,8 @@ type APIBuilder struct {
|
||||||
doneHandlers context.Handlers
|
doneHandlers context.Handlers
|
||||||
// global done handlers, order doesn't matter
|
// global done handlers, order doesn't matter
|
||||||
doneGlobalHandlers context.Handlers
|
doneGlobalHandlers context.Handlers
|
||||||
|
// fallback stack, LIFO order
|
||||||
|
fallbackStack *FallbackStack
|
||||||
// the per-party
|
// the per-party
|
||||||
relativePath string
|
relativePath string
|
||||||
}
|
}
|
||||||
|
@ -106,6 +108,7 @@ func NewAPIBuilder() *APIBuilder {
|
||||||
reporter: errors.NewReporter(),
|
reporter: errors.NewReporter(),
|
||||||
relativePath: "/",
|
relativePath: "/",
|
||||||
routes: new(repository),
|
routes: new(repository),
|
||||||
|
fallbackStack: NewFallbackStack(),
|
||||||
}
|
}
|
||||||
|
|
||||||
return api
|
return api
|
||||||
|
@ -268,9 +271,10 @@ func (api *APIBuilder) Party(relativePath string, handlers ...context.Handler) P
|
||||||
doneGlobalHandlers: api.doneGlobalHandlers,
|
doneGlobalHandlers: api.doneGlobalHandlers,
|
||||||
reporter: api.reporter,
|
reporter: api.reporter,
|
||||||
// per-party/children
|
// per-party/children
|
||||||
middleware: middleware,
|
middleware: middleware,
|
||||||
doneHandlers: api.doneHandlers,
|
doneHandlers: api.doneHandlers,
|
||||||
relativePath: fullpath,
|
fallbackStack: api.fallbackStack,
|
||||||
|
relativePath: fullpath,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -422,6 +426,15 @@ func (api *APIBuilder) DoneGlobal(handlers ...context.Handler) {
|
||||||
api.doneGlobalHandlers = append(api.doneGlobalHandlers, handlers...)
|
api.doneGlobalHandlers = append(api.doneGlobalHandlers, handlers...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fallback appends Handler(s) to the current Party's fallback stack.
|
||||||
|
// Handler(s) is(are) called from Fallback stack when no route found and before sending NotFound status.
|
||||||
|
// Therefore Handler(s) in Fallback stack could send another thing than NotFound status,
|
||||||
|
// if `Context.Next()` method is not called.
|
||||||
|
// Done & DoneGlobal Handlers are not called.
|
||||||
|
func (api *APIBuilder) Fallback(middleware ...context.Handler) {
|
||||||
|
api.fallbackStack.add(middleware)
|
||||||
|
}
|
||||||
|
|
||||||
// Reset removes all the begin and done handlers that may derived from the parent party via `Use` & `Done`,
|
// Reset removes all the begin and done handlers that may derived from the parent party via `Use` & `Done`,
|
||||||
// note that the `Reset` will not reset the handlers that are registered via `UseGlobal` & `DoneGlobal`.
|
// note that the `Reset` will not reset the handlers that are registered via `UseGlobal` & `DoneGlobal`.
|
||||||
//
|
//
|
||||||
|
|
44
core/router/fallback_stack.go
Normal file
44
core/router/fallback_stack.go
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
package router
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/kataras/iris/context"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FallbackStack struct {
|
||||||
|
handlers context.Handlers
|
||||||
|
m sync.Mutex
|
||||||
|
}
|
||||||
|
|
||||||
|
func (stk *FallbackStack) add(h context.Handlers) {
|
||||||
|
stk.m.Lock()
|
||||||
|
defer stk.m.Unlock()
|
||||||
|
|
||||||
|
stk.handlers = append(stk.handlers, h...)
|
||||||
|
|
||||||
|
copy(stk.handlers[len(h):], stk.handlers)
|
||||||
|
copy(stk.handlers, h)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (stk *FallbackStack) list() context.Handlers {
|
||||||
|
res := make(context.Handlers, len(stk.handlers))
|
||||||
|
|
||||||
|
stk.m.Lock()
|
||||||
|
defer stk.m.Unlock()
|
||||||
|
|
||||||
|
copy(res, stk.handlers)
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFallbackStack() *FallbackStack {
|
||||||
|
return &FallbackStack{
|
||||||
|
handlers: context.Handlers{
|
||||||
|
func(ctx context.Context) {
|
||||||
|
ctx.StatusCode(http.StatusNotFound)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
|
@ -33,8 +33,9 @@ type tree struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type routerHandler struct {
|
type routerHandler struct {
|
||||||
trees []*tree
|
trees []*tree
|
||||||
hosts bool // true if at least one route contains a Subdomain.
|
hosts bool // true if at least one route contains a Subdomain.
|
||||||
|
fallbackStack *FallbackStack
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ RequestHandler = &routerHandler{}
|
var _ RequestHandler = &routerHandler{}
|
||||||
|
@ -82,6 +83,8 @@ func NewDefaultHandler() RequestHandler {
|
||||||
type RoutesProvider interface { // api builder
|
type RoutesProvider interface { // api builder
|
||||||
GetRoutes() []*Route
|
GetRoutes() []*Route
|
||||||
GetRoute(routeName string) *Route
|
GetRoute(routeName string) *Route
|
||||||
|
|
||||||
|
FallBackStack() *FallbackStack
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *routerHandler) Build(provider RoutesProvider) error {
|
func (h *routerHandler) Build(provider RoutesProvider) error {
|
||||||
|
@ -242,5 +245,5 @@ func (h *routerHandler) HandleRequest(ctx context.Context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.StatusCode(http.StatusNotFound)
|
ctx.Do(h.fallbackStack.list())
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,6 +60,13 @@ type Party interface {
|
||||||
// If the current Party is the root, then it registers the middleware to all child Parties' routes too.
|
// If the current Party is the root, then it registers the middleware to all child Parties' routes too.
|
||||||
Use(middleware ...context.Handler)
|
Use(middleware ...context.Handler)
|
||||||
|
|
||||||
|
// Fallback appends Handler(s) to the current Party's fallback stack.
|
||||||
|
// Handler(s) is(are) called from Fallback stack when no route found and before sending NotFound status.
|
||||||
|
// Therefore Handler(s) in Fallback stack could send another thing than NotFound status,
|
||||||
|
// if `Context.Next()` method is not called.
|
||||||
|
// Done Handler(s) is(are) not called.
|
||||||
|
Fallback(middleware ...context.Handler)
|
||||||
|
|
||||||
// Done appends to the very end, Handler(s) to the current Party's routes and child routes.
|
// 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.
|
// The difference from .Use is that this/or these Handler(s) are being always running last.
|
||||||
Done(handlers ...context.Handler)
|
Done(handlers ...context.Handler)
|
||||||
|
|
|
@ -176,6 +176,13 @@ func (app *Application) Handle(controller interface{}) *Application {
|
||||||
return app
|
return app
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fallback is an alias to `app.Router.Fallback(handlers...)`
|
||||||
|
//
|
||||||
|
// See `core/router#Party.Fallback`
|
||||||
|
func (app *Application) Fallback(handlers ...context.Handler) {
|
||||||
|
app.Router.Fallback(handlers...)
|
||||||
|
}
|
||||||
|
|
||||||
// Clone returns a new mvc Application which has the dependencies
|
// Clone returns a new mvc Application which has the dependencies
|
||||||
// of the current mvc Mpplication's dependencies.
|
// of the current mvc Mpplication's dependencies.
|
||||||
//
|
//
|
||||||
|
|
Loading…
Reference in New Issue
Block a user