mirror of
https://github.com/kataras/iris.git
synced 2025-03-15 03:56:27 +01:00
Thanks goes to all of you you help building this (nice) framework - Update README and add errors on mux entry register
This commit is contained in:
parent
dcded4e400
commit
647f0d704c
|
@ -84,7 +84,7 @@ Docs & Community
|
||||||
|
|
||||||
- Take a look at the [examples](https://github.com/iris-contrib/examples)
|
- Take a look at the [examples](https://github.com/iris-contrib/examples)
|
||||||
|
|
||||||
- If for some reason your old code doesn't runs, view the [HISTORY](https://github.com//kataras/iris/tree/master/HISTORY.md)
|
- [HISTORY](https://github.com//kataras/iris/tree/master/HISTORY.md) file is your friend.
|
||||||
|
|
||||||
|
|
||||||
If you'd like to discuss this package, or ask questions about it, feel free to
|
If you'd like to discuss this package, or ask questions about it, feel free to
|
||||||
|
@ -150,7 +150,9 @@ If you're willing to donate click [here](DONATIONS.md)
|
||||||
|
|
||||||
People
|
People
|
||||||
------------
|
------------
|
||||||
The author of Iris is [@kataras](https://github.com/kataras)
|
A big thanks goes to [all people](https://github.com/kataras/iris/issues?utf8=%E2%9C%93&q=label%3A%22feature+request%22) who help building this framework with feature-requests, bug reports and more!
|
||||||
|
|
||||||
|
The author of Iris is [@kataras](https://github.com/kataras).
|
||||||
|
|
||||||
|
|
||||||
License
|
License
|
||||||
|
|
72
http.go
72
http.go
|
@ -11,6 +11,7 @@ import (
|
||||||
|
|
||||||
"github.com/kataras/iris/config"
|
"github.com/kataras/iris/config"
|
||||||
"github.com/kataras/iris/errors"
|
"github.com/kataras/iris/errors"
|
||||||
|
"github.com/kataras/iris/logger"
|
||||||
"github.com/kataras/iris/utils"
|
"github.com/kataras/iris/utils"
|
||||||
"github.com/valyala/fasthttp"
|
"github.com/valyala/fasthttp"
|
||||||
"github.com/valyala/fasthttp/fasthttpadaptor"
|
"github.com/valyala/fasthttp/fasthttpadaptor"
|
||||||
|
@ -567,6 +568,17 @@ type (
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
errMuxEntryConflictsWildcard = errors.New("Router: Path's part: '%s' conflicts with wildcard '%s' in the route path: '%s' !")
|
||||||
|
errMuxEntryMiddlewareAlreadyExists = errors.New("Router: Middleware were already registered for the path: '%s' !")
|
||||||
|
errMuxEntryInvalidWildcard = errors.New("Router: More than one wildcard found in the path part: '%s' in route's path: '%s' !")
|
||||||
|
errMuxEntryConflictsExistingWildcard = errors.New("Router: Wildcard for route path: '%s' conflicts with existing children in route path: '%s' !")
|
||||||
|
errMuxEntryWildcardUnnamed = errors.New("Router: Unnamed wildcard found in path: '%s' !")
|
||||||
|
errMuxEntryWildcardInvalidPlace = errors.New("Router: Wildcard is only allowed at the end of the path, in the route path: '%s' !")
|
||||||
|
errMuxEntryWildcardConflictsMiddleware = errors.New("Router: Wildcard conflicts with existing middleware for the route path: '%s' !")
|
||||||
|
errMuxEntryWildcardMissingSlash = errors.New("Router: No slash(/) were found before wildcard in the route path: '%s' !")
|
||||||
|
)
|
||||||
|
|
||||||
// Get returns a value from a key inside this Parameters
|
// Get returns a value from a key inside this Parameters
|
||||||
// If no parameter with this key given then it returns an empty string
|
// If no parameter with this key given then it returns an empty string
|
||||||
func (params PathParameters) Get(key string) string {
|
func (params PathParameters) Get(key string) string {
|
||||||
|
@ -635,7 +647,7 @@ func getParamsLen(path string) uint8 {
|
||||||
}
|
}
|
||||||
|
|
||||||
// add adds a muxEntry to the existing muxEntry or to the tree if no muxEntry has the prefix of
|
// add adds a muxEntry to the existing muxEntry or to the tree if no muxEntry has the prefix of
|
||||||
func (e *muxEntry) add(path string, middleware Middleware) {
|
func (e *muxEntry) add(path string, middleware Middleware) error {
|
||||||
fullPath := path
|
fullPath := path
|
||||||
e.precedence++
|
e.precedence++
|
||||||
numParams := getParamsLen(path)
|
numParams := getParamsLen(path)
|
||||||
|
@ -694,8 +706,7 @@ func (e *muxEntry) add(path string, middleware Middleware) {
|
||||||
continue loop
|
continue loop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return errMuxEntryConflictsWildcard.Format(path, e.part, fullPath)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
c := path[0]
|
c := path[0]
|
||||||
|
@ -725,24 +736,25 @@ func (e *muxEntry) add(path string, middleware Middleware) {
|
||||||
e = node
|
e = node
|
||||||
}
|
}
|
||||||
e.addNode(numParams, path, fullPath, middleware)
|
e.addNode(numParams, path, fullPath, middleware)
|
||||||
return
|
return nil
|
||||||
|
|
||||||
} else if i == len(path) {
|
} else if i == len(path) {
|
||||||
if e.middleware != nil {
|
if e.middleware != nil {
|
||||||
return
|
return errMuxEntryMiddlewareAlreadyExists.Format(fullPath)
|
||||||
}
|
}
|
||||||
e.middleware = middleware
|
e.middleware = middleware
|
||||||
}
|
}
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
e.addNode(numParams, path, fullPath, middleware)
|
e.addNode(numParams, path, fullPath, middleware)
|
||||||
e.entryCase = isRoot
|
e.entryCase = isRoot
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// addNode adds a muxEntry as children to other muxEntry
|
// addNode adds a muxEntry as children to other muxEntry
|
||||||
func (e *muxEntry) addNode(numParams uint8, path string, fullPath string, middleware Middleware) {
|
func (e *muxEntry) addNode(numParams uint8, path string, fullPath string, middleware Middleware) error {
|
||||||
var offset int
|
var offset int
|
||||||
|
|
||||||
for i, max := 0, len(path); numParams > 0; i++ {
|
for i, max := 0, len(path); numParams > 0; i++ {
|
||||||
|
@ -752,21 +764,25 @@ func (e *muxEntry) addNode(numParams uint8, path string, fullPath string, middle
|
||||||
}
|
}
|
||||||
|
|
||||||
end := i + 1
|
end := i + 1
|
||||||
for end < max && path[end] != '/' {
|
for end < max && path[end] != slashByte {
|
||||||
switch path[end] {
|
switch path[end] {
|
||||||
case parameterStartByte, matchEverythingByte:
|
case parameterStartByte, matchEverythingByte:
|
||||||
|
/*
|
||||||
|
panic("only one wildcard per path segment is allowed, has: '" +
|
||||||
|
path[i:] + "' in path '" + fullPath + "'")
|
||||||
|
*/
|
||||||
|
return errMuxEntryInvalidWildcard.Format(path[i:], fullPath)
|
||||||
default:
|
default:
|
||||||
end++
|
end++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(e.nodes) > 0 {
|
if len(e.nodes) > 0 {
|
||||||
return
|
return errMuxEntryConflictsExistingWildcard.Format(path[i:end], fullPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
if end-i < 2 {
|
if end-i < 2 {
|
||||||
return
|
return errMuxEntryWildcardUnnamed.Format(fullPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
if c == parameterStartByte {
|
if c == parameterStartByte {
|
||||||
|
@ -800,16 +816,16 @@ func (e *muxEntry) addNode(numParams uint8, path string, fullPath string, middle
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if end != max || numParams > 1 {
|
if end != max || numParams > 1 {
|
||||||
return
|
return errMuxEntryWildcardInvalidPlace.Format(fullPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(e.part) > 0 && e.part[len(e.part)-1] == '/' {
|
if len(e.part) > 0 && e.part[len(e.part)-1] == '/' {
|
||||||
return
|
return errMuxEntryWildcardConflictsMiddleware.Format(fullPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
i--
|
i--
|
||||||
if path[i] != '/' {
|
if path[i] != slashByte {
|
||||||
return
|
return errMuxEntryWildcardMissingSlash.Format(fullPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
e.part = path[offset:i]
|
e.part = path[offset:i]
|
||||||
|
@ -833,12 +849,14 @@ func (e *muxEntry) addNode(numParams uint8, path string, fullPath string, middle
|
||||||
}
|
}
|
||||||
e.nodes = []*muxEntry{child}
|
e.nodes = []*muxEntry{child}
|
||||||
|
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
e.part = path[offset:]
|
e.part = path[offset:]
|
||||||
e.middleware = middleware
|
e.middleware = middleware
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// get is used by the Router, it finds and returns the correct muxEntry for a path
|
// get is used by the Router, it finds and returns the correct muxEntry for a path
|
||||||
|
@ -1081,8 +1099,9 @@ type (
|
||||||
|
|
||||||
api *muxAPI
|
api *muxAPI
|
||||||
errorHandlers map[int]Handler
|
errorHandlers map[int]Handler
|
||||||
// the main server host, ex: localhost, 127.0.0.1:8080, iris-go.com
|
logger *logger.Logger
|
||||||
host string
|
// the main server host's name, ex: localhost, 127.0.0.1, iris-go.com
|
||||||
|
hostname string
|
||||||
// if any of the trees contains not empty subdomain
|
// if any of the trees contains not empty subdomain
|
||||||
hosts bool
|
hosts bool
|
||||||
// if false then searching by unescaped path
|
// if false then searching by unescaped path
|
||||||
|
@ -1095,21 +1114,22 @@ type (
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func newServeMux(contextPool sync.Pool) *serveMux {
|
func newServeMux(contextPool sync.Pool, logger *logger.Logger) *serveMux {
|
||||||
mux := &serveMux{
|
mux := &serveMux{
|
||||||
cPool: &contextPool,
|
cPool: &contextPool,
|
||||||
lookups: make([]*route, 0),
|
lookups: make([]*route, 0),
|
||||||
errorHandlers: make(map[int]Handler, 0),
|
errorHandlers: make(map[int]Handler, 0),
|
||||||
host: config.DefaultServerAddr,
|
hostname: "127.0.0.1",
|
||||||
escapePath: !config.DefaultDisablePathEscape,
|
escapePath: !config.DefaultDisablePathEscape,
|
||||||
correctPath: !config.DefaultDisablePathCorrection,
|
correctPath: !config.DefaultDisablePathCorrection,
|
||||||
|
logger: logger,
|
||||||
}
|
}
|
||||||
|
|
||||||
return mux
|
return mux
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mux *serveMux) setHost(h string) {
|
func (mux *serveMux) setHostname(h string) {
|
||||||
mux.host = h
|
mux.hostname = h
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mux *serveMux) setEscapePath(b bool) {
|
func (mux *serveMux) setEscapePath(b bool) {
|
||||||
|
@ -1191,7 +1211,9 @@ func (mux *serveMux) register(method []byte, subdomain string, path string, midd
|
||||||
}
|
}
|
||||||
// I decide that it's better to explicit give subdomain and a path to it than registedPath(mysubdomain./something) now its: subdomain: mysubdomain., path: /something
|
// I decide that it's better to explicit give subdomain and a path to it than registedPath(mysubdomain./something) now its: subdomain: mysubdomain., path: /something
|
||||||
// we have different tree for each of subdomains, now you can use everyting you can use with the normal paths ( before you couldn't set /any/*path)
|
// we have different tree for each of subdomains, now you can use everyting you can use with the normal paths ( before you couldn't set /any/*path)
|
||||||
tree.entry.add(path, middleware)
|
if err := tree.entry.add(path, middleware); err != nil {
|
||||||
|
mux.logger.Panic(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
// add to the lookups, it's just a collection of routes information
|
// add to the lookups, it's just a collection of routes information
|
||||||
lookup := newRoute(method, subdomain, path, middleware)
|
lookup := newRoute(method, subdomain, path, middleware)
|
||||||
|
@ -1237,13 +1259,13 @@ func (mux *serveMux) ServeRequest() fasthttp.RequestHandler {
|
||||||
if mux.hosts && tree.subdomain != "" {
|
if mux.hosts && tree.subdomain != "" {
|
||||||
// context.VirtualHost() is a slow method because it makes string.Replaces but user can understand that if subdomain then server will have some nano/or/milleseconds performance cost
|
// context.VirtualHost() is a slow method because it makes string.Replaces but user can understand that if subdomain then server will have some nano/or/milleseconds performance cost
|
||||||
requestHost := context.VirtualHostname()
|
requestHost := context.VirtualHostname()
|
||||||
if requestHost != mux.host {
|
if requestHost != mux.hostname {
|
||||||
// we have a subdomain
|
// we have a subdomain
|
||||||
if strings.Index(tree.subdomain, dynamicSubdomainIndicator) != -1 {
|
if strings.Index(tree.subdomain, dynamicSubdomainIndicator) != -1 {
|
||||||
} else {
|
} else {
|
||||||
// mux.host = iris-go.com:8080, the subdomain for example is api.,
|
// mux.host = iris-go.com:8080, the subdomain for example is api.,
|
||||||
// so the host must be api.iris-go.com:8080
|
// so the host must be api.iris-go.com:8080
|
||||||
if tree.subdomain+mux.host != requestHost {
|
if tree.subdomain+mux.hostname != requestHost {
|
||||||
// go to the next tree, we have a subdomain but it is not the correct
|
// go to the next tree, we have a subdomain but it is not the correct
|
||||||
tree = tree.next
|
tree = tree.next
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -99,7 +99,7 @@ func New(cfg ...config.Iris) *Framework {
|
||||||
// set the websocket server
|
// set the websocket server
|
||||||
s.Websocket = websocket.NewServer(s.Config.Websocket)
|
s.Websocket = websocket.NewServer(s.Config.Websocket)
|
||||||
// set the servemux, which will provide us the public API also, with its context pool
|
// set the servemux, which will provide us the public API also, with its context pool
|
||||||
mux := newServeMux(sync.Pool{New: func() interface{} { return &Context{framework: s} }})
|
mux := newServeMux(sync.Pool{New: func() interface{} { return &Context{framework: s} }}, s.Logger)
|
||||||
// set the public router API (and party)
|
// set the public router API (and party)
|
||||||
s.muxAPI = &muxAPI{mux: mux, relativePath: "/"}
|
s.muxAPI = &muxAPI{mux: mux, relativePath: "/"}
|
||||||
// set the server
|
// set the server
|
||||||
|
@ -128,7 +128,7 @@ func (s *Framework) initialize() {
|
||||||
// prepare the mux
|
// prepare the mux
|
||||||
s.mux.setCorrectPath(!s.Config.DisablePathCorrection)
|
s.mux.setCorrectPath(!s.Config.DisablePathCorrection)
|
||||||
s.mux.setEscapePath(!s.Config.DisablePathEscape)
|
s.mux.setEscapePath(!s.Config.DisablePathEscape)
|
||||||
s.mux.setHost(s.HTTPServer.VirtualHostname())
|
s.mux.setHostname(s.HTTPServer.VirtualHostname())
|
||||||
// set the debug profiling handlers if ProfilePath is setted
|
// set the debug profiling handlers if ProfilePath is setted
|
||||||
if debugPath := s.Config.ProfilePath; debugPath != "" {
|
if debugPath := s.Config.ProfilePath; debugPath != "" {
|
||||||
s.Handle(MethodGet, debugPath+"/*action", profileMiddleware(debugPath)...)
|
s.Handle(MethodGet, debugPath+"/*action", profileMiddleware(debugPath)...)
|
||||||
|
|
4
iris.go
4
iris.go
|
@ -1042,7 +1042,7 @@ func StaticFS(reqPath string, systemPath string, stripSlashes int) RouteNameFunc
|
||||||
// * stripSlashes = 2, original path: "/foo/bar", result: ""
|
// * stripSlashes = 2, original path: "/foo/bar", result: ""
|
||||||
func (api *muxAPI) StaticFS(reqPath string, systemPath string, stripSlashes int) RouteNameFunc {
|
func (api *muxAPI) StaticFS(reqPath string, systemPath string, stripSlashes int) RouteNameFunc {
|
||||||
if reqPath[len(reqPath)-1] != slashByte {
|
if reqPath[len(reqPath)-1] != slashByte {
|
||||||
reqPath += "/"
|
reqPath += slash
|
||||||
}
|
}
|
||||||
|
|
||||||
h := api.StaticHandler(systemPath, stripSlashes, true, true, nil)
|
h := api.StaticHandler(systemPath, stripSlashes, true, true, nil)
|
||||||
|
@ -1074,7 +1074,7 @@ func StaticWeb(reqPath string, systemPath string, stripSlashes int) RouteNameFun
|
||||||
// * if you don't know what to put on stripSlashes just 1
|
// * if you don't know what to put on stripSlashes just 1
|
||||||
func (api *muxAPI) StaticWeb(reqPath string, systemPath string, stripSlashes int) RouteNameFunc {
|
func (api *muxAPI) StaticWeb(reqPath string, systemPath string, stripSlashes int) RouteNameFunc {
|
||||||
if reqPath[len(reqPath)-1] != slashByte { // if / then /*filepath, if /something then /something/*filepath
|
if reqPath[len(reqPath)-1] != slashByte { // if / then /*filepath, if /something then /something/*filepath
|
||||||
reqPath += "/"
|
reqPath += slash
|
||||||
}
|
}
|
||||||
|
|
||||||
hasIndex := utils.Exists(systemPath + utils.PathSeparator + "index.html")
|
hasIndex := utils.Exists(systemPath + utils.PathSeparator + "index.html")
|
||||||
|
|
|
@ -110,7 +110,7 @@ func (l *Logger) Fatalf(format string, a ...interface{}) {
|
||||||
|
|
||||||
// Panic is equivalent to l.Dangerf("%#v",interface{}) followed by a call to panic().
|
// Panic is equivalent to l.Dangerf("%#v",interface{}) followed by a call to panic().
|
||||||
func (l *Logger) Panic(a interface{}) {
|
func (l *Logger) Panic(a interface{}) {
|
||||||
l.Dangerf("%#v", a)
|
l.Dangerf("%s\n", a)
|
||||||
panic("")
|
panic("")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user