gocraft / web

Go Router + Middleware. Your Contexts.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Method Contexts via route reflect does not support pointers in said Context

bundah opened this issue · comments

Here is a snippet of a continuation of the nested routers and use of pointers with Context example from the docs:
https://gist.github.com/bundah/d29cfc5fed6a6cb8428c

Removing the struct pointer for User and following same pattern in web.New yields less crash but still incorrect behaviour:

adminRouter := rootRouter.Subrouter(AdminContext{CurrentAdmin: User{Name: "Bill"}}, "/admin") // and also change the struct

And finally, if we change these bits to:

type AdminContext struct {
    *Context
    CurrentAdmin User
}

actx := AdminContext{CurrentAdmin: User{Name: "Bill"}}
adminRouter := rootRouter.Subrouter(actx, "/admin")
    adminRouter.Get("/reports", (actx).Reports) //(*AdminContext).Reports)

and curl that one, the name prints... Except that all requests now share actx instance and changing anywere at runtime via middleware etc crosses the request boundary (and can poison other requests).

Please advise...

commented

Please format your code such that it is readable in Github markdown.

commented

Looking at your example, what makes you think the library is at fault? The type of the value passed to "New" and "Subrouter" is what the important part, not the value itself. The zero value of the struct is what is allocated at request time, it is not a copy of the value passed in.

http://godoc.org/github.com/gocraft/web#New

Thanks for the response and fixed the markdowns... the example issue(s) and progression of was actually the reverse in how I began using gocraft. I was doing it very very wrong at first setting/defining the root router and handler contexts with an instantiated context struct which had static configuration data (below is an oversimplified example of how I was incorrectly using it).

type Context struct {
  Config *CFG
  Token *AuthToken
}

ctx := { Config: &CFG{}, Token: nil}

route := web.New(ctx)
route.Get("/", ctx.SlashHandler)

Then when the context was modified in middleware (oauth) the issue(s) became more evident as it was the exact same *context being passed around and there were collisions at runtime when auth tokens were gleaned from headers... This was eventually resolved by not passing struct values into handlers AND following a similar solution as:

#38

...where middleware uses a closure to populate said context struct w/ the static data (Config) and another middleware is used to fill dynamic value (Auth tokens) on the copied context type passed in by gocrafts middlware invoke.

I guess the takeway is I received an ID-10-T error and at a minimum at least these two "issues" (38 and this) may help others to not make the same mistake.