This commit is contained in:
Gerasimos (Makis) Maropoulos 2020-08-15 12:17:48 +03:00
parent d0d7679a98
commit 8340285e7d
No known key found for this signature in database
GPG Key ID: 5DBE766BD26A54E7
11 changed files with 105 additions and 11 deletions

View File

@ -395,7 +395,9 @@ func main() {
} }
``` ```
- `Application.UseRouter(...Handler)` - per party to register handlers before the main router, useful on handlers that should control whether the router itself should ran or not. Independently of the incoming request's method and path values. These handlers will be executed ALWAYS against ALL incoming matched requests. Example of use-case: CORS. - `Party.UseError(...Handler)` - to register handlers to run before the `OnErrorCode/OnAnyErrorCode` ones.
- `Party.UseRouter(...Handler)` - to register handlers before the main router, useful on handlers that should control whether the router itself should ran or not. Independently of the incoming request's method and path values. These handlers will be executed ALWAYS against ALL incoming matched requests. Example of use-case: CORS.
- `*versioning.Group` type is a full `Party` now. - `*versioning.Group` type is a full `Party` now.

View File

@ -61,6 +61,7 @@
* [Wildcard](routing/subdomains/wildcard/main.go) * [Wildcard](routing/subdomains/wildcard/main.go)
* [WWW](routing/subdomains/www/main.go) * [WWW](routing/subdomains/www/main.go)
* [Redirection](routing/subdomains/redirect/main.go) * [Redirection](routing/subdomains/redirect/main.go)
* [HTTP Errors View](routing/subdomains/http-errors-view/main.go)
* [HTTP Method Override](https://github.com/kataras/iris/blob/master/middleware/methodoverride/methodoverride_test.go) * [HTTP Method Override](https://github.com/kataras/iris/blob/master/middleware/methodoverride/methodoverride_test.go)
* [API Versioning](routing/versioning/main.go) * [API Versioning](routing/versioning/main.go)
* [Sitemap](routing/sitemap/main.go) * [Sitemap](routing/sitemap/main.go)

View File

@ -0,0 +1,30 @@
package main
import "github.com/kataras/iris/v12"
func main() {
newApp().Listen("mydomain.com:80", iris.WithLogLevel("debug"))
}
func newApp() *iris.Application {
app := iris.New()
test := app.Subdomain("test")
test.RegisterView(iris.HTML("./views", ".html").
Layout("layouts/test.layout.html"))
test.OnErrorCode(iris.StatusNotFound, handleNotFoundTestSubdomain)
test.Get("/", testIndex)
return app
}
func handleNotFoundTestSubdomain(ctx iris.Context) {
ctx.View("error.html", iris.Map{
"ErrorCode": ctx.GetStatusCode(),
})
}
func testIndex(ctx iris.Context) {
ctx.Writef("%s index page\n", ctx.Subdomain())
}

View File

@ -0,0 +1,9 @@
<div style="background-color: black; color: red">
<h1>Oups, you've got an error!</h1>
{{ if .ErrorCode }}
{{ $tmplName := print "partials/" .ErrorCode ".html"}}
{{ render $tmplName }}
{{ else }}
{{ render "partials/500.html" }}
{{ end }}
</div>

View File

@ -0,0 +1,3 @@
<div style="background-color: black; color: blue">
Index Page
</div>

View File

@ -0,0 +1,12 @@
<html>
<head>
<title>Website Layout</title>
</head>
<body>
<h1>This is the global layout</h1>
<br />
<!-- Render the current template here -->
{{ yield }}
</body>
</html>

View File

@ -0,0 +1,10 @@
<html>
<head>
<title>Test Subdomain</title>
</head>
<body>
<!-- Render the current template here -->
{{ yield }}
</body>
</html>

View File

@ -0,0 +1,3 @@
<div style="background-color: white; color: red">
<h1>Not Found</h1>
</div>

View File

@ -0,0 +1,3 @@
<div style="background-color: white; color: red">
<h1>Internal Server Error</h1>
</div>

View File

@ -174,6 +174,7 @@ type APIBuilder struct {
// the per-party handlers, order // the per-party handlers, order
// of handlers registration matters. // of handlers registration matters.
middleware context.Handlers middleware context.Handlers
middlewareErrorCode context.Handlers
// the global middleware handlers, order of call doesn't matters, order // the global middleware handlers, order of call doesn't matters, order
// of handlers registration matters. We need a secondary field for this // of handlers registration matters. We need a secondary field for this
// because `UseGlobal` registers handlers that should be executed // because `UseGlobal` registers handlers that should be executed
@ -539,6 +540,8 @@ func (api *APIBuilder) createRoutes(errorCode int, methods []string, relativePat
if errorCode == 0 { if errorCode == 0 {
beginHandlers = context.JoinHandlers(beginHandlers, api.middleware) beginHandlers = context.JoinHandlers(beginHandlers, api.middleware)
doneHandlers = context.JoinHandlers(doneHandlers, api.doneHandlers) doneHandlers = context.JoinHandlers(doneHandlers, api.doneHandlers)
} else {
beginHandlers = context.JoinHandlers(beginHandlers, api.middlewareErrorCode)
} }
mainHandlers := context.Handlers(handlers) mainHandlers := context.Handlers(handlers)
@ -549,7 +552,7 @@ func (api *APIBuilder) createRoutes(errorCode int, methods []string, relativePat
mainHandlerFileName, mainHandlerFileNumber := context.HandlerFileLineRel(handlers[mainHandlerIndex]) mainHandlerFileName, mainHandlerFileNumber := context.HandlerFileLineRel(handlers[mainHandlerIndex])
// re-calculate mainHandlerIndex in favor of the middlewares. // re-calculate mainHandlerIndex in favor of the middlewares.
mainHandlerIndex = len(api.middleware) + len(api.beginGlobalHandlers) + mainHandlerIndex mainHandlerIndex = len(beginHandlers) + mainHandlerIndex
// TODO: for UseGlobal/DoneGlobal that doesn't work. // TODO: for UseGlobal/DoneGlobal that doesn't work.
applyExecutionRules(api.handlerExecutionRules, &beginHandlers, &doneHandlers, &mainHandlers) applyExecutionRules(api.handlerExecutionRules, &beginHandlers, &doneHandlers, &mainHandlers)
@ -668,6 +671,7 @@ func (api *APIBuilder) Party(relativePath string, handlers ...context.Handler) P
// per-party/children // per-party/children
parent: api, parent: api,
middleware: middleware, middleware: middleware,
middlewareErrorCode: context.JoinHandlers(api.middlewareErrorCode, context.Handlers{}),
doneHandlers: api.doneHandlers[0:], doneHandlers: api.doneHandlers[0:],
relativePath: fullpath, relativePath: fullpath,
allowMethods: allowMethods, allowMethods: allowMethods,
@ -938,6 +942,13 @@ func (api *APIBuilder) UseRouter(handlers ...context.Handler) {
} }
} }
// UseError upserts one or more handlers that will be fired,
// as middleware, before any error handler registered through `On(Any)ErrorCode`.
// See `OnErrorCode` too.
func (api *APIBuilder) UseError(handlers ...context.Handler) {
api.middlewareErrorCode = context.UpsertHandlers(api.middlewareErrorCode, handlers)
}
// Use appends Handler(s) to the current Party's routes and child routes. // Use appends Handler(s) to the current Party's routes and child routes.
// 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.
// //
@ -1011,6 +1022,7 @@ func (api *APIBuilder) DoneGlobal(handlers ...context.Handler) {
// Returns this Party. // Returns this Party.
func (api *APIBuilder) Reset() Party { func (api *APIBuilder) Reset() Party {
api.middleware = api.middleware[0:0] api.middleware = api.middleware[0:0]
api.middlewareErrorCode = api.middlewareErrorCode[0:0]
api.doneHandlers = api.doneHandlers[0:0] api.doneHandlers = api.doneHandlers[0:0]
api.handlerExecutionRules = ExecutionRules{} api.handlerExecutionRules = ExecutionRules{}
api.routeRegisterRule = RouteOverride api.routeRegisterRule = RouteOverride
@ -1189,7 +1201,7 @@ func (api *APIBuilder) Favicon(favPath string, requestPath ...string) *Route {
// OnErrorCode registers a handlers chain for this `Party` for a specific HTTP status code. // OnErrorCode registers a handlers chain for this `Party` for a specific HTTP status code.
// Read more at: http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml // Read more at: http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
// Look `OnAnyErrorCode` too. // Look `UseError` and `OnAnyErrorCode` too.
func (api *APIBuilder) OnErrorCode(statusCode int, handlers ...context.Handler) (routes []*Route) { func (api *APIBuilder) OnErrorCode(statusCode int, handlers ...context.Handler) (routes []*Route) {
routes = append(routes, api.handle(statusCode, "", "/", handlers...)) routes = append(routes, api.handle(statusCode, "", "/", handlers...))
@ -1202,7 +1214,7 @@ func (api *APIBuilder) OnErrorCode(statusCode int, handlers ...context.Handler)
// OnAnyErrorCode registers a handlers chain for all error codes // OnAnyErrorCode registers a handlers chain for all error codes
// (4xxx and 5xxx, change the `context.ClientErrorCodes` and `context.ServerErrorCodes` variables to modify those) // (4xxx and 5xxx, change the `context.ClientErrorCodes` and `context.ServerErrorCodes` variables to modify those)
// Look `OnErrorCode` too. // Look `UseError` and `OnErrorCode` too.
func (api *APIBuilder) OnAnyErrorCode(handlers ...context.Handler) (routes []*Route) { func (api *APIBuilder) OnAnyErrorCode(handlers ...context.Handler) (routes []*Route) {
for _, statusCode := range context.ClientAndServerErrorCodes { for _, statusCode := range context.ClientAndServerErrorCodes {
routes = append(routes, api.OnErrorCode(statusCode, handlers...)...) routes = append(routes, api.OnErrorCode(statusCode, handlers...)...)
@ -1221,10 +1233,12 @@ func (api *APIBuilder) RegisterView(viewEngine context.ViewEngine) {
return return
} }
api.Use(func(ctx *context.Context) { handler := func(ctx *context.Context) {
ctx.ViewEngine(viewEngine) ctx.ViewEngine(viewEngine)
ctx.Next() ctx.Next()
}) }
api.Use(handler)
api.UseError(handler)
// Note (@kataras): It does not return the Party in order // Note (@kataras): It does not return the Party in order
// to keep the iris.Application a compatible Party. // to keep the iris.Application a compatible Party.
} }
@ -1244,10 +1258,13 @@ func (api *APIBuilder) RegisterView(viewEngine context.ViewEngine) {
// //
// Examples: https://github.com/kataras/iris/tree/master/_examples/view // Examples: https://github.com/kataras/iris/tree/master/_examples/view
func (api *APIBuilder) Layout(tmplLayoutFile string) Party { func (api *APIBuilder) Layout(tmplLayoutFile string) Party {
api.Use(func(ctx *context.Context) { handler := func(ctx *context.Context) {
ctx.ViewLayout(tmplLayoutFile) ctx.ViewLayout(tmplLayoutFile)
ctx.Next() ctx.Next()
}) }
api.Use(handler)
api.UseError(handler)
return api return api
} }

View File

@ -41,11 +41,11 @@ type Party interface {
// OnErrorCode registers a handlers chain for this `Party` for a specific HTTP status code. // OnErrorCode registers a handlers chain for this `Party` for a specific HTTP status code.
// Read more at: http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml // Read more at: http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
// Look `OnAnyErrorCode` too. // Look `UseError` and `OnAnyErrorCode` too.
OnErrorCode(statusCode int, handlers ...context.Handler) []*Route OnErrorCode(statusCode int, handlers ...context.Handler) []*Route
// OnAnyErrorCode registers a handlers chain for all error codes // OnAnyErrorCode registers a handlers chain for all error codes
// (4xxx and 5xxx, change the `ClientErrorCodes` and `ServerErrorCodes` variables to modify those) // (4xxx and 5xxx, change the `ClientErrorCodes` and `ServerErrorCodes` variables to modify those)
// Look `OnErrorCode` too. // Look `UseError` and `OnErrorCode` too.
OnAnyErrorCode(handlers ...context.Handler) []*Route OnAnyErrorCode(handlers ...context.Handler) []*Route
// Party returns a new child Party which inherites its // Party returns a new child Party which inherites its
@ -96,6 +96,10 @@ type Party interface {
// The context SHOULD call its `Next` method in order to proceed to // The context SHOULD call its `Next` method in order to proceed to
// the next handler in the chain or the main request handler one. // the next handler in the chain or the main request handler one.
UseRouter(handlers ...context.Handler) UseRouter(handlers ...context.Handler)
// UseError upserts one or more handlers that will be fired,
// as middleware, before any error handler registered through `On(Any)ErrorCode`.
// See `OnErrorCode` too.
UseError(handlers ...context.Handler)
// Use appends Handler(s) to the current Party's routes and child routes. // Use appends Handler(s) to the current Party's routes and child routes.
// 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)