Skip to content

Commit 1b1d58a

Browse files
committed
fix: Read() data truncation issue
remove the multireader abstraction and modify conn.Read() so that we start by draining buffered data (from the header parsing), then reading directly from the underlying connection in a single Read() call fixes data loss in TLS passthrough scenarios (e.g. ingress-nginx) when PROXY header + TLS ClientHello exceeds the 256-byte buffer.
1 parent 452c70b commit 1b1d58a

1 file changed

Lines changed: 12 additions & 3 deletions

File tree

protocol.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ type Conn struct {
5252
readErr error
5353
conn net.Conn
5454
bufReader *bufio.Reader
55-
reader io.Reader
5655
header *Header
5756
ProxyHeaderPolicy Policy
5857
Validate Validator
@@ -161,7 +160,6 @@ func NewConn(conn net.Conn, opts ...func(*Conn)) *Conn {
161160

162161
pConn := &Conn{
163162
bufReader: br,
164-
reader: io.MultiReader(br, conn),
165163
conn: conn,
166164
}
167165

@@ -183,7 +181,18 @@ func (p *Conn) Read(b []byte) (int, error) {
183181
return 0, p.readErr
184182
}
185183

186-
return p.reader.Read(b)
184+
// First drain any buffered data from header parsing,
185+
// then read directly from the underlying connection.
186+
n := 0
187+
if p.bufReader.Buffered() > 0 {
188+
n, _ = p.bufReader.Read(b)
189+
}
190+
191+
if n < len(b) {
192+
nn, err := p.conn.Read(b[n:])
193+
return n + nn, err
194+
}
195+
return n, nil
187196
}
188197

189198
// Write wraps original conn.Write.

0 commit comments

Comments
 (0)