I need some help,
The following example code:
app.WrapRouter(func(w http.ResponseWriter, r *http.Request, router http.HandlerFunc) {
path := r.URL.Path
pathSlice := strings.Split(path, "/")
needRemovePart := pathSlice[len(pathSlice)-1]
newPath := strings.Join(pathSlice[:len(pathSlice)-1], "/")
r.URL.Path = newPath
ctx := app.ContextPool.Acquire(w, r)
ctx.Values().Set("removePath", needRemovePart)
router(w, r)
return
})
I want to truncate the last part needRemovePart in url path, then store into context ctx.Values().Set("removePath", needRemovePart) for future middleware use. The new url path newPath continue to match the route.
But the result is not what I expected,
ctx := app.ContextPool.Acquire(w, r) include BeginRequest will return a new Context,
https://github.com/kataras/iris/blob/d6cbfc4cc63482ea7356c2db41b6c507c6761cfb/context/pool.go#L33-L39
The controller whole flow also include BeginRequest and use a new Context, How to use same one?
Hello @Ostaer and sorry for the delay. You have two ways to do it:
1. The router has the ServeHTTPC method to handle requests based on an already-created Context.
Example:
app.WrapRouter(func(w http.ResponseWriter, r *http.Request, router http.HandlerFunc) {
path := r.URL.Path
pathSlice := strings.Split(path, "/")
needRemovePart := pathSlice[len(pathSlice)-1]
newPath := strings.Join(pathSlice[:len(pathSlice)-1], "/")
r.URL.Path = newPath
// BEGIN
ctx := app.ContextPool.Acquire(w, r)
ctx.Values().Set(removedPathCtxKey, needRemovePart)
app.ServeHTTPC(ctx) // <---
app.ContextPool.Release(ctx) // <---
// END
})
app.Get("/remove", func(ctx iris.Context) {
removedPathPart := ctx.Values().Get(removedPathCtxKey)
ctx.Writef("As Path: %s (registered route path: %s)\nRemoved Path Part was: /%s\n", ctx.Path(), ctx.GetCurrentRoute().Path(), removedPathPart)
})
2. You can always use the std net/http request's values (when you rely on third-parties that must run before router) to store such data and retrieve it with a middleware which will store the data(in your case the, "removedPath") to ctx.Values() if you want so. Example:
package main
import (
"context"
"net/http"
"strings"
"github.com/kataras/iris/v12"
)
func main() {
app := iris.New()
// BEGIN
const removedPathCtxKey = "removedPath"
app.WrapRouter(func(w http.ResponseWriter, r *http.Request, router http.HandlerFunc) {
path := r.URL.Path
pathSlice := strings.Split(path, "/")
needRemovePart := pathSlice[len(pathSlice)-1]
newPath := strings.Join(pathSlice[:len(pathSlice)-1], "/")
r.URL.Path = newPath
router(w, r.WithContext(context.WithValue(context.TODO(), removedPathCtxKey, needRemovePart)))
})
// Use `app.UseGlobal` or `app.Use`, we use `app.UseGlobal` here
// to ensure that this middleware is always in front of
// any other middleware (but after the router itself) e no matter what .
app.UseGlobal(func(ctx iris.Context) {
ctx.Values().Set(removedPathCtxKey, ctx.Request().Context().Value(removedPathCtxKey))
ctx.Next()
})
// END
app.Get("/remove", func(ctx iris.Context) {
removedPathPart := ctx.Values().Get(removedPathCtxKey)
ctx.Writef("As Path: %s (registered route path: %s)\nRemoved Path Part was: /%s\n",
ctx.Path(), ctx.GetCurrentRoute().Path(), removedPathPart)
})
// GET: http://localhost:8080/remove/lastpart
app.Run(iris.Addr(":8080"))
}
Output:

The 2. solution has a performance cost because it clones the request on request.WithContext as we already know from Go Authors and net/http developer(s).
Thanks,
Gerasimos Maropoulos
The ServeHTTPC method is suitable for me, Thanks.
Most helpful comment
Hello @Ostaer and sorry for the delay. You have two ways to do it:
1. The router has the
ServeHTTPCmethod to handle requests based on an already-createdContext.https://github.com/kataras/iris/blob/46b761ba4661ff771e5de9819d852dc933f74eb1/core/router/router.go#L156-L159
Example:
2. You can always use the std net/http request's values (when you rely on third-parties that must run before router) to store such data and retrieve it with a middleware which will store the data(in your case the,
"removedPath") toctx.Values()if you want so. Example:Output:
The 2. solution has a performance cost because it clones the request on
request.WithContextas we already know from Go Authors and net/http developer(s).Thanks,
Gerasimos Maropoulos