mirror of
https://github.com/kataras/iris.git
synced 2025-12-30 00:07:04 +00:00
New: context#NextOr && context#NextOrNotFound and some performance improvements on the awesome https://github.com/kataras/iris/pull/909 pushed a while ago
Former-commit-id: 35dd2ab80b69a5bea6f35f58e636bc11229d9921
This commit is contained in:
@@ -90,7 +90,7 @@ type APIBuilder struct {
|
||||
doneHandlers context.Handlers
|
||||
// global done handlers, order doesn't matter
|
||||
doneGlobalHandlers context.Handlers
|
||||
// fallback stack, LIFO order
|
||||
// fallback stack, LIFO order, initialized on first `Fallback`.
|
||||
fallbackStack *FallbackStack
|
||||
// the per-party
|
||||
relativePath string
|
||||
@@ -437,13 +437,13 @@ func (api *APIBuilder) DoneGlobal(handlers ...context.Handler) {
|
||||
// Fallback appends Handler(s) to the current 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.
|
||||
// if `context.NextOrNotFound()` method is not called.
|
||||
// Done & DoneGlobal Handlers are not called.
|
||||
func (api *APIBuilder) Fallback(middleware ...context.Handler) {
|
||||
api.fallbackStack.Add(middleware)
|
||||
}
|
||||
|
||||
// FallBackStack returns Fallback stack, this is implementation of interface RoutesProvider
|
||||
// GetFallBackStack returns Fallback stack, this is implementation of interface RoutesProvider
|
||||
// that is used in Router building by the RequestHandler.
|
||||
func (api *APIBuilder) GetFallBackStack() *FallbackStack {
|
||||
return api.fallbackStack
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/kataras/iris/context"
|
||||
)
|
||||
import "github.com/kataras/iris/context"
|
||||
|
||||
// FallbackStack is a stack (with LIFO calling order) for fallback handlers
|
||||
// A fallback 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.
|
||||
// if `context#NextOrNotFound()` method is not called.
|
||||
// Done & DoneGlobal Handlers are not called.
|
||||
type FallbackStack struct {
|
||||
parent *FallbackStack
|
||||
@@ -65,14 +61,5 @@ func (stk *FallbackStack) List() context.Handlers {
|
||||
return res
|
||||
}
|
||||
|
||||
// NewFallbackStack create a new Fallback stack with as first entry
|
||||
// a handler which send NotFound status (the default)
|
||||
func NewFallbackStack() *FallbackStack {
|
||||
return &FallbackStack{
|
||||
handlers: context.Handlers{
|
||||
func(ctx context.Context) {
|
||||
ctx.StatusCode(http.StatusNotFound)
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
// NewFallbackStack create a new empty Fallback stack.
|
||||
func NewFallbackStack() *FallbackStack { return &FallbackStack{} }
|
||||
|
||||
@@ -94,8 +94,7 @@ func TestFallbackStackCall(t *testing.T) {
|
||||
// setup fallback handler
|
||||
app.Fallback(func(ctx context.Context) {
|
||||
if ctx.Method() != "GET" {
|
||||
ctx.Next()
|
||||
|
||||
ctx.NextOrNotFound() // it checks if we have next, otherwise fire 404 not found.
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,11 @@ type routerHandler struct {
|
||||
trees []*tree
|
||||
hosts bool // true if at least one route contains a Subdomain.
|
||||
fallbackStack *FallbackStack
|
||||
// on build: true if fallbackStack.Size() > 0,
|
||||
// reduces the checks because fallbackStack is NEVER nil (api_builder.go always initializes it).
|
||||
// If re-checked needed (serve-time fallback handler added)
|
||||
// then a re-build/refresh of the application's router is necessary, as with every handler.
|
||||
hasFallbackHandlers bool
|
||||
}
|
||||
|
||||
var _ RequestHandler = &routerHandler{}
|
||||
@@ -93,6 +98,7 @@ func (h *routerHandler) Build(provider RoutesProvider) error {
|
||||
registeredRoutes := provider.GetRoutes()
|
||||
h.trees = h.trees[0:0] // reset, inneed when rebuilding.
|
||||
h.fallbackStack = provider.GetFallBackStack()
|
||||
h.hasFallbackHandlers = h.fallbackStack.Size() > 0
|
||||
|
||||
// sort, subdomains goes first.
|
||||
sort.Slice(registeredRoutes, func(i, j int) bool {
|
||||
@@ -248,11 +254,12 @@ func (h *routerHandler) HandleRequest(ctx context.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
if h.fallbackStack == nil {
|
||||
ctx.StatusCode(http.StatusNotFound)
|
||||
} else {
|
||||
if h.hasFallbackHandlers {
|
||||
ctx.Do(h.fallbackStack.List())
|
||||
return
|
||||
}
|
||||
|
||||
ctx.StatusCode(http.StatusNotFound)
|
||||
}
|
||||
|
||||
// RouteExists checks if a route exists
|
||||
|
||||
Reference in New Issue
Block a user