1
0
mirror of https://github.com/kataras/iris.git synced 2026-01-10 13:35:59 +00:00

Implement the Status Method Not Allowed for gorilla mux too and add some tests

Former-commit-id: b157bacfa15567b8c98f959f3359e025fdf1b205
This commit is contained in:
Gerasimos (Makis) Maropoulos
2017-02-21 14:20:31 +02:00
parent 6fca78d12a
commit b25d99870e
5 changed files with 164 additions and 10 deletions

View File

@@ -34,6 +34,15 @@ import (
const dynamicSymbol = '{'
func staticPath(path string) string {
i := strings.IndexByte(path, dynamicSymbol)
if i > -1 {
return path[0:i]
}
return path
}
// New returns a new gorilla mux router which can be plugged inside iris.
// This is magic.
func New() iris.Policies {
@@ -46,14 +55,7 @@ func New() iris.Policies {
}},
RouterReversionPolicy: iris.RouterReversionPolicy{
// path normalization done on iris' side
StaticPath: func(path string) string {
i := strings.IndexByte(path, dynamicSymbol)
if i > -1 {
return path[0:i]
}
return path
},
StaticPath: staticPath,
WildcardPath: func(requestPath string, paramName string) string {
return requestPath + "/{" + paramName + ":.*}"
},
@@ -94,10 +96,48 @@ func New() iris.Policies {
router.NotFoundHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := context.Acquire(w, r)
// to catch custom 404 not found http errors may registered by user
ctx.EmitError(iris.StatusNotFound)
// gorilla mux doesn't supports fire method not allowed like iris
// so this is my hack to support it:
if ctx.Framework().Config.FireMethodNotAllowed {
stopVisitor := false
repo.Visit(func(route iris.RouteInfo) {
if stopVisitor {
return
}
// this is not going to work 100% for all routes especially the coblex
// but this is the best solution, to check via static path, subdomain and cors to find the 'correct' route to
// compare its method in order to implement the status method not allowed in gorilla mux which doesn't support it
// and if I edit its internal implementation it will be complicated for new releases to be updated.
p := staticPath(route.Path())
if route.Subdomain() == "" || route.Subdomain() == ctx.Subdomain() {
if p == ctx.Path() {
// we don't care about this route because it has cors and this method is options
// or its method is equal with the requests but the router didn't select this route
// that means that the dynamic path didn't match, so we skip it.
if (route.HasCors() && ctx.Method() == iris.MethodOptions) || ctx.Method() == route.Method() {
return
}
if ctx.Method() != route.Method() {
// RCF rfc2616 https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
// The response MUST include an Allow header containing a list of valid methods for the requested resource.
ctx.SetHeader("Allow", route.Method())
ctx.EmitError(iris.StatusMethodNotAllowed)
stopVisitor = true
return
}
}
}
})
} else {
// to catch custom 404 not found http errors may registered by user
ctx.EmitError(iris.StatusNotFound)
}
context.Release(ctx)
})
return router
},
}