iris/core/router/macro.go

257 lines
7.3 KiB
Go
Raw Normal View History

Publish the new version :airplane: | Look description please! # FAQ ### Looking for free support? http://support.iris-go.com https://kataras.rocket.chat/channel/iris ### Looking for previous versions? https://github.com/kataras/iris#version ### Should I upgrade my Iris? Developers are not forced to upgrade if they don't really need it. Upgrade whenever you feel ready. > Iris uses the [vendor directory](https://docs.google.com/document/d/1Bz5-UB7g2uPBdOx-rw5t9MxJwkfpx90cqG9AFL0JAYo) feature, so you get truly reproducible builds, as this method guards against upstream renames and deletes. **How to upgrade**: Open your command-line and execute this command: `go get -u github.com/kataras/iris`. For further installation support, please click [here](http://support.iris-go.com/d/16-how-to-install-iris-web-framework). ### About our new home page http://iris-go.com Thanks to [Santosh Anand](https://github.com/santoshanand) the http://iris-go.com has been upgraded and it's really awesome! [Santosh](https://github.com/santoshanand) is a freelancer, he has a great knowledge of nodejs and express js, Android, iOS, React Native, Vue.js etc, if you need a developer to find or create a solution for your problem or task, please contact with him. The amount of the next two or three donations you'll send they will be immediately transferred to his own account balance, so be generous please! Read more at https://github.com/kataras/iris/blob/master/HISTORY.md Former-commit-id: eec2d71bbe011d6b48d2526eb25919e36e5ad94e
2017-06-03 22:22:52 +02:00
// Copyright 2017 Gerasimos Maropoulos, ΓΜ. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package router
import (
"net/http"
"strconv"
"strings"
"github.com/kataras/iris/context"
"github.com/kataras/iris/core/errors"
"github.com/kataras/iris/core/router/macro"
"github.com/kataras/iris/core/router/macro/interpreter/ast"
)
// defaultMacros returns a new macro map which
// contains the default router's named param types functions.
func defaultMacros() *macro.Map {
macros := macro.NewMap()
Publish the new version :airplane: | Look description please! # FAQ ### Looking for free support? http://support.iris-go.com https://kataras.rocket.chat/channel/iris ### Looking for previous versions? https://github.com/kataras/iris#version ### Should I upgrade my Iris? Developers are not forced to upgrade if they don't really need it. Upgrade whenever you feel ready. > Iris uses the [vendor directory](https://docs.google.com/document/d/1Bz5-UB7g2uPBdOx-rw5t9MxJwkfpx90cqG9AFL0JAYo) feature, so you get truly reproducible builds, as this method guards against upstream renames and deletes. **How to upgrade**: Open your command-line and execute this command: `go get -u github.com/kataras/iris`. For further installation support, please click [here](http://support.iris-go.com/d/16-how-to-install-iris-web-framework). ### About our new home page http://iris-go.com Thanks to [Santosh Anand](https://github.com/santoshanand) the http://iris-go.com has been upgraded and it's really awesome! [Santosh](https://github.com/santoshanand) is a freelancer, he has a great knowledge of nodejs and express js, Android, iOS, React Native, Vue.js etc, if you need a developer to find or create a solution for your problem or task, please contact with him. The amount of the next two or three donations you'll send they will be immediately transferred to his own account balance, so be generous please! Read more at https://github.com/kataras/iris/blob/master/HISTORY.md Former-commit-id: eec2d71bbe011d6b48d2526eb25919e36e5ad94e
2017-06-03 22:22:52 +02:00
// registers the String and Int default macro funcs
// user can add or override of his own funcs later on
// i.e:
// app.Macro.String.RegisterFunc("equal", func(eqWith string) func(string) bool {
// return func(paramValue string) bool {
// return eqWith == paramValue
// }})
registerBuiltinsMacroFuncs(macros)
return macros
}
func registerBuiltinsMacroFuncs(out *macro.Map) {
Publish the new version :airplane: | Look description please! # FAQ ### Looking for free support? http://support.iris-go.com https://kataras.rocket.chat/channel/iris ### Looking for previous versions? https://github.com/kataras/iris#version ### Should I upgrade my Iris? Developers are not forced to upgrade if they don't really need it. Upgrade whenever you feel ready. > Iris uses the [vendor directory](https://docs.google.com/document/d/1Bz5-UB7g2uPBdOx-rw5t9MxJwkfpx90cqG9AFL0JAYo) feature, so you get truly reproducible builds, as this method guards against upstream renames and deletes. **How to upgrade**: Open your command-line and execute this command: `go get -u github.com/kataras/iris`. For further installation support, please click [here](http://support.iris-go.com/d/16-how-to-install-iris-web-framework). ### About our new home page http://iris-go.com Thanks to [Santosh Anand](https://github.com/santoshanand) the http://iris-go.com has been upgraded and it's really awesome! [Santosh](https://github.com/santoshanand) is a freelancer, he has a great knowledge of nodejs and express js, Android, iOS, React Native, Vue.js etc, if you need a developer to find or create a solution for your problem or task, please contact with him. The amount of the next two or three donations you'll send they will be immediately transferred to his own account balance, so be generous please! Read more at https://github.com/kataras/iris/blob/master/HISTORY.md Former-commit-id: eec2d71bbe011d6b48d2526eb25919e36e5ad94e
2017-06-03 22:22:52 +02:00
// register the String which is the default type if not
// parameter type is specified or
// if a given parameter into path given but the func doesn't exist on the
// parameter type's function list.
//
// these can be overridden by the user, later on.
registerStringMacroFuncs(out.String)
registerIntMacroFuncs(out.Int)
registerAlphabeticalMacroFuncs(out.Alphabetical)
registerFileMacroFuncs(out.File)
registerPathMacroFuncs(out.Path)
}
// String
// anything one part
func registerStringMacroFuncs(out *macro.Macro) {
// this can be used everywhere, it's to help users to define custom regexp expressions
// on all macros
out.RegisterFunc("regexp", func(expr string) macro.EvaluatorFunc {
regexpEvaluator := macro.MustNewEvaluatorFromRegexp(expr)
return regexpEvaluator
})
// checks if param value starts with the 'prefix' arg
out.RegisterFunc("prefix", func(prefix string) macro.EvaluatorFunc {
return func(paramValue string) bool {
return strings.HasPrefix(paramValue, prefix)
}
})
// checks if param value ends with the 'suffix' arg
out.RegisterFunc("suffix", func(suffix string) macro.EvaluatorFunc {
return func(paramValue string) bool {
return strings.HasSuffix(paramValue, suffix)
}
})
// checks if param value contains the 's' arg
out.RegisterFunc("contains", func(s string) macro.EvaluatorFunc {
return func(paramValue string) bool {
return strings.Contains(paramValue, s)
}
})
// checks if param value's length is at least 'min'
out.RegisterFunc("min", func(min int) macro.EvaluatorFunc {
return func(paramValue string) bool {
return len(paramValue) >= min
}
})
// checks if param value's length is not bigger than 'max'
out.RegisterFunc("max", func(max int) macro.EvaluatorFunc {
return func(paramValue string) bool {
return max >= len(paramValue)
}
})
}
// Int
// only numbers (0-9)
func registerIntMacroFuncs(out *macro.Macro) {
// checks if the param value's int representation is
// bigger or equal than 'min'
out.RegisterFunc("min", func(min int) macro.EvaluatorFunc {
return func(paramValue string) bool {
n, err := strconv.Atoi(paramValue)
if err != nil {
return false
}
return n >= min
}
})
// checks if the param value's int representation is
// smaller or equal than 'max'
out.RegisterFunc("max", func(max int) macro.EvaluatorFunc {
return func(paramValue string) bool {
n, err := strconv.Atoi(paramValue)
if err != nil {
return false
}
return n <= max
}
})
// checks if the param value's int representation is
// between min and max, including 'min' and 'max'
out.RegisterFunc("range", func(min, max int) macro.EvaluatorFunc {
return func(paramValue string) bool {
n, err := strconv.Atoi(paramValue)
if err != nil {
return false
}
if n < min || n > max {
return false
}
return true
}
})
}
// Alphabetical
// letters only (upper or lowercase)
func registerAlphabeticalMacroFuncs(out *macro.Macro) {
}
// File
// letters (upper or lowercase)
// numbers (0-9)
// underscore (_)
// dash (-)
// point (.)
// no spaces! or other character
func registerFileMacroFuncs(out *macro.Macro) {
}
// Path
// File+slashes(anywhere)
// should be the latest param, it's the wildcard
func registerPathMacroFuncs(out *macro.Macro) {
}
// compileRoutePathAndHandlers receives a route info and returns its parsed/"compiled" path
// and the new handlers (prepend all the macro's handler, if any).
//
// It's not exported for direct use.
func compileRoutePathAndHandlers(handlers context.Handlers, tmpl *macro.Template) (string, context.Handlers, error) {
// parse the path to node's path, now.
path, err := convertTmplToNodePath(tmpl)
if err != nil {
return tmpl.Src, handlers, err
}
// prepend the macro handler to the route, now,
// right before the register to the tree, so routerbuilder.UseGlobal will work as expected.
if len(tmpl.Params) > 0 {
macroEvaluatorHandler := convertTmplToHandler(tmpl)
// may return nil if no really need a macro handler evaluator
if macroEvaluatorHandler != nil {
handlers = append(context.Handlers{macroEvaluatorHandler}, handlers...)
}
}
return path, handlers, nil
}
func convertTmplToNodePath(tmpl *macro.Template) (string, error) {
routePath := tmpl.Src
if len(tmpl.Params) > 0 {
if routePath[len(routePath)-1] == '/' {
routePath = routePath[0 : len(routePath)-2] // remove the last "/" if macro syntax instead of underline's
}
}
Publish the new version :airplane: | Look description please! # FAQ ### Looking for free support? http://support.iris-go.com https://kataras.rocket.chat/channel/iris ### Looking for previous versions? https://github.com/kataras/iris#version ### Should I upgrade my Iris? Developers are not forced to upgrade if they don't really need it. Upgrade whenever you feel ready. > Iris uses the [vendor directory](https://docs.google.com/document/d/1Bz5-UB7g2uPBdOx-rw5t9MxJwkfpx90cqG9AFL0JAYo) feature, so you get truly reproducible builds, as this method guards against upstream renames and deletes. **How to upgrade**: Open your command-line and execute this command: `go get -u github.com/kataras/iris`. For further installation support, please click [here](http://support.iris-go.com/d/16-how-to-install-iris-web-framework). ### About our new home page http://iris-go.com Thanks to [Santosh Anand](https://github.com/santoshanand) the http://iris-go.com has been upgraded and it's really awesome! [Santosh](https://github.com/santoshanand) is a freelancer, he has a great knowledge of nodejs and express js, Android, iOS, React Native, Vue.js etc, if you need a developer to find or create a solution for your problem or task, please contact with him. The amount of the next two or three donations you'll send they will be immediately transferred to his own account balance, so be generous please! Read more at https://github.com/kataras/iris/blob/master/HISTORY.md Former-commit-id: eec2d71bbe011d6b48d2526eb25919e36e5ad94e
2017-06-03 22:22:52 +02:00
// if it has started with {} and it's valid
// then the tmpl.Params will be filled,
// so no any further check needed
for i, p := range tmpl.Params {
if p.Type == ast.ParamTypePath {
if i != len(tmpl.Params)-1 {
return "", errors.New("parameter type \"ParamTypePath\" should be putted to the very last of a path")
Publish the new version :airplane: | Look description please! # FAQ ### Looking for free support? http://support.iris-go.com https://kataras.rocket.chat/channel/iris ### Looking for previous versions? https://github.com/kataras/iris#version ### Should I upgrade my Iris? Developers are not forced to upgrade if they don't really need it. Upgrade whenever you feel ready. > Iris uses the [vendor directory](https://docs.google.com/document/d/1Bz5-UB7g2uPBdOx-rw5t9MxJwkfpx90cqG9AFL0JAYo) feature, so you get truly reproducible builds, as this method guards against upstream renames and deletes. **How to upgrade**: Open your command-line and execute this command: `go get -u github.com/kataras/iris`. For further installation support, please click [here](http://support.iris-go.com/d/16-how-to-install-iris-web-framework). ### About our new home page http://iris-go.com Thanks to [Santosh Anand](https://github.com/santoshanand) the http://iris-go.com has been upgraded and it's really awesome! [Santosh](https://github.com/santoshanand) is a freelancer, he has a great knowledge of nodejs and express js, Android, iOS, React Native, Vue.js etc, if you need a developer to find or create a solution for your problem or task, please contact with him. The amount of the next two or three donations you'll send they will be immediately transferred to his own account balance, so be generous please! Read more at https://github.com/kataras/iris/blob/master/HISTORY.md Former-commit-id: eec2d71bbe011d6b48d2526eb25919e36e5ad94e
2017-06-03 22:22:52 +02:00
}
routePath = strings.Replace(routePath, p.Src, WildcardParam(p.Name), 1)
} else {
routePath = strings.Replace(routePath, p.Src, Param(p.Name), 1)
}
}
return routePath, nil
}
// note: returns nil if not needed, the caller(router) should be check for that before adding that on route's Middleware
func convertTmplToHandler(tmpl *macro.Template) context.Handler {
Publish the new version :airplane: | Look description please! # FAQ ### Looking for free support? http://support.iris-go.com https://kataras.rocket.chat/channel/iris ### Looking for previous versions? https://github.com/kataras/iris#version ### Should I upgrade my Iris? Developers are not forced to upgrade if they don't really need it. Upgrade whenever you feel ready. > Iris uses the [vendor directory](https://docs.google.com/document/d/1Bz5-UB7g2uPBdOx-rw5t9MxJwkfpx90cqG9AFL0JAYo) feature, so you get truly reproducible builds, as this method guards against upstream renames and deletes. **How to upgrade**: Open your command-line and execute this command: `go get -u github.com/kataras/iris`. For further installation support, please click [here](http://support.iris-go.com/d/16-how-to-install-iris-web-framework). ### About our new home page http://iris-go.com Thanks to [Santosh Anand](https://github.com/santoshanand) the http://iris-go.com has been upgraded and it's really awesome! [Santosh](https://github.com/santoshanand) is a freelancer, he has a great knowledge of nodejs and express js, Android, iOS, React Native, Vue.js etc, if you need a developer to find or create a solution for your problem or task, please contact with him. The amount of the next two or three donations you'll send they will be immediately transferred to his own account balance, so be generous please! Read more at https://github.com/kataras/iris/blob/master/HISTORY.md Former-commit-id: eec2d71bbe011d6b48d2526eb25919e36e5ad94e
2017-06-03 22:22:52 +02:00
needMacroHandler := false
// check if we have params like: {name:string} or {name} or {anything:path} without else keyword or any functions used inside these params.
// 1. if we don't have, then we don't need to add a handler before the main route's handler (as I said, no performance if macro is not really used)
// 2. if we don't have any named params then we don't need a handler too.
for _, p := range tmpl.Params {
if len(p.Funcs) == 0 && (p.Type == ast.ParamTypeUnExpected || p.Type == ast.ParamTypeString || p.Type == ast.ParamTypePath) && p.ErrCode == http.StatusNotFound {
Publish the new version :airplane: | Look description please! # FAQ ### Looking for free support? http://support.iris-go.com https://kataras.rocket.chat/channel/iris ### Looking for previous versions? https://github.com/kataras/iris#version ### Should I upgrade my Iris? Developers are not forced to upgrade if they don't really need it. Upgrade whenever you feel ready. > Iris uses the [vendor directory](https://docs.google.com/document/d/1Bz5-UB7g2uPBdOx-rw5t9MxJwkfpx90cqG9AFL0JAYo) feature, so you get truly reproducible builds, as this method guards against upstream renames and deletes. **How to upgrade**: Open your command-line and execute this command: `go get -u github.com/kataras/iris`. For further installation support, please click [here](http://support.iris-go.com/d/16-how-to-install-iris-web-framework). ### About our new home page http://iris-go.com Thanks to [Santosh Anand](https://github.com/santoshanand) the http://iris-go.com has been upgraded and it's really awesome! [Santosh](https://github.com/santoshanand) is a freelancer, he has a great knowledge of nodejs and express js, Android, iOS, React Native, Vue.js etc, if you need a developer to find or create a solution for your problem or task, please contact with him. The amount of the next two or three donations you'll send they will be immediately transferred to his own account balance, so be generous please! Read more at https://github.com/kataras/iris/blob/master/HISTORY.md Former-commit-id: eec2d71bbe011d6b48d2526eb25919e36e5ad94e
2017-06-03 22:22:52 +02:00
} else {
// println("we need handler for: " + tmpl.Src)
Publish the new version :airplane: | Look description please! # FAQ ### Looking for free support? http://support.iris-go.com https://kataras.rocket.chat/channel/iris ### Looking for previous versions? https://github.com/kataras/iris#version ### Should I upgrade my Iris? Developers are not forced to upgrade if they don't really need it. Upgrade whenever you feel ready. > Iris uses the [vendor directory](https://docs.google.com/document/d/1Bz5-UB7g2uPBdOx-rw5t9MxJwkfpx90cqG9AFL0JAYo) feature, so you get truly reproducible builds, as this method guards against upstream renames and deletes. **How to upgrade**: Open your command-line and execute this command: `go get -u github.com/kataras/iris`. For further installation support, please click [here](http://support.iris-go.com/d/16-how-to-install-iris-web-framework). ### About our new home page http://iris-go.com Thanks to [Santosh Anand](https://github.com/santoshanand) the http://iris-go.com has been upgraded and it's really awesome! [Santosh](https://github.com/santoshanand) is a freelancer, he has a great knowledge of nodejs and express js, Android, iOS, React Native, Vue.js etc, if you need a developer to find or create a solution for your problem or task, please contact with him. The amount of the next two or three donations you'll send they will be immediately transferred to his own account balance, so be generous please! Read more at https://github.com/kataras/iris/blob/master/HISTORY.md Former-commit-id: eec2d71bbe011d6b48d2526eb25919e36e5ad94e
2017-06-03 22:22:52 +02:00
needMacroHandler = true
}
}
if !needMacroHandler {
// println("we don't need handler for: " + tmpl.Src)
Publish the new version :airplane: | Look description please! # FAQ ### Looking for free support? http://support.iris-go.com https://kataras.rocket.chat/channel/iris ### Looking for previous versions? https://github.com/kataras/iris#version ### Should I upgrade my Iris? Developers are not forced to upgrade if they don't really need it. Upgrade whenever you feel ready. > Iris uses the [vendor directory](https://docs.google.com/document/d/1Bz5-UB7g2uPBdOx-rw5t9MxJwkfpx90cqG9AFL0JAYo) feature, so you get truly reproducible builds, as this method guards against upstream renames and deletes. **How to upgrade**: Open your command-line and execute this command: `go get -u github.com/kataras/iris`. For further installation support, please click [here](http://support.iris-go.com/d/16-how-to-install-iris-web-framework). ### About our new home page http://iris-go.com Thanks to [Santosh Anand](https://github.com/santoshanand) the http://iris-go.com has been upgraded and it's really awesome! [Santosh](https://github.com/santoshanand) is a freelancer, he has a great knowledge of nodejs and express js, Android, iOS, React Native, Vue.js etc, if you need a developer to find or create a solution for your problem or task, please contact with him. The amount of the next two or three donations you'll send they will be immediately transferred to his own account balance, so be generous please! Read more at https://github.com/kataras/iris/blob/master/HISTORY.md Former-commit-id: eec2d71bbe011d6b48d2526eb25919e36e5ad94e
2017-06-03 22:22:52 +02:00
return nil
}
return func(tmpl macro.Template) context.Handler {
return func(ctx context.Context) {
for _, p := range tmpl.Params {
paramValue := ctx.Params().Get(p.Name)
// first, check for type evaluator
if !p.TypeEvaluator(paramValue) {
ctx.StatusCode(p.ErrCode)
ctx.StopExecution()
return
}
// then check for all of its functions
for _, evalFunc := range p.Funcs {
if !evalFunc(paramValue) {
ctx.StatusCode(p.ErrCode)
ctx.StopExecution()
return
}
}
}
// if all passed, just continue
ctx.Next()
}
}(*tmpl)
}