Skip to content

Commit 590b137

Browse files
committed
protocol: test read/write post buffer gc
1 parent 74fa662 commit 590b137

1 file changed

Lines changed: 85 additions & 0 deletions

File tree

protocol_test.go

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2458,6 +2458,91 @@ func TestConnReadHandlesChunkedPayload(t *testing.T) {
24582458
}
24592459
}
24602460

2461+
func TestReadUsesConnWhenBufReaderNil(t *testing.T) {
2462+
serverConn, clientConn := net.Pipe()
2463+
t.Cleanup(func() {
2464+
if closeErr := serverConn.Close(); closeErr != nil {
2465+
t.Errorf("failed to close server connection: %v", closeErr)
2466+
}
2467+
})
2468+
t.Cleanup(func() {
2469+
if closeErr := clientConn.Close(); closeErr != nil {
2470+
t.Errorf("failed to close client connection: %v", closeErr)
2471+
}
2472+
})
2473+
2474+
proxyConn := NewConn(serverConn)
2475+
sendSecond := make(chan struct{})
2476+
2477+
go func() {
2478+
_, _ = clientConn.Write([]byte("a"))
2479+
<-sendSecond
2480+
_, _ = clientConn.Write([]byte("b"))
2481+
_ = clientConn.Close()
2482+
}()
2483+
2484+
buf := make([]byte, 1)
2485+
// First read processes header detection and drains the buffer.
2486+
if _, err := proxyConn.Read(buf); err != nil {
2487+
t.Fatalf("first read failed: %v", err)
2488+
}
2489+
if proxyConn.bufReader != nil {
2490+
t.Fatalf("expected bufReader to be nil after draining buffer")
2491+
}
2492+
2493+
// With bufReader cleared, Read should use the underlying conn.
2494+
close(sendSecond)
2495+
if _, err := proxyConn.Read(buf); err != nil {
2496+
t.Fatalf("second read failed: %v", err)
2497+
}
2498+
if string(buf) != "b" {
2499+
t.Fatalf("unexpected second read payload: %q", string(buf))
2500+
}
2501+
}
2502+
2503+
func TestWriteToUsesConnWhenBufReaderNil(t *testing.T) {
2504+
serverConn, clientConn := net.Pipe()
2505+
t.Cleanup(func() {
2506+
if closeErr := serverConn.Close(); closeErr != nil {
2507+
t.Errorf("failed to close server connection: %v", closeErr)
2508+
}
2509+
})
2510+
t.Cleanup(func() {
2511+
if closeErr := clientConn.Close(); closeErr != nil {
2512+
t.Errorf("failed to close client connection: %v", closeErr)
2513+
}
2514+
})
2515+
2516+
proxyConn := NewConn(serverConn)
2517+
sendPayload := make(chan struct{})
2518+
2519+
go func() {
2520+
_, _ = clientConn.Write([]byte("x"))
2521+
<-sendPayload
2522+
_, _ = clientConn.Write([]byte("payload"))
2523+
_ = clientConn.Close()
2524+
}()
2525+
2526+
// Process header detection and drain the buffer.
2527+
buf := make([]byte, 1)
2528+
if _, err := proxyConn.Read(buf); err != nil {
2529+
t.Fatalf("initial read failed: %v", err)
2530+
}
2531+
if proxyConn.bufReader != nil {
2532+
t.Fatalf("expected bufReader to be nil after draining buffer")
2533+
}
2534+
2535+
// With bufReader cleared, WriteTo should copy directly from conn.
2536+
close(sendPayload)
2537+
var out bytes.Buffer
2538+
if _, err := proxyConn.WriteTo(&out); err != nil {
2539+
t.Fatalf("WriteTo failed: %v", err)
2540+
}
2541+
if out.String() != "payload" {
2542+
t.Fatalf("unexpected WriteTo output: %q", out.String())
2543+
}
2544+
}
2545+
24612546
func benchmarkTCPProxy(size int, b *testing.B) {
24622547
// create and start the echo backend
24632548
backend, err := net.Listen("tcp", testLocalhostRandomPort)

0 commit comments

Comments
 (0)