Skip to content

Commit

Permalink
Ensure a hijacked connection implements CloseWrite whenever its under…
Browse files Browse the repository at this point in the history
…lying

backport jim-minter@3798392#diff-59ab7cc5bb1a636a4bc611d138984608

Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1668042

Signed-off-by: Antonio Murdaca <runcom@linux.com>
  • Loading branch information
runcom committed Jan 21, 2019
1 parent 11e17d3 commit b2f74b2
Showing 1 changed file with 41 additions and 2 deletions.
43 changes: 41 additions & 2 deletions client/hijack.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package client

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

rwc, br := clientconn.Hijack()
c, br := clientconn.Hijack()
if br.Buffered() > 0 {
// If there is buffered content, wrap the connection. We return an
// object that implements CloseWrite iff the underlying connection
// implements it.
if _, ok := c.(types.CloseWriter); ok {
c = &hijackedConnCloseWriter{c, br}
} else {
c = &hijackedConn{c, br}
}
} else {
br.Reset(nil)
}

return types.HijackedResponse{Conn: c, Reader: bufio.NewReader(c)}, err
}

// hijackedConn wraps a net.Conn and is returned by setupHijackConn in the case
// that a) there was already buffered data in the http layer when Hijack() was
// called, and b) the underlying net.Conn does *not* implement CloseWrite().
// hijackedConn does not implement CloseWrite() either.
type hijackedConn struct {
net.Conn
r *bufio.Reader
}

func (c *hijackedConn) Read(b []byte) (int, error) {
return c.r.Read(b)
}

// hijackedConnCloseWriter is a hijackedConn which additionally implements
// CloseWrite(). It is returned by setupHijackConn in the case that a) there
// was already buffered data in the http layer when Hijack() was called, and b)
// the underlying net.Conn *does* implement CloseWrite().
type hijackedConnCloseWriter hijackedConn

var _ types.CloseWriter = &hijackedConnCloseWriter{}

return types.HijackedResponse{Conn: rwc, Reader: br}, err
func (c *hijackedConnCloseWriter) CloseWrite() error {
conn := c.Conn.(types.CloseWriter)
return conn.CloseWrite()
}

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

0 comments on commit b2f74b2

Please sign in to comment.