mirror of
https://github.com/kataras/iris.git
synced 2025-03-15 17:36:29 +01:00
Document https://github.com/kataras/iris/issues/720 and fix https://github.com/kataras/iris/issues/719 for good
Former-commit-id: 75b855bee9216c28ce8e1ff46aee467766c37f23
This commit is contained in:
parent
960ddb9f72
commit
39a24fb7cb
1
_examples/file-server/basic/assets/index.html
Normal file
1
_examples/file-server/basic/assets/index.html
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<h1>Hello index</h1>
|
|
@ -20,8 +20,16 @@ type MyContext struct {
|
||||||
|
|
||||||
var _ context.Context = &MyContext{} // optionally: validate on compile-time if MyContext implements context.Context.
|
var _ context.Context = &MyContext{} // optionally: validate on compile-time if MyContext implements context.Context.
|
||||||
|
|
||||||
// Optional Part 2:
|
// The only one important if you will override the Context
|
||||||
// The only one important if you will override the Context with an embedded context.Context inside it.
|
// with an embedded context.Context inside it.
|
||||||
|
// Required in order to run the handlers via this "*MyContext".
|
||||||
|
func (ctx *MyContext) Do(handlers context.Handlers) {
|
||||||
|
context.Do(ctx, handlers)
|
||||||
|
}
|
||||||
|
|
||||||
|
// The second one important if you will override the Context
|
||||||
|
// with an embedded context.Context inside it.
|
||||||
|
// Required in order to run the chain of handlers via this "*MyContext".
|
||||||
func (ctx *MyContext) Next() {
|
func (ctx *MyContext) Next() {
|
||||||
context.Next(ctx)
|
context.Next(ctx)
|
||||||
}
|
}
|
||||||
|
@ -40,11 +48,9 @@ func main() {
|
||||||
app := iris.New()
|
app := iris.New()
|
||||||
// app.Logger().SetLevel("debug")
|
// app.Logger().SetLevel("debug")
|
||||||
|
|
||||||
// Register a view engine on .html files inside the ./view/** directory.
|
|
||||||
app.RegisterView(iris.HTML("./view", ".html"))
|
|
||||||
|
|
||||||
// The only one Required:
|
// The only one Required:
|
||||||
// here is how you define how your own context will be created and acquired from the iris' generic context pool.
|
// here is how you define how your own context will
|
||||||
|
// be created and acquired from the iris' generic context pool.
|
||||||
app.ContextPool.Attach(func() context.Context {
|
app.ContextPool.Attach(func() context.Context {
|
||||||
return &MyContext{
|
return &MyContext{
|
||||||
// Optional Part 3:
|
// Optional Part 3:
|
||||||
|
@ -52,6 +58,9 @@ func main() {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Register a view engine on .html files inside the ./view/** directory.
|
||||||
|
app.RegisterView(iris.HTML("./view", ".html"))
|
||||||
|
|
||||||
// register your route, as you normally do
|
// register your route, as you normally do
|
||||||
app.Handle("GET", "/", recordWhichContextJustForProofOfConcept, func(ctx context.Context) {
|
app.Handle("GET", "/", recordWhichContextJustForProofOfConcept, func(ctx context.Context) {
|
||||||
// use the context's overridden HTML method.
|
// use the context's overridden HTML method.
|
||||||
|
|
|
@ -14,12 +14,13 @@ func main() {
|
||||||
// / -> because of app.Get("/", ...)
|
// / -> because of app.Get("/", ...)
|
||||||
// /other/anything/here -> because of app.Get("/other/{paramother:path}", ...)
|
// /other/anything/here -> because of app.Get("/other/{paramother:path}", ...)
|
||||||
// /other2/anything/here -> because of app.Get("/other2/{paramothersecond:path}", ...)
|
// /other2/anything/here -> because of app.Get("/other2/{paramothersecond:path}", ...)
|
||||||
// /other2/static -> because of app.Get("/other2/static", ...)
|
// /other2/static2 -> because of app.Get("/other2/static", ...)
|
||||||
//
|
//
|
||||||
// It isn't conflicts with the rest of the routes, without routing performance cost!
|
// It isn't conflicts with the rest of the routes, without routing performance cost!
|
||||||
//
|
//
|
||||||
// i.e /something/here/that/cannot/be/found/by/other/registered/routes/order/not/matters
|
// i.e /something/here/that/cannot/be/found/by/other/registered/routes/order/not/matters
|
||||||
app.Get("/{p:path}", h)
|
app.Get("/{p:path}", h)
|
||||||
|
// app.Get("/static/{p:path}", staticWildcardH)
|
||||||
|
|
||||||
// this will handle only GET /
|
// this will handle only GET /
|
||||||
app.Get("/", staticPath)
|
app.Get("/", staticPath)
|
||||||
|
@ -36,7 +37,7 @@ func main() {
|
||||||
app.Get("/other2/{paramothersecond:path}", other2)
|
app.Get("/other2/{paramothersecond:path}", other2)
|
||||||
|
|
||||||
// this will handle only GET "/other2/static"
|
// this will handle only GET "/other2/static"
|
||||||
app.Get("/other2/static", staticPath)
|
app.Get("/other2/static2", staticPathOther2)
|
||||||
|
|
||||||
app.Run(iris.Addr(":8080"), iris.WithoutServerError(iris.ErrServerClosed))
|
app.Run(iris.Addr(":8080"), iris.WithoutServerError(iris.ErrServerClosed))
|
||||||
}
|
}
|
||||||
|
@ -46,6 +47,11 @@ func h(ctx context.Context) {
|
||||||
ctx.WriteString(param)
|
ctx.WriteString(param)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func staticWildcardH(ctx context.Context) {
|
||||||
|
param := ctx.Params().Get("p")
|
||||||
|
ctx.WriteString("from staticWildcardH: param=" + param)
|
||||||
|
}
|
||||||
|
|
||||||
func other(ctx context.Context) {
|
func other(ctx context.Context) {
|
||||||
param := ctx.Params().Get("paramother")
|
param := ctx.Params().Get("paramother")
|
||||||
ctx.Writef("from other: %s", param)
|
ctx.Writef("from other: %s", param)
|
||||||
|
@ -57,5 +63,9 @@ func other2(ctx context.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func staticPath(ctx context.Context) {
|
func staticPath(ctx context.Context) {
|
||||||
ctx.Writef("from the static path: %s", ctx.Path())
|
ctx.Writef("from the static path(/): %s", ctx.Path())
|
||||||
|
}
|
||||||
|
|
||||||
|
func staticPathOther2(ctx context.Context) {
|
||||||
|
ctx.Writef("from the static path(/other2/static2): %s", ctx.Path())
|
||||||
}
|
}
|
||||||
|
|
|
@ -758,6 +758,19 @@ func Next(ctx Context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Do calls the SetHandlers(handlers)
|
||||||
|
// and executes the first handler,
|
||||||
|
// handlers should not be empty.
|
||||||
|
//
|
||||||
|
// It's used by the router, developers may use that
|
||||||
|
// to replace and execute handlers immediately.
|
||||||
|
func Do(ctx Context, handlers Handlers) {
|
||||||
|
if len(handlers) > 0 {
|
||||||
|
ctx.SetHandlers(handlers)
|
||||||
|
handlers[0](ctx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// LimitRequestBodySize is a middleware which sets a request body size limit
|
// LimitRequestBodySize is a middleware which sets a request body size limit
|
||||||
// for all next handlers in the chain.
|
// for all next handlers in the chain.
|
||||||
var LimitRequestBodySize = func(maxRequestBodySizeBytes int64) Handler {
|
var LimitRequestBodySize = func(maxRequestBodySizeBytes int64) Handler {
|
||||||
|
|
|
@ -21,6 +21,11 @@ func New(newFunc func() Context) *Pool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attach changes the pool's return value Context.
|
// Attach changes the pool's return value Context.
|
||||||
|
//
|
||||||
|
// The new Context should explicitly define the `Next()`
|
||||||
|
// and `Do(context.Handlers)` functions.
|
||||||
|
//
|
||||||
|
// Example: https://github.com/kataras/iris/blob/master/_examples/routing/custom-context/method-overriding/main.go
|
||||||
func (c *Pool) Attach(newFunc func() Context) {
|
func (c *Pool) Attach(newFunc func() Context) {
|
||||||
c.newFunc = newFunc
|
c.newFunc = newFunc
|
||||||
}
|
}
|
||||||
|
|
|
@ -658,6 +658,7 @@ func (rb *APIBuilder) StaticWeb(requestPath string, systemPath string) *Route {
|
||||||
}
|
}
|
||||||
|
|
||||||
requestPath = joinPath(fullpath, WildcardParam(paramName))
|
requestPath = joinPath(fullpath, WildcardParam(paramName))
|
||||||
|
// requestPath = fullpath + "/{file:path}"
|
||||||
return rb.registerResourceRoute(requestPath, handler)
|
return rb.registerResourceRoute(requestPath, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,8 @@ type node struct {
|
||||||
// ErrDublicate returnned from `Add` when two or more routes have the same registered path.
|
// ErrDublicate returnned from `Add` when two or more routes have the same registered path.
|
||||||
var ErrDublicate = errors.New("two or more routes have the same registered path")
|
var ErrDublicate = errors.New("two or more routes have the same registered path")
|
||||||
|
|
||||||
|
/// TODO: clean up needed until v8.5
|
||||||
|
|
||||||
// Add adds a node to the tree, returns an ErrDublicate error on failure.
|
// Add adds a node to the tree, returns an ErrDublicate error on failure.
|
||||||
func (nodes *Nodes) Add(path string, handlers context.Handlers) error {
|
func (nodes *Nodes) Add(path string, handlers context.Handlers) error {
|
||||||
// println("[Add] adding path: " + path)
|
// println("[Add] adding path: " + path)
|
||||||
|
@ -99,15 +101,19 @@ func (nodes *Nodes) add(path string, paramNames []string, handlers context.Handl
|
||||||
// set the wildcard param name to the root and its children.
|
// set the wildcard param name to the root and its children.
|
||||||
wildcardIdx := strings.IndexByte(path, '*')
|
wildcardIdx := strings.IndexByte(path, '*')
|
||||||
wildcardParamName := ""
|
wildcardParamName := ""
|
||||||
if wildcardIdx > 0 {
|
if wildcardIdx > 0 && len(paramNames) == 0 {
|
||||||
wildcardParamName = path[wildcardIdx+1:]
|
wildcardParamName = path[wildcardIdx+1:]
|
||||||
|
|
||||||
path = path[0:wildcardIdx-1] + "/" // replace *paramName with single slash
|
path = path[0:wildcardIdx-1] + "/" // replace *paramName with single slash
|
||||||
|
|
||||||
|
// if path[len(path)-1] == '/' {
|
||||||
// if root wildcard, then add it as it's and return
|
// if root wildcard, then add it as it's and return
|
||||||
if path == "/" {
|
rootWildcard := path == "/"
|
||||||
|
if rootWildcard {
|
||||||
path += "/" // if root wildcard, then do it like "//" instead of simple "/"
|
path += "/" // if root wildcard, then do it like "//" instead of simple "/"
|
||||||
|
}
|
||||||
|
|
||||||
n := &node{
|
n := &node{
|
||||||
rootWildcard: true,
|
rootWildcard: rootWildcard,
|
||||||
s: path,
|
s: path,
|
||||||
wildcardParamName: wildcardParamName,
|
wildcardParamName: wildcardParamName,
|
||||||
paramNames: paramNames,
|
paramNames: paramNames,
|
||||||
|
@ -117,7 +123,6 @@ func (nodes *Nodes) add(path string, paramNames []string, handlers context.Handl
|
||||||
*nodes = append(*nodes, n)
|
*nodes = append(*nodes, n)
|
||||||
// println("1. nodes.Add path: " + path)
|
// println("1. nodes.Add path: " + path)
|
||||||
return
|
return
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,6 +132,10 @@ loop:
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(n.paramNames) == 0 && n.wildcardParamName != "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
minlen := len(n.s)
|
minlen := len(n.s)
|
||||||
if len(path) < minlen {
|
if len(path) < minlen {
|
||||||
minlen = len(path)
|
minlen = len(path)
|
||||||
|
@ -226,8 +235,9 @@ loop:
|
||||||
handlers: handlers,
|
handlers: handlers,
|
||||||
root: root,
|
root: root,
|
||||||
}
|
}
|
||||||
// println("5. nodes.Add path: " + n.s)
|
|
||||||
*nodes = append(*nodes, n)
|
*nodes = append(*nodes, n)
|
||||||
|
|
||||||
|
// println("5. node add on path: " + path + " n.s: " + n.s + " wildcard param: " + n.wildcardParamName)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,7 +286,7 @@ func (nodes Nodes) Exists(path string) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (nodes Nodes) findChild(path string, params []string) (*node, []string) {
|
func (nodes Nodes) findChild(path string, params []string) (*node, []string) {
|
||||||
// println("request path: " + path)
|
|
||||||
for _, n := range nodes {
|
for _, n := range nodes {
|
||||||
if n.s == ":" {
|
if n.s == ":" {
|
||||||
paramEnd := strings.IndexByte(path, '/')
|
paramEnd := strings.IndexByte(path, '/')
|
||||||
|
@ -309,8 +319,39 @@ func (nodes Nodes) findChild(path string, params []string) (*node, []string) {
|
||||||
return n, append(params, path[1:])
|
return n, append(params, path[1:])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// second conditional may be unnecessary
|
||||||
|
// because of the n.rootWildcard before, but do it.
|
||||||
|
if n.wildcardParamName != "" && len(path) > 2 {
|
||||||
|
// println("n has wildcard n.s: " + n.s + " on path: " + path)
|
||||||
|
// n.s = static/, path = static
|
||||||
|
|
||||||
|
// println(n.s + " vs path: " + path)
|
||||||
|
|
||||||
|
// we could have /other/ as n.s so
|
||||||
|
// we must do this check, remember:
|
||||||
|
// now wildcards live on their own nodes
|
||||||
|
if len(path) == len(n.s)-1 {
|
||||||
|
// then it's like:
|
||||||
|
// path = /other2
|
||||||
|
// ns = /other2/
|
||||||
|
if path == n.s[0:len(n.s)-1] {
|
||||||
|
return n, params
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// othwerwise path = /other2/dsadas
|
||||||
|
// ns= /other2/
|
||||||
|
if strings.HasPrefix(path, n.s) {
|
||||||
|
if len(path) > len(n.s)+1 {
|
||||||
|
return n, append(params, path[len(n.s):]) // without slash
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if !strings.HasPrefix(path, n.s) {
|
if !strings.HasPrefix(path, n.s) {
|
||||||
// fmt.Printf("---here root: %v, n.s: "+n.s+" and path: "+path+" is dynamic: %v , wildcardParamName: %s, children len: %v \n", n.root, n.isDynamic(), n.wildcardParamName, len(n.childrenNodes))
|
// fmt.Printf("---here root: %v, n.s: "+n.s+" and path: "+path+" is dynamic: %v , wildcardParamName: %s, children len: %v \n", n.root, n.isDynamic(), n.wildcardParamName, len(n.childrenNodes))
|
||||||
|
// println(path + " n.s: " + n.s + " continue...")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -322,6 +363,7 @@ func (nodes Nodes) findChild(path string, params []string) (*node, []string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
child, childParamNames := n.childrenNodes.findChild(path[len(n.s):], params)
|
child, childParamNames := n.childrenNodes.findChild(path[len(n.s):], params)
|
||||||
|
|
||||||
// print("childParamNames len: ")
|
// print("childParamNames len: ")
|
||||||
// println(len(childParamNames))
|
// println(len(childParamNames))
|
||||||
|
|
||||||
|
|
|
@ -117,13 +117,16 @@ func TestRouterWildcardRootManyAndRootStatic(t *testing.T) {
|
||||||
// this feature is very important and can remove noumerous of previous hacks on our apps.
|
// this feature is very important and can remove noumerous of previous hacks on our apps.
|
||||||
{"GET", "/{p:path}", h, []testRouteRequest{
|
{"GET", "/{p:path}", h, []testRouteRequest{
|
||||||
{"GET", "", "/other2almost/some", iris.StatusOK, same_as_request_path},
|
{"GET", "", "/other2almost/some", iris.StatusOK, same_as_request_path},
|
||||||
// it's a request to /other , not other/something, therefore the root wildcard is the handler
|
}},
|
||||||
{"GET", "", "/other", iris.StatusOK, same_as_request_path},
|
{"GET", "/static/{p:path}", h, []testRouteRequest{
|
||||||
|
{"GET", "", "/static", iris.StatusOK, same_as_request_path},
|
||||||
|
{"GET", "", "/static/something/here", iris.StatusOK, same_as_request_path},
|
||||||
}},
|
}},
|
||||||
{"GET", "/", h, []testRouteRequest{
|
{"GET", "/", h, []testRouteRequest{
|
||||||
{"GET", "", "/", iris.StatusOK, same_as_request_path},
|
{"GET", "", "/", iris.StatusOK, same_as_request_path},
|
||||||
}},
|
}},
|
||||||
{"GET", "/other/{paramother:path}", h2, []testRouteRequest{
|
{"GET", "/other/{paramother:path}", h2, []testRouteRequest{
|
||||||
|
{"GET", "", "/other", iris.StatusForbidden, same_as_request_path},
|
||||||
{"GET", "", "/other/wildcard", iris.StatusForbidden, same_as_request_path},
|
{"GET", "", "/other/wildcard", iris.StatusForbidden, same_as_request_path},
|
||||||
{"GET", "", "/other/wildcard/here", iris.StatusForbidden, same_as_request_path},
|
{"GET", "", "/other/wildcard/here", iris.StatusForbidden, same_as_request_path},
|
||||||
}},
|
}},
|
||||||
|
|
Loading…
Reference in New Issue
Block a user