From 9c191f5301ae7cd7708c42cd602daa0624125989 Mon Sep 17 00:00:00 2001 From: WeidiDeng Date: Wed, 17 Jan 2024 16:44:03 +0800 Subject: [PATCH] migrate from http.Flusher to http.NewResponseController --- forwardproxy.go | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/forwardproxy.go b/forwardproxy.go index 218f205..15d8069 100644 --- a/forwardproxy.go +++ b/forwardproxy.go @@ -299,13 +299,12 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyht fallthrough case 3: defer r.Body.Close() - wFlusher, ok := w.(http.Flusher) - if !ok { - return caddyhttp.Error(http.StatusInternalServerError, - fmt.Errorf("ResponseWriter doesn't implement http.Flusher")) - } w.WriteHeader(http.StatusOK) - wFlusher.Flush() + err := http.NewResponseController(w).Flush() + if err != nil { + return caddyhttp.Error(http.StatusInternalServerError, + fmt.Errorf("ResponseWriter flush error: %v", err)) + } return dualStream(targetConn, r.Body, w) } @@ -652,15 +651,15 @@ type closeWriter interface { // If dst does not implement http.Flusher(e.g. net.TCPConn), it will do a simple io.CopyBuffer(). // Reasoning: http2ResponseWriter will not flush on its own, so we have to do it manually. func flushingIoCopy(dst io.Writer, src io.Reader, buf []byte) (written int64, err error) { - flusher, ok := dst.(http.Flusher) + rw, ok := dst.(http.ResponseWriter) if !ok { return io.CopyBuffer(dst, src, buf) } + rc := http.NewResponseController(rw) for { nr, er := src.Read(buf) if nr > 0 { nw, ew := dst.Write(buf[0:nr]) - flusher.Flush() if nw > 0 { written += int64(nw) } @@ -668,6 +667,11 @@ func flushingIoCopy(dst io.Writer, src io.Reader, buf []byte) (written int64, er err = ew break } + ef := rc.Flush() + if ef != nil { + err = ef + break + } if nr != nw { err = io.ErrShortWrite break