diff --git a/_examples/file-server/basic/assets/index.html b/_examples/file-server/basic/assets/index.html
new file mode 100644
index 00000000..06651a45
--- /dev/null
+++ b/_examples/file-server/basic/assets/index.html
@@ -0,0 +1 @@
+
Hello index
\ No newline at end of file
diff --git a/_examples/routing/custom-context/method-overriding/main.go b/_examples/routing/custom-context/method-overriding/main.go
index bfed8efb..8747be93 100644
--- a/_examples/routing/custom-context/method-overriding/main.go
+++ b/_examples/routing/custom-context/method-overriding/main.go
@@ -20,8 +20,16 @@ type MyContext struct {
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 with an embedded context.Context inside it.
+// The only one important if you will override the Context
+// 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() {
context.Next(ctx)
}
@@ -40,11 +48,9 @@ func main() {
app := iris.New()
// 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:
- // 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 {
return &MyContext{
// 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
app.Handle("GET", "/", recordWhichContextJustForProofOfConcept, func(ctx context.Context) {
// use the context's overridden HTML method.
diff --git a/_examples/routing/dynamic-path/root-wildcard/main.go b/_examples/routing/dynamic-path/root-wildcard/main.go
index 13eacb32..1be0d1ca 100644
--- a/_examples/routing/dynamic-path/root-wildcard/main.go
+++ b/_examples/routing/dynamic-path/root-wildcard/main.go
@@ -14,12 +14,13 @@ func main() {
// / -> because of app.Get("/", ...)
// /other/anything/here -> because of app.Get("/other/{paramother: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!
//
// i.e /something/here/that/cannot/be/found/by/other/registered/routes/order/not/matters
app.Get("/{p:path}", h)
+ // app.Get("/static/{p:path}", staticWildcardH)
// this will handle only GET /
app.Get("/", staticPath)
@@ -36,7 +37,7 @@ func main() {
app.Get("/other2/{paramothersecond:path}", other2)
// 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))
}
@@ -46,6 +47,11 @@ func h(ctx context.Context) {
ctx.WriteString(param)
}
+func staticWildcardH(ctx context.Context) {
+ param := ctx.Params().Get("p")
+ ctx.WriteString("from staticWildcardH: param=" + param)
+}
+
func other(ctx context.Context) {
param := ctx.Params().Get("paramother")
ctx.Writef("from other: %s", param)
@@ -57,5 +63,9 @@ func other2(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())
}
diff --git a/context/context.go b/context/context.go
index 5793c87c..2aff0e6b 100644
--- a/context/context.go
+++ b/context/context.go
@@ -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
// for all next handlers in the chain.
var LimitRequestBodySize = func(maxRequestBodySizeBytes int64) Handler {
diff --git a/context/pool.go b/context/pool.go
index a48d1026..30ab5523 100644
--- a/context/pool.go
+++ b/context/pool.go
@@ -21,6 +21,11 @@ func New(newFunc func() Context) *Pool {
}
// 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) {
c.newFunc = newFunc
}
diff --git a/core/router/api_builder.go b/core/router/api_builder.go
index dfa608e6..9f7e597f 100644
--- a/core/router/api_builder.go
+++ b/core/router/api_builder.go
@@ -658,6 +658,7 @@ func (rb *APIBuilder) StaticWeb(requestPath string, systemPath string) *Route {
}
requestPath = joinPath(fullpath, WildcardParam(paramName))
+ // requestPath = fullpath + "/{file:path}"
return rb.registerResourceRoute(requestPath, handler)
}
diff --git a/core/router/node/node.go b/core/router/node/node.go
index 5c04c2a6..3cce094f 100644
--- a/core/router/node/node.go
+++ b/core/router/node/node.go
@@ -25,6 +25,8 @@ type node struct {
// 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")
+/// TODO: clean up needed until v8.5
+
// Add adds a node to the tree, returns an ErrDublicate error on failure.
func (nodes *Nodes) Add(path string, handlers context.Handlers) error {
// println("[Add] adding path: " + path)
@@ -99,26 +101,29 @@ func (nodes *Nodes) add(path string, paramNames []string, handlers context.Handl
// set the wildcard param name to the root and its children.
wildcardIdx := strings.IndexByte(path, '*')
wildcardParamName := ""
- if wildcardIdx > 0 {
+ if wildcardIdx > 0 && len(paramNames) == 0 {
wildcardParamName = path[wildcardIdx+1:]
-
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 path == "/" {
+ rootWildcard := path == "/"
+ if rootWildcard {
path += "/" // if root wildcard, then do it like "//" instead of simple "/"
- n := &node{
- rootWildcard: true,
- s: path,
- wildcardParamName: wildcardParamName,
- paramNames: paramNames,
- handlers: handlers,
- root: root,
- }
- *nodes = append(*nodes, n)
- // println("1. nodes.Add path: " + path)
- return
}
+ n := &node{
+ rootWildcard: rootWildcard,
+ s: path,
+ wildcardParamName: wildcardParamName,
+ paramNames: paramNames,
+ handlers: handlers,
+ root: root,
+ }
+ *nodes = append(*nodes, n)
+ // println("1. nodes.Add path: " + path)
+ return
+
}
loop:
@@ -127,6 +132,10 @@ loop:
continue
}
+ if len(n.paramNames) == 0 && n.wildcardParamName != "" {
+ continue
+ }
+
minlen := len(n.s)
if len(path) < minlen {
minlen = len(path)
@@ -226,8 +235,9 @@ loop:
handlers: handlers,
root: root,
}
- // println("5. nodes.Add path: " + n.s)
*nodes = append(*nodes, n)
+
+ // println("5. node add on path: " + path + " n.s: " + n.s + " wildcard param: " + n.wildcardParamName)
return
}
@@ -276,7 +286,7 @@ func (nodes Nodes) Exists(path string) bool {
}
func (nodes Nodes) findChild(path string, params []string) (*node, []string) {
- // println("request path: " + path)
+
for _, n := range nodes {
if n.s == ":" {
paramEnd := strings.IndexByte(path, '/')
@@ -309,8 +319,39 @@ func (nodes Nodes) findChild(path string, params []string) (*node, []string) {
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) {
// 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
}
@@ -322,6 +363,7 @@ func (nodes Nodes) findChild(path string, params []string) (*node, []string) {
}
child, childParamNames := n.childrenNodes.findChild(path[len(n.s):], params)
+
// print("childParamNames len: ")
// println(len(childParamNames))
diff --git a/core/router/router_wildcard_root_test.go b/core/router/router_wildcard_root_test.go
index 9ec72a17..2ca30652 100644
--- a/core/router/router_wildcard_root_test.go
+++ b/core/router/router_wildcard_root_test.go
@@ -117,13 +117,16 @@ func TestRouterWildcardRootManyAndRootStatic(t *testing.T) {
// this feature is very important and can remove noumerous of previous hacks on our apps.
{"GET", "/{p:path}", h, []testRouteRequest{
{"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", "", "/", iris.StatusOK, same_as_request_path},
}},
{"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/here", iris.StatusForbidden, same_as_request_path},
}},