Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.Sign up
proposal: net/http: add ResponseWriterAs function #39558
Wrapping an http.ResponseWriter is difficult because handlers are supposed to test for capabilities by testing for the presence of an optional interface. This means a wrapper type cannot just have a Push method that delegates to the ResponseWriter it wraps. This does not work because the presence of the method is the only mechanism for detecting support for http.Pusher. Instead there need to be 2^N types that a wrapper function chooses from depending on which optional interfaces (Pusher, Hijacker, Flusher) its wrapped type supports. This becomes impractical very quickly.
I propose that the http package gains a function that works like errors.As.
It could also, like errors.As, test for
We've basically stopped adding these other methods precisely for the reason you identify.
Errors have the nice property that the API is very simple and wrappers really change very little.
Suppose you had an http.ResponseWriter wrapper that did gzipping of data passed to Write.
It's also unclear that adding As at this point would help much, since we can't rewrite all the code in the wild that doesn't use it, nor can we rewrite all the code in the wild that doesn't implement Unwrap, and now we'd have two ways to do it (only one of which is guaranteed to work - the old way).
We are aware of the problem, though, and if/when we get to designing a second version of the http server API we should definitely think hard about how to repeat this mistake.
But I don't see how this specific proposal improves the situation given the large amount of existing code.
I don't think that the .As approach would work with io.Reader/Writer though, for the reason you outlined. The optional interfaces there end up changing the semantics in ways that don't lend themselves to wrapping. I still think it might work for some of the ResponseWriter cases though.
I know Brad Fitz started looking at making a v2 of the http client. I hadn't heard anything about a v2 for http server.
I guess the question is what strategy makes more sense: a hard v2 with no backwards compatibility or a continuing evolution of what exists. I think this could be made entirely backwards compatible or at least mostly compatible with only some optional interfaces accidentally by passed.
For ResponseWriter, it might make more sense to have