diff options
author | Kevin Lin <masknu@users.noreply.github.com> | 2020-07-21 02:14:46 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-07-20 12:14:46 -0600 |
commit | e9b1d7dcb4cbf85da7fb4cf8c411a4f840a98cf1 (patch) | |
tree | c21f3f66b5e1c2a8cf60172f07004a4ee6c261b5 /modules/caddyhttp | |
parent | bd9d796e6ed64c713002e3503a8b0012bd4f1460 (diff) |
reverse_proxy: flush HTTP/2 response when ContentLength is unknown (#3561)
* reverse proxy: Support more h2 stream scenarios (#3556)
* reverse proxy: add integration test for better h2 stream (#3556)
* reverse proxy: adjust comments as francislavoie suggests
* link to issue #3556 in the comments
Diffstat (limited to 'modules/caddyhttp')
-rw-r--r-- | modules/caddyhttp/reverseproxy/reverseproxy.go | 8 | ||||
-rw-r--r-- | modules/caddyhttp/reverseproxy/streaming.go | 5 |
2 files changed, 13 insertions, 0 deletions
diff --git a/modules/caddyhttp/reverseproxy/reverseproxy.go b/modules/caddyhttp/reverseproxy/reverseproxy.go index bb1453a..0a53db4 100644 --- a/modules/caddyhttp/reverseproxy/reverseproxy.go +++ b/modules/caddyhttp/reverseproxy/reverseproxy.go @@ -611,6 +611,14 @@ func (h *Handler) reverseProxy(rw http.ResponseWriter, req *http.Request, di Dia rw.WriteHeader(res.StatusCode) + // some apps need the response headers before starting to stream content with http2, + // so it's important to explicitly flush the headers to the client before streaming the data. + // (see https://github.com/caddyserver/caddy/issues/3556 for use case) + if req.ProtoMajor == 2 && res.ContentLength == -1 { + if wf, ok := rw.(http.Flusher); ok { + wf.Flush() + } + } err = h.copyResponse(rw, res.Body, h.flushInterval(req, res)) res.Body.Close() // close now, instead of defer, to populate res.Trailer if err != nil { diff --git a/modules/caddyhttp/reverseproxy/streaming.go b/modules/caddyhttp/reverseproxy/streaming.go index 8a7c6f7..105ff32 100644 --- a/modules/caddyhttp/reverseproxy/streaming.go +++ b/modules/caddyhttp/reverseproxy/streaming.go @@ -96,6 +96,11 @@ func (h Handler) flushInterval(req *http.Request, res *http.Response) time.Durat return -1 // negative means immediately } + // for h2 and h2c upstream streaming data to client (issue #3556) + if req.ProtoMajor == 2 && res.ContentLength == -1 { + return -1 + } + // TODO: more specific cases? e.g. res.ContentLength == -1? (this TODO is from the std lib) return time.Duration(h.FlushInterval) } |