mirror of
https://github.com/kataras/iris.git
synced 2025-12-20 11:27:06 +00:00
Add fallback handlers
Former-commit-id: f7e9bd17076a10e1ed1702780d7ce9e89f00b592
This commit is contained in:
@@ -22,6 +22,8 @@ type RequestHandler interface {
|
||||
HandleRequest(context.Context)
|
||||
// Build should builds the handler, it's being called on router's BuildRouter.
|
||||
Build(provider RoutesProvider) error
|
||||
// RouteExists checks if a route exists
|
||||
RouteExists(method, path string, ctx context.Context) bool
|
||||
}
|
||||
|
||||
type tree struct {
|
||||
@@ -84,12 +86,13 @@ type RoutesProvider interface { // api builder
|
||||
GetRoutes() []*Route
|
||||
GetRoute(routeName string) *Route
|
||||
|
||||
FallBackStack() *FallbackStack
|
||||
GetFallBackStack() *FallbackStack
|
||||
}
|
||||
|
||||
func (h *routerHandler) Build(provider RoutesProvider) error {
|
||||
registeredRoutes := provider.GetRoutes()
|
||||
h.trees = h.trees[0:0] // reset, inneed when rebuilding.
|
||||
h.fallbackStack = provider.GetFallBackStack()
|
||||
|
||||
// sort, subdomains goes first.
|
||||
sort.Slice(registeredRoutes, func(i, j int) bool {
|
||||
@@ -245,5 +248,62 @@ func (h *routerHandler) HandleRequest(ctx context.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
ctx.Do(h.fallbackStack.list())
|
||||
if h.fallbackStack == nil {
|
||||
ctx.StatusCode(http.StatusNotFound)
|
||||
} else {
|
||||
ctx.Do(h.fallbackStack.List())
|
||||
}
|
||||
}
|
||||
|
||||
// RouteExists checks if a route exists
|
||||
func (h *routerHandler) RouteExists(method, path string, ctx context.Context) bool {
|
||||
for i := range h.trees {
|
||||
t := h.trees[i]
|
||||
if method != t.Method {
|
||||
continue
|
||||
}
|
||||
|
||||
if h.hosts && t.Subdomain != "" {
|
||||
requestHost := ctx.Host()
|
||||
if netutil.IsLoopbackSubdomain(requestHost) {
|
||||
// this fixes a bug when listening on
|
||||
// 127.0.0.1:8080 for example
|
||||
// and have a wildcard subdomain and a route registered to root domain.
|
||||
continue // it's not a subdomain, it's something like 127.0.0.1 probably
|
||||
}
|
||||
// it's a dynamic wildcard subdomain, we have just to check if ctx.subdomain is not empty
|
||||
if t.Subdomain == SubdomainWildcardIndicator {
|
||||
// mydomain.com -> invalid
|
||||
// localhost -> invalid
|
||||
// sub.mydomain.com -> valid
|
||||
// sub.localhost -> valid
|
||||
serverHost := ctx.Application().ConfigurationReadOnly().GetVHost()
|
||||
if serverHost == requestHost {
|
||||
continue // it's not a subdomain, it's a full domain (with .com...)
|
||||
}
|
||||
|
||||
dotIdx := strings.IndexByte(requestHost, '.')
|
||||
slashIdx := strings.IndexByte(requestHost, '/')
|
||||
if dotIdx > 0 && (slashIdx == -1 || slashIdx > dotIdx) {
|
||||
// if "." was found anywhere but not at the first path segment (host).
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
// continue to that, any subdomain is valid.
|
||||
} else if !strings.HasPrefix(requestHost, t.Subdomain) { // t.Subdomain contains the dot.
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
_, handlers := t.Nodes.Find(path, ctx.Params())
|
||||
if len(handlers) > 0 {
|
||||
// found
|
||||
return true
|
||||
}
|
||||
|
||||
// not found or method not allowed.
|
||||
break
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user