Reputation: 9429
I want to set a context value inside an http.HandleFunc. The following approach seems to work.
I'm a little worried about *r = *r.WithContext(ctx)
though.
type contextKey string
var myContext = contextKey("myContext")
func setValue(r *http.Request, val string) {
ctx := context.WithValue(r.Context(), myContext, val)
*r = *r.WithContext(ctx)
}
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
setValue(r, "foobar")
})
What's the best approach to set a context variable inside an http.HandleFunc?
Upvotes: 1
Views: 6268
Reputation: 120941
The code in the question overwrites the request object. This can result in code up the stack using the wrong context value. Request.WithContext
creates a shallow copy of the request to avoid this. Return a pointer to that shallow copy.
func setValue(r *http.Request, val string) *http.Request {
return r.WithContext(context.WithValue(r.Context(), myContext, val))
}
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
r = setValue(r, "foobar")
})
If then handler invokes some other handler, then pass the new request along to the new handler:
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
r = setValue(r, "foobar")
someOtherHandler.ServeHTTP(w, r)
})
Upvotes: 6