diff options
author | WeidiDeng <[email protected]> | 2024-04-26 23:09:18 +0800 |
---|---|---|
committer | GitHub <[email protected]> | 2024-04-26 09:09:18 -0600 |
commit | 1b9042bcdd03b4edea8447355f970e1c5aff8c10 (patch) | |
tree | 9d45812da2d43d16759c5cf7f3cfbf065f3dfa3b | |
parent | 4d6370bf92de163a53aec9081c5d5ae6614597a0 (diff) | |
download | caddy-1b9042bcdd03b4edea8447355f970e1c5aff8c10.tar.gz caddy-1b9042bcdd03b4edea8447355f970e1c5aff8c10.zip |
reverseproxy: handle buffered data during hijack (#6274)
-rw-r--r-- | modules/caddyhttp/responsewriter.go | 2 | ||||
-rw-r--r-- | modules/caddyhttp/reverseproxy/streaming.go | 11 |
2 files changed, 13 insertions, 0 deletions
diff --git a/modules/caddyhttp/responsewriter.go b/modules/caddyhttp/responsewriter.go index 12627d45c..d51d37cb2 100644 --- a/modules/caddyhttp/responsewriter.go +++ b/modules/caddyhttp/responsewriter.go @@ -263,6 +263,8 @@ func (rr *responseRecorder) Hijack() (net.Conn, *bufio.ReadWriter, error) { conn.(*hijackedConn).updateReadSize(buffered) data, _ := brw.Peek(buffered) brw.Reader.Reset(io.MultiReader(bytes.NewReader(data), conn)) + // peek to make buffered data appear, as Reset will make it 0 + _, _ = brw.Peek(buffered) } else { brw.Reader.Reset(conn) } diff --git a/modules/caddyhttp/reverseproxy/streaming.go b/modules/caddyhttp/reverseproxy/streaming.go index 6d8990575..a696ac7fb 100644 --- a/modules/caddyhttp/reverseproxy/streaming.go +++ b/modules/caddyhttp/reverseproxy/streaming.go @@ -101,6 +101,17 @@ func (h *Handler) handleUpgradeResponse(logger *zap.Logger, wg *sync.WaitGroup, return } + // There may be buffered data in the *bufio.Reader + // see: https://github.com/caddyserver/caddy/issues/6273 + if buffered := brw.Reader.Buffered(); buffered > 0 { + data, _ := brw.Peek(buffered) + _, err := backConn.Write(data) + if err != nil { + logger.Debug("backConn write failed", zap.Error(err)) + return + } + } + // Ensure the hijacked client connection, and the new connection established // with the backend, are both closed in the event of a server shutdown. This // is done by registering them. We also try to gracefully close connections |