Skip to content

Commit b2f74b2

Browse files
committed
Ensure a hijacked connection implements CloseWrite whenever its underlying
backport jim-minter@3798392#diff-59ab7cc5bb1a636a4bc611d138984608 Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1668042 Signed-off-by: Antonio Murdaca <[email protected]>
1 parent 11e17d3 commit b2f74b2

File tree

1 file changed

+41
-2
lines changed

1 file changed

+41
-2
lines changed

client/hijack.go

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package client
22

33
import (
4+
"bufio"
45
"crypto/tls"
56
"errors"
67
"fmt"
@@ -74,9 +75,47 @@ func (cli *Client) postHijacked(ctx context.Context, path string, query url.Valu
7475
// Server hijacks the connection, error 'connection closed' expected
7576
_, err = clientconn.Do(req)
7677

77-
rwc, br := clientconn.Hijack()
78+
c, br := clientconn.Hijack()
79+
if br.Buffered() > 0 {
80+
// If there is buffered content, wrap the connection. We return an
81+
// object that implements CloseWrite iff the underlying connection
82+
// implements it.
83+
if _, ok := c.(types.CloseWriter); ok {
84+
c = &hijackedConnCloseWriter{c, br}
85+
} else {
86+
c = &hijackedConn{c, br}
87+
}
88+
} else {
89+
br.Reset(nil)
90+
}
91+
92+
return types.HijackedResponse{Conn: c, Reader: bufio.NewReader(c)}, err
93+
}
94+
95+
// hijackedConn wraps a net.Conn and is returned by setupHijackConn in the case
96+
// that a) there was already buffered data in the http layer when Hijack() was
97+
// called, and b) the underlying net.Conn does *not* implement CloseWrite().
98+
// hijackedConn does not implement CloseWrite() either.
99+
type hijackedConn struct {
100+
net.Conn
101+
r *bufio.Reader
102+
}
103+
104+
func (c *hijackedConn) Read(b []byte) (int, error) {
105+
return c.r.Read(b)
106+
}
107+
108+
// hijackedConnCloseWriter is a hijackedConn which additionally implements
109+
// CloseWrite(). It is returned by setupHijackConn in the case that a) there
110+
// was already buffered data in the http layer when Hijack() was called, and b)
111+
// the underlying net.Conn *does* implement CloseWrite().
112+
type hijackedConnCloseWriter hijackedConn
113+
114+
var _ types.CloseWriter = &hijackedConnCloseWriter{}
78115

79-
return types.HijackedResponse{Conn: rwc, Reader: br}, err
116+
func (c *hijackedConnCloseWriter) CloseWrite() error {
117+
conn := c.Conn.(types.CloseWriter)
118+
return conn.CloseWrite()
80119
}
81120

82121
func tlsDial(network, addr string, config *tls.Config) (net.Conn, error) {

0 commit comments

Comments
 (0)