-
Notifications
You must be signed in to change notification settings - Fork 127
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
support for H2 Push #36
Conversation
add support for H2 Push without removing support for previous Go versions.
Hi there, @romainmenke. Thanks for getting things started on the H2 Push! This looks pretty clean, but I'm not sure we need the entire docs from the Also, please create a test for these changes. |
shorten Push description
Hi, I'm not sure this would works as expected. Am'I right? |
@alexandrestein that is not how H2 Push works in Go.
This is not immediately clear at first as it all happens "auto-magically". A good way to verify this behaviour is to setup a test server with a hardcoded Push. Set a custom header value in pusher.Push("/relative-path/some-resource", &http.PushOptions{
Header: http.Header{
"Go-H2-Push": "X",
},
}) Verify that the header value appears. func someHandler(w http.ResponseWriter, r *http.Request) {
if r.Header.Get("Go-H2-Push") == "X" {
fmt.Println("this did not come from the client")
}
} @jprobinson Haven't had time yet to write a descent test for this, but I have already shortened the docs. |
I made a test server to check this. I didn't try to call the server from go because I believe the target is more probably the web browsers over direct language requests. I don't really see the point of doing this except for web pages. The result is that Push are working, but not gziped.
The source of the server can be find here and the working server is here. |
@alexandrestein You haven't passed any headers from the original request to the If you add these
|
Your are right. But I would personally expect the package to do that. Is it an option to make the GzipResponseWriter.Push look like this: func (w *GzipResponseWriter) Push(target string, opts *http.PushOptions) error {
// Try to get the pusher interface.
pusher, ok := w.ResponseWriter.(http.Pusher)
if ok && pusher != nil {
if opts == nil {
opts = &http.PushOptions{Header: getHeader()}
} else {
if opts.Header != nil {
opts.Header = getHeader()
} else {
opts.Header.Set(acceptEncoding, "gzip")
}
}
return pusher.Push(target, opts)
}
return http.ErrNotSupported
}
func getHeader() http.Header {
return http.Header{
acceptEncoding: []string{"gzip"},
}
} That way, it's transparent for caller. Thanks for your tips. |
I agree that such behaviour would be helpful to many people implementing H2 Push. func (w *GzipResponseWriter) Push(target string, opts *http.PushOptions) error {
// Try to get the pusher interface.
pusher, ok := w.ResponseWriter.(http.Pusher)
if !ok || pusher == nil {
return http.ErrNotSupported
}
if opts == nil {
opts = &http.PushOptions{
Header: http.Header{
acceptEncoding: []string{"gzip"},
},
}
return pusher.Push(target, opts)
}
if opts.Header == nil {
opts.Header = http.Header{
acceptEncoding: []string{"gzip"},
}
return pusher.Push(target, opts)
}
return pusher.Push(target, opts)
} If the Or maybe restrict it to not overriding the Accept-Encoding header? |
This is even better. if encoding := opts.Header.Get(acceptEncoding); encoding == "" {
opts.Header.Add(acceptEncoding, "gzip")
return pusher.Push(target, opts)
} That way caller can add headers without "accidentally" disable compression. |
@alexandrestein I moved the logic for adding the Accept-Encoding header to a separate func to facilitate tests. This also made it possible to rewrite @jprobinson I looked into writing a test for the It is possible to create a test that checks if the server receives the |
@romainmenke this looks really good to me; but I'm not the one to convince. 😄 I'm thinking about a edge case. But maybe save the "Accept-Encoding" value of the initial caller into the GzipResponseWriter struct can prevent the possible issue of sending GZIP content to a client which not support it. A more programatic and less hardcodeed solution would maybe looks like this: func (w *GzipResponseWriter) setAcceptEncodingForPushOptions(opts *http.PushOptions) *http.PushOptions {
if opts == nil {
opts = &http.PushOptions{
Header: http.Header{
acceptEncoding: w.clientAcceptEncoding,
},
}
return opts
}
if opts.Header == nil {
opts.Header = http.Header{
acceptEncoding: w.clientAcceptEncoding,
}
return opts
}
if encoding := opts.Header.Get(acceptEncoding); encoding == "" {
opts.Header[acceptEncoding] = w.clientAcceptEncoding
return opts
}
return opts
} Is it a good idea? |
@alexandrestein I believe it is impossible for a client that doesn't support GZIP to end up in this flow. So we can safely assume that the client will always support GZIP. We however cannot assume anything about other middleware, which is why I would not override headers, but adding them seems perfectly safe to me. |
OK, it looks like you are right. |
Sorry for the delay, gang. This LGTM. Pulling in. |
add support for H2 Push without removing support for previous Go versions.
#28