1
0
mirror of https://github.com/kataras/iris.git synced 2025-12-20 11:27:06 +00:00

Add a simple and pure .Regex middleware for routers that don't support regex route path validations out-of-the-box

Former-commit-id: 84cf1fb267e54543ad6d419b2ca39658b2773b58
This commit is contained in:
Gerasimos (Makis) Maropoulos
2017-02-22 00:51:50 +02:00
parent 51c74b5bb6
commit 42cf24fda2
10 changed files with 132 additions and 81 deletions

View File

@@ -4,6 +4,7 @@ import (
"net/http"
"os"
"path"
"regexp"
"strings"
"time"
@@ -130,6 +131,66 @@ type Router struct {
relativePath string
}
// Regex takes pairs with the named path (without symbols) following by its expression
// and returns a middleware which will do a pure but effective validation using the regexp package.
//
// Note: '/adaptors/gorillamux' already supports regex path validation.
// It's useful while the developer uses the '/adaptors/httprouter' instead.
func (s *Framework) Regex(pairParamExpr ...string) HandlerFunc {
srvErr := func(ctx *Context) {
ctx.EmitError(StatusInternalServerError)
}
wp := s.policies.RouterReversionPolicy.WildcardPath
if wp == nil {
s.Log(ProdMode, "expr cannot be used when a router policy is missing\n"+errRouterIsMissing.Format(s.Config.VHost).Error())
return srvErr
}
if len(pairParamExpr)%2 != 0 {
s.Log(ProdMode,
"regexp expr pre-compile error: the correct format is paramName, expression"+
"paramName2, expression2. The len should be %2==0")
return srvErr
}
pairs := make(map[string]*regexp.Regexp, len(pairParamExpr)/2)
for i := 0; i < len(pairParamExpr)-1; i++ {
expr := pairParamExpr[i+1]
r, err := regexp.Compile(expr)
if err != nil {
s.Log(ProdMode, "expr: regexp failed on: "+expr+". Trace:"+err.Error())
return srvErr
}
pairs[pairParamExpr[i]] = r
i++
}
// return the middleware
return func(ctx *Context) {
for k, v := range pairs {
pathPart := ctx.Param(k)
if pathPart == "" {
// take care, the router already
// does the param validations
// so if it's empty here it means that
// the router has label it as optional.
// so we skip it, and continue to the next.
continue
}
// the improtant thing:
// if the path part didn't match with the relative exp, then fire status not found.
if !v.MatchString(pathPart) {
ctx.EmitError(StatusNotFound)
return
}
}
// otherwise continue to the next handler...
ctx.Next()
}
}
var (
// errDirectoryFileNotFound returns an error with message: 'Directory or file %s couldn't found. Trace: +error trace'
errDirectoryFileNotFound = errors.New("Directory or file %s couldn't found. Trace: %s")