Skip to content

Commit fd5808d

Browse files
authored
Implement flushing copy on proxy response (#416)
1 parent 117c652 commit fd5808d

File tree

1 file changed

+23
-1
lines changed

1 file changed

+23
-1
lines changed

http/proxy_server.go

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,12 +324,34 @@ func (s *ProxyServer) proxyToTarget(w http.ResponseWriter, r *http.Request, pass
324324

325325
// Set response code and copy the body.
326326
w.WriteHeader(resp.StatusCode)
327-
if _, err := io.Copy(w, resp.Body); err != nil {
327+
if err := copyAndFlush(w, resp.Body); err != nil {
328328
log.Printf("http: proxy response error: %s", err)
329329
return
330330
}
331331
}
332332

333+
// copyAndFlush implements a basic io.Copy() but calls dst.Flush() after every write.
334+
// dst must implement http.Flusher or else it will panic.
335+
func copyAndFlush(dst io.Writer, src io.Reader) error {
336+
buf := make([]byte, 32*1024)
337+
338+
for {
339+
n, err := src.Read(buf)
340+
if n > 0 {
341+
if _, e := dst.Write(buf[:n]); e != nil {
342+
return err
343+
}
344+
dst.(http.Flusher).Flush()
345+
}
346+
347+
if err == io.EOF {
348+
return nil
349+
} else if err != nil {
350+
return err
351+
}
352+
}
353+
}
354+
333355
func (s *ProxyServer) isWriteRequest(r *http.Request) bool {
334356
return r.Method != http.MethodGet && r.Method != http.MethodHead
335357
}

0 commit comments

Comments
 (0)