Skip to content

Commit 9cdda4d

Browse files
committed
commit to a buffered reader for the proxy connection so we avoid nasty edge cases of silently dropped/ignored pieces of the response from the proxy
1 parent 53a93f7 commit 9cdda4d

1 file changed

Lines changed: 18 additions & 5 deletions

File tree

internal/api/proxy.go

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,15 @@ import (
1111
"net/url"
1212
)
1313

14+
type connWithBufferedReader struct {
15+
net.Conn
16+
r *bufio.Reader
17+
}
18+
19+
func (c *connWithBufferedReader) Read(p []byte) (int, error) {
20+
return c.r.Read(p)
21+
}
22+
1423
// withProxyTransport modifies the given transport to handle proxying of unix, socks5 and http connections.
1524
//
1625
// Note: baseTransport is considered to be a clone created with transport.Clone()
@@ -82,18 +91,22 @@ func withProxyTransport(baseTransport *http.Transport, proxyURL *url.URL, proxyP
8291
return nil, err
8392
}
8493

85-
// Read and check the response from the proxy
86-
resp, err := http.ReadResponse(bufio.NewReader(conn), nil)
94+
br := bufio.NewReader(conn)
95+
resp, err := http.ReadResponse(br, nil)
8796
if err != nil {
8897
conn.Close()
8998
return nil, err
9099
}
91100
if resp.StatusCode != http.StatusOK {
101+
// For non-200, it's safe/appropriate to close the body (it’s a real response body here).
102+
// Try to read a bit (4k bytes) to include in the error message.
103+
b, _ := io.ReadAll(io.LimitReader(resp.Body, 4<<10))
104+
resp.Body.Close()
92105
conn.Close()
93-
return nil, fmt.Errorf("failed to connect to proxy %v: %v", proxyURL, resp.Status)
106+
return nil, fmt.Errorf("failed to connect to proxy %s: %s: %q", proxyURL.Redacted(), resp.Status, b)
94107
}
95-
resp.Body.Close()
96-
return conn, nil
108+
// 200 CONNECT: do NOT resp.Body.Close(); it would interfere with the tunnel.
109+
return &connWithBufferedReader{Conn: conn, r: br}, nil
97110
}
98111
dialTLS := func(ctx context.Context, network, addr string) (net.Conn, error) {
99112
// Dial the underlying connection through the proxy

0 commit comments

Comments
 (0)