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.

View File

@ -61,6 +61,7 @@
* [Wildcard](routing/subdomains/wildcard/main.go)
* [WWW](routing/subdomains/www/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)
* [API Versioning](routing/versioning/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

@ -173,7 +173,8 @@ type APIBuilder struct {
// the per-party handlers, order
// of handlers registration matters.
middleware context.Handlers
middleware context.Handlers
middlewareErrorCode context.Handlers
// the global middleware handlers, order of call doesn't matters, order
// of handlers registration matters. We need a secondary field for this
// because `UseGlobal` registers handlers that should be executed
@ -539,6 +540,8 @@ func (api *APIBuilder) createRoutes(errorCode int, methods []string, relativePat
if errorCode == 0 {
beginHandlers = context.JoinHandlers(beginHandlers, api.middleware)
doneHandlers = context.JoinHandlers(doneHandlers, api.doneHandlers)
} else {
beginHandlers = context.JoinHandlers(beginHandlers, api.middlewareErrorCode)
}
mainHandlers := context.Handlers(handlers)
@ -549,7 +552,7 @@ func (api *APIBuilder) createRoutes(errorCode int, methods []string, relativePat
mainHandlerFileName, mainHandlerFileNumber := context.HandlerFileLineRel(handlers[mainHandlerIndex])
// 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.
applyExecutionRules(api.handlerExecutionRules, &beginHandlers, &doneHandlers, &mainHandlers)
@ -668,6 +671,7 @@ func (api *APIBuilder) Party(relativePath string, handlers ...context.Handler) P
// per-party/children
parent: api,
middleware: middleware,
middlewareErrorCode: context.JoinHandlers(api.middlewareErrorCode, context.Handlers{}),
doneHandlers: api.doneHandlers[0:],
relativePath: fullpath,
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.
// 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.
func (api *APIBuilder) Reset() Party {
api.middleware = api.middleware[0:0]
api.middlewareErrorCode = api.middlewareErrorCode[0:0]
api.doneHandlers = api.doneHandlers[0:0]
api.handlerExecutionRules = ExecutionRules{}
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.
// 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) {
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
// (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) {
for _, statusCode := range context.ClientAndServerErrorCodes {
routes = append(routes, api.OnErrorCode(statusCode, handlers...)...)
@ -1221,10 +1233,12 @@ func (api *APIBuilder) RegisterView(viewEngine context.ViewEngine) {
return
}
api.Use(func(ctx *context.Context) {
handler := func(ctx *context.Context) {
ctx.ViewEngine(viewEngine)
ctx.Next()
})
}
api.Use(handler)
api.UseError(handler)
// Note (@kataras): It does not return the Party in order
// 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
func (api *APIBuilder) Layout(tmplLayoutFile string) Party {
api.Use(func(ctx *context.Context) {
handler := func(ctx *context.Context) {
ctx.ViewLayout(tmplLayoutFile)
ctx.Next()
})
}
api.Use(handler)
api.UseError(handler)
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.
// 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
// OnAnyErrorCode registers a handlers chain for all error codes
// (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
// 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 next handler in the chain or the main request handler one.
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.
// If the current Party is the root, then it registers the middleware to all child Parties' routes too.
Use(middleware ...context.Handler)