New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
proposal: net/http: add ResponseWriterAs function #39558
Comments
CC @bradfitz |
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 |
But as I noted in my comment above, adding ResponseWriterAs isn't backwards compatible. Code would still have to deal with all the special case methods that exist today - they're not going away and can't be shoehorned into a different API. Maybe when it's time to add the next such method on ResponseWriter we should talk more about this proposal, but right now it doesn't seem like it simplifies anything. |
It wasn't clear to me before why Basically, there are two ways to do I think two is not the worst failure case, but I concede that it's not really backwards compatible. Closing the issue. In the event that someone proposes a new optional interface for ResponseWriter, I think something like ResponseWriterAs should be created for that new optional interface, but I don't think that's on the horizon at the moment. |
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.
http.ResponseWriterAs(w http.ResponseWriter, target interface{}) bool
will first test ifw
can be converted to the target type, and if not, check whether w has anUnwrap() http.ResponseWriter
method then test whether any ResponseWriter in the chain can be converted.It could also, like errors.As, test for
As(target interface{}) bool
methods in the chain, although I suspect this would be less useful than in the errors case.The text was updated successfully, but these errors were encountered: