Right now WithContext deep-copies URL only. At minimum, it should also deep-copy Headers for the same reason. For some reason the code distinguishes URL because it is "not a map", but maps are also pointer types.
Related to #20068, which added URL deep-copying.
Probably, but this is also getting a little sad in terms of copies/allocs.
It might be time for a new NewRequest constructor variant (NewRequestContext?) that takes a context. Currently all code that wants to make a request with contexts has to make their Request, and then copy/alloc everything again, just to set the context.
Unfortunately the name NewRequestContext isn't exactly beautiful.
Alternatively we could export the context. There's nothing special about it compared to the other mutable parts IMO.
Then add Request.Clone() and have proper separation of concerns.
Alternatively we could export the context. There's nothing special about it compared to the other mutable parts IMO.
It was an explicit decision to make it unexported, so people don't shoot themselves in the foot. Russ described the problem in the original bug(s).
I'm probably alone here: I am strongly opposed to turning WithContext into Clone. The vast majority of the time that I call WithContext, I don't need a deepy copy. If a deep copies are frequently needed, let's just add Request.Clone.
I also think https://golang.org/cl/41308 was a mistake. The CL description says "server.ServeHTTP mutates the request's URL", but net/http's server does not mutate Request.URL AFAIK. The original bug (#20068) is about net/http/httputil/reverseproxy and I think the change should have been restricted to that package.
ping @bradfitz @tombergan for decision
Punting to Go 1.12. But I think we do probably want to add a Clone and a new Context-accepting NewRequest. And maybe revert CL 41308.
But maybe this is all moot if we end up making a new http client interface. (#23707).
I am checking in here to remind myself to be involved with the decision to rollback CL 41308 which I authored but also to be involved in this conversation, for Go1.12
Punting to Go 1.13.
Change https://golang.org/cl/174324 mentions this issue: net/http: add func NewRequestWithContext
@bradfitz I just came across Clone as a first time user of contexts within net/http. I had a question about this bit of documentation on WithContext:
...To change the context of a request (such as an incoming) you then also want to modify to send back out, use Request.Clone. Between those two uses, it's rare to need WithContext.
I wanted to ask if Clone should be preferred over WithContext in all situations. Specifically I'm writing a server middleware and only need to annotate a request (adding a logged in user) so it can be used by other handlers.
Is WithContext not appropriate for this situation?
WithContext works there.
Most helpful comment
WithContext works there.