Skip to content

Commit

Permalink
Implement flushing copy on proxy response (#416)
Browse files Browse the repository at this point in the history
  • Loading branch information
benbjohnson authored Oct 26, 2023
1 parent 117c652 commit fd5808d
Showing 1 changed file with 23 additions and 1 deletion.
24 changes: 23 additions & 1 deletion http/proxy_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -324,12 +324,34 @@ func (s *ProxyServer) proxyToTarget(w http.ResponseWriter, r *http.Request, pass

// Set response code and copy the body.
w.WriteHeader(resp.StatusCode)
if _, err := io.Copy(w, resp.Body); err != nil {
if err := copyAndFlush(w, resp.Body); err != nil {
log.Printf("http: proxy response error: %s", err)
return
}
}

// copyAndFlush implements a basic io.Copy() but calls dst.Flush() after every write.
// dst must implement http.Flusher or else it will panic.
func copyAndFlush(dst io.Writer, src io.Reader) error {
buf := make([]byte, 32*1024)

for {
n, err := src.Read(buf)
if n > 0 {
if _, e := dst.Write(buf[:n]); e != nil {
return err
}
dst.(http.Flusher).Flush()
}

if err == io.EOF {
return nil
} else if err != nil {
return err
}
}
}

func (s *ProxyServer) isWriteRequest(r *http.Request) bool {
return r.Method != http.MethodGet && r.Method != http.MethodHead
}
Expand Down

0 comments on commit fd5808d

Please sign in to comment.