Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stuck Hijack() on net.Conn compatible I/O server rnet/http.(*conn).hijackLocked #48167

Closed
prologic opened this issue Sep 3, 2021 · 3 comments

Comments

@prologic
Copy link

prologic commented Sep 3, 2021

What version of Go are you using (go version)?

$ go version
go version go1.16.6 darwin/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/prologic/Library/Caches/go-build"
GOENV="/Users/prologic/Library/Application Support/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/prologic/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/prologic/go"
GOPRIVATE=""
GOPROXY="https://goproxy.mills.io/"
GOROOT="/usr/local/Cellar/go/1.16.6/libexec"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/Cellar/go/1.16.6/libexec/pkg/tool/darwin_amd64"
GOVCS=""
GOVERSION="go1.16.6"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/prologic/Projects/go-http-bug/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/8h/c9gl4gms3fjb0kyf7nb42ybh0000gn/T/go-build2407089176=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

The follow code (re-pasted here for posterity) exhibits a bug? very similar to this issue that was discussed and closed with no fixes/changes? to the Go std library some years ago.

package main

import (
	"errors"
	"fmt"
	"io"
	"net"
	"net/http"
	"net/http/httputil"
	"sync"
	"time"

	"github.com/gliderlabs/ssh"
	log "github.com/sirupsen/logrus"
	"github.com/tv42/httpunix"
)

// StdioAddr implements net.Addr to provide an emulated network
// address for use with StdioConn.
type StdioAddr struct {
	id string
}

func (s *StdioAddr) Network() string {
	return "stdio"
}

func (s *StdioAddr) String() string {
	return s.id
}

func NewStdioConn(localID, remoteID string, in io.ReadCloser, out io.WriteCloser) *StdioConn {
	return &StdioConn{
		local:  &StdioAddr{localID},
		remote: &StdioAddr{remoteID},
		in:     in,
		out:    out,
	}
}

// StdioConn implements net.Conn to provide an emulated network
// connection between two processes over stdin/stdout.
type StdioConn struct {
	sync.RWMutex
	readClosed  bool
	writeClosed bool

	local  *StdioAddr
	remote *StdioAddr
	in     io.ReadCloser
	out    io.WriteCloser
}

func (sc *StdioConn) String() string {
	return fmt.Sprintf("%s<->%s", sc.LocalAddr(), sc.RemoteAddr())
}

func (sc *StdioConn) isClosed() bool {
	sc.RLock()
	defer sc.RUnlock()
	return sc.writeClosed && sc.readClosed
}

func (sc *StdioConn) isReadClosed() bool {
	sc.RLock()
	defer sc.RUnlock()
	return sc.readClosed
}

func (sc *StdioConn) isWriteClosed() bool {
	sc.RLock()
	defer sc.RUnlock()
	return sc.writeClosed
}

func (sc *StdioConn) Read(b []byte) (int, error) {
	if sc.isReadClosed() {
		return 0, errors.New("read on closed conn")
	}
	return sc.in.Read(b)
}

func (sc *StdioConn) Write(b []byte) (int, error) {
	if sc.isWriteClosed() {
		return 0, errors.New("write on closed conn")
	}
	return sc.out.Write(b)
}

func (sc *StdioConn) CloseRead() error {
	sc.Lock()
	defer sc.Unlock()
	sc.readClosed = true
	return sc.in.Close()
}

func (sc *StdioConn) CloseWrite() error {
	sc.Lock()
	defer sc.Unlock()
	sc.writeClosed = true
	return sc.out.Close()
}

func (sc *StdioConn) Close() error {
	if err := sc.CloseRead(); err != nil {
		return err
	}

	return sc.CloseWrite()
}

func (sc *StdioConn) LocalAddr() net.Addr {
	return sc.local
}

func (sc *StdioConn) RemoteAddr() net.Addr {
	return sc.remote
}

func (sc *StdioConn) SetDeadline(t time.Time) error {
	return nil
}

func (sc *StdioConn) SetReadDeadline(t time.Time) error {
	return nil
}

func (sc *StdioConn) SetWriteDeadline(t time.Time) error {
	return nil
}

func NewStdioListener(conn *StdioConn) *StdioListener {
	sl := &StdioListener{
		ready: make(chan *StdioConn),
		conn:  conn,
	}
	sl.Close()
	return sl
}

// StdioListener wraps a *StdioConn to implement net.Listener.
type StdioListener struct {
	ready chan *StdioConn
	conn  *StdioConn
}

func (sl *StdioListener) Accept() (net.Conn, error) {
	if sl.conn.isClosed() {
		return nil, errors.New("accept on closed conn")
	}
	return <-sl.ready, nil
}

func (sl *StdioListener) Addr() net.Addr {
	return sl.conn.LocalAddr()
}

func (sl *StdioListener) Close() error {
	if sl.conn.isClosed() {
		return nil
	}

	go func() {
		sl.ready <- sl.conn
	}()
	return nil
}

func main() {
	ssh.Handle(func(sess ssh.Session) {
		switch sess.RawCommand() {
		case "docker system dial-stdio":
		default:
			sess.Write([]byte("This is not a normal SSH server\n"))
			sess.Exit(255)
		}

		conn := NewStdioConn(
			sess.LocalAddr().String(),
			sess.RemoteAddr().String(),
			sess.(io.ReadCloser),
			sess.(io.WriteCloser),
		)
		ln := NewStdioListener(conn)

		t := &httpunix.Transport{
			DialTimeout:           100 * time.Millisecond,
			RequestTimeout:        1 * time.Second,
			ResponseHeaderTimeout: 1 * time.Second,
		}
		t.RegisterLocation("docker", "/var/run/docker.sock")

		proxy := &httputil.ReverseProxy{
			Director: func(req *http.Request) {
				req.URL.Scheme = "http+unix"
				req.URL.Host = "docker"
			},
			Transport: t,
		}

		svr := &http.Server{Handler: proxy}

		if err := svr.Serve(ln); err != nil {
			log.WithError(err).Error("error serving http session")
		}
	})

	log.Fatal(ssh.ListenAndServe(":2222", nil))
}

Compiling and running this:

  1. Ensure you have a Docker daemon running on your system (either Linux or Docker for Desktop)
  2. Compile the above code with Go111Modules enabled
  3. Run without arguments
  4. Connect a docker client with a simple:
    DOCKER_HOST=ssh://localhost:2222 docker run -i --rm alpine echo Hello World

For clarity:

$ mkdir go-http-hijack-bug
$ cd go-http-hijack-bug
$ wget https://gist.github.com/prologic/62dfb545e86aa1d066f8e7e1f3bf8de7/raw/5e0e8abe6572be0afb24116b1fe1c747363ae537/main.go
$ go mod init go-http-hijack-bug
$ go mod tidy
$ go build
$ ./go-http-hijack-bug

And connect a Docker CLI client:

$ DOCKER_HOST=ssh://localhost:2222 docker run -i --rm alpine echo Hello World

What did you expect to see?

I expect to see:

Hello World

from running the Docker CLI client with the above sample.

This should also in turn start and attach to the created container. You can see the container has in fact been created in a "created" state:

$ docker ps -a | head
CONTAINER ID   IMAGE     COMMAND              CREATED              STATUS                    PORTS     NAMES
e2c51aca3d97   alpine    "echo Hello World"   About a minute ago   Created                             zealous_goldberg

What did you see instead?

Observe that the Docker CLI client above "hangs" with the expected output of "Hello World" not shown and the container is never run.

@prologic
Copy link
Author

prologic commented Sep 3, 2021

Terminating the process with SIGQUIT (^\) shows:

Stack trace
$ ./go-http-hijack-bug
^\SIGQUIT: quit
PC=0x7fff2038ecde m=0 sigcode=0

goroutine 0 [idle]:
runtime.pthread_cond_wait(0x1549be0, 0x1549ba0, 0x0)
/usr/local/Cellar/go/1.16.6/libexec/src/runtime/sys_darwin.go:384 +0x39
runtime.semasleep(0xffffffffffffffff, 0x1027bc7)
/usr/local/Cellar/go/1.16.6/libexec/src/runtime/os_darwin.go:63 +0x8d
runtime.notesleep(0x1549990)
/usr/local/Cellar/go/1.16.6/libexec/src/runtime/lock_sema.go:181 +0xdb
runtime.mPark()
/usr/local/Cellar/go/1.16.6/libexec/src/runtime/proc.go:1340 +0x39
runtime.stopm()
/usr/local/Cellar/go/1.16.6/libexec/src/runtime/proc.go:2301 +0x92
runtime.findrunnable(0xc00003f000, 0x0)
/usr/local/Cellar/go/1.16.6/libexec/src/runtime/proc.go:2960 +0x72e
runtime.schedule()
/usr/local/Cellar/go/1.16.6/libexec/src/runtime/proc.go:3169 +0x2d7
runtime.park_m(0xc00008ac00)
/usr/local/Cellar/go/1.16.6/libexec/src/runtime/proc.go:3318 +0x9d
runtime.mcall(0x106a236)
/usr/local/Cellar/go/1.16.6/libexec/src/runtime/asm_amd64.s:327 +0x5b

goroutine 1 [IO wait, 6 minutes]:
internal/poll.runtime_pollWait(0x17c7f48, 0x72, 0x0)
/usr/local/Cellar/go/1.16.6/libexec/src/runtime/netpoll.go:222 +0x55
internal/poll.(*pollDesc).wait(0xc00015e018, 0x72, 0x0, 0x0, 0x13477da)
/usr/local/Cellar/go/1.16.6/libexec/src/internal/poll/fd_poll_runtime.go:87 +0x45
internal/poll.(*pollDesc).waitRead(...)
/usr/local/Cellar/go/1.16.6/libexec/src/internal/poll/fd_poll_runtime.go:92
internal/poll.(*FD).Accept(0xc00015e000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
/usr/local/Cellar/go/1.16.6/libexec/src/internal/poll/fd_unix.go:401 +0x212
net.(*netFD).accept(0xc00015e000, 0x37e11d600, 0x0, 0x0)
/usr/local/Cellar/go/1.16.6/libexec/src/net/fd_unix.go:172 +0x45
net.(*TCPListener).accept(0xc00000e3f0, 0xc000127e18, 0xc000127e20, 0x18)
/usr/local/Cellar/go/1.16.6/libexec/src/net/tcpsock_posix.go:139 +0x32
net.(*TCPListener).Accept(0xc00000e3f0, 0x1360f08, 0xc00011a6c0, 0x13b2318, 0xc000586120)
/usr/local/Cellar/go/1.16.6/libexec/src/net/tcpsock.go:261 +0x65
github.com/gliderlabs/ssh.(*Server).Serve(0xc00011a6c0, 0x13afb60, 0xc00000e3f0, 0x0, 0x0)
/Users/prologic/go/pkg/mod/github.com/gliderlabs/[email protected]/server.go:237 +0x151
github.com/gliderlabs/ssh.(*Server).ListenAndServe(0xc00011a6c0, 0xc00011a6c0, 0x300000002)
/Users/prologic/go/pkg/mod/github.com/gliderlabs/[email protected]/server.go:338 +0xaf
github.com/gliderlabs/ssh.ListenAndServe(0x134745f, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
/Users/prologic/go/pkg/mod/github.com/gliderlabs/[email protected]/ssh.go:108 +0xc5
main.main()
/Users/prologic/Projects/go-http-hijack-bug/main.go:208 +0x65

goroutine 121 [select, 6 minutes]:
golang.org/x/crypto/ssh.(*handshakeTransport).kexLoop(0xc0005978c0)
/Users/prologic/go/pkg/mod/golang.org/x/[email protected]/ssh/handshake.go:268 +0xd8
created by golang.org/x/crypto/ssh.newServerTransport
/Users/prologic/go/pkg/mod/golang.org/x/[email protected]/ssh/handshake.go:143 +0x107

goroutine 103 [chan receive, 6 minutes]:
github.com/gliderlabs/ssh.(*Server).HandleConn(0xc00011a6c0, 0x13b2318, 0xc0004ec080)
/Users/prologic/go/pkg/mod/github.com/gliderlabs/[email protected]/server.go:296 +0x313
created by github.com/gliderlabs/ssh.(*Server).Serve
/Users/prologic/go/pkg/mod/github.com/gliderlabs/[email protected]/server.go:258 +0x19c

goroutine 148 [sync.Cond.Wait, 6 minutes]:
sync.runtime_notifyListWait(0xc00020e590, 0xc000000001)
/usr/local/Cellar/go/1.16.6/libexec/src/runtime/sema.go:513 +0xf8
sync.(*Cond).Wait(0xc00020e580)
/usr/local/Cellar/go/1.16.6/libexec/src/sync/cond.go:56 +0x99
golang.org/x/crypto/ssh.(*buffer).Read(0xc0004ca280, 0xc0004e6c11, 0x1, 0x1, 0x0, 0x0, 0x0)
/Users/prologic/go/pkg/mod/golang.org/x/[email protected]/ssh/buffer.go:94 +0x1dc
golang.org/x/crypto/ssh.(*channel).ReadExtended(0xc000242000, 0xc0004e6c11, 0x1, 0x1, 0x0, 0x0, 0x0, 0x12517f0)
/Users/prologic/go/pkg/mod/golang.org/x/[email protected]/ssh/channel.go:351 +0x1fc
golang.org/x/crypto/ssh.(*channel).Read(0xc000242000, 0xc0004e6c11, 0x1, 0x1, 0x4, 0x13619d0, 0xc0004e45a0)
/Users/prologic/go/pkg/mod/golang.org/x/[email protected]/ssh/channel.go:528 +0x5b
main.(*StdioConn).Read(0xc0004e45a0, 0xc0004e6c11, 0x1, 0x1, 0xc00050a7c8, 0xc00050a7c8, 0xc000202780)
/Users/prologic/Projects/go-http-hijack-bug/main.go:80 +0xb6
net/http.(*connReader).backgroundRead(0xc0004e6c00)
/usr/local/Cellar/go/1.16.6/libexec/src/net/http/server.go:672 +0x58
created by net/http.(*connReader).startBackgroundRead
/usr/local/Cellar/go/1.16.6/libexec/src/net/http/server.go:668 +0xd5

goroutine 107 [chan receive, 6 minutes]:
main.(*StdioListener).Accept(0xc0004ce670, 0xc00017add0, 0x18, 0xc00008b080, 0x123e13b)
/Users/prologic/Projects/go-http-hijack-bug/main.go:151 +0xa8
net/http.(*Server).Serve(0xc0004dc2a0, 0x13afb30, 0xc0004ce670, 0x0, 0x0)
/usr/local/Cellar/go/1.16.6/libexec/src/net/http/server.go:2961 +0x285
main.main.func1(0x13b3558, 0xc000214680)
/Users/prologic/Projects/go-http-hijack-bug/main.go:203 +0x465
github.com/gliderlabs/ssh.(*session).handleRequests.func1(0xc000214680)
/Users/prologic/go/pkg/mod/github.com/gliderlabs/[email protected]/session.go:262 +0x3b
created by github.com/gliderlabs/ssh.(*session).handleRequests
/Users/prologic/go/pkg/mod/github.com/gliderlabs/[email protected]/session.go:261 +0x49b

goroutine 87 [chan receive, 6 minutes]:
main.(*StdioListener).Accept(0xc00058c610, 0xc000178dd0, 0x18, 0xc00008b380, 0x123e13b)
/Users/prologic/Projects/go-http-hijack-bug/main.go:151 +0xa8
net/http.(*Server).Serve(0xc0005a2460, 0x13afb30, 0xc00058c610, 0x0, 0x0)
/usr/local/Cellar/go/1.16.6/libexec/src/net/http/server.go:2961 +0x285
main.main.func1(0x13b3558, 0xc00007ea90)
/Users/prologic/Projects/go-http-hijack-bug/main.go:203 +0x465
github.com/gliderlabs/ssh.(*session).handleRequests.func1(0xc00007ea90)
/Users/prologic/go/pkg/mod/github.com/gliderlabs/[email protected]/session.go:262 +0x3b
created by github.com/gliderlabs/ssh.(*session).handleRequests
/Users/prologic/go/pkg/mod/github.com/gliderlabs/[email protected]/session.go:261 +0x49b

goroutine 94 [chan receive, 6 minutes]:
main.(*StdioListener).Accept(0xc00058c940, 0xc00005fdd0, 0x18, 0xc00008b980, 0x123e13b)
/Users/prologic/Projects/go-http-hijack-bug/main.go:151 +0xa8
net/http.(*Server).Serve(0xc0005a2620, 0x13afb30, 0xc00058c940, 0x0, 0x0)
/usr/local/Cellar/go/1.16.6/libexec/src/net/http/server.go:2961 +0x285
main.main.func1(0x13b3558, 0xc00007ed00)
/Users/prologic/Projects/go-http-hijack-bug/main.go:203 +0x465
github.com/gliderlabs/ssh.(*session).handleRequests.func1(0xc00007ed00)
/Users/prologic/go/pkg/mod/github.com/gliderlabs/[email protected]/session.go:262 +0x3b
created by github.com/gliderlabs/ssh.(*session).handleRequests
/Users/prologic/go/pkg/mod/github.com/gliderlabs/[email protected]/session.go:261 +0x49b

goroutine 106 [chan receive, 6 minutes]:
github.com/gliderlabs/ssh.(*session).handleRequests(0xc000214680, 0xc0004cd020)
/Users/prologic/go/pkg/mod/github.com/gliderlabs/[email protected]/session.go:238 +0x59
github.com/gliderlabs/ssh.DefaultSessionHandler(0xc00011a6c0, 0xc000528360, 0x13b0418, 0xc000242000, 0x13b2ce8, 0xc0004d8420)
/Users/prologic/go/pkg/mod/github.com/gliderlabs/[email protected]/session.go:107 +0x12a
created by github.com/gliderlabs/ssh.(*Server).HandleConn
/Users/prologic/go/pkg/mod/github.com/gliderlabs/[email protected]/server.go:305 +0x3f0

goroutine 116 [IO wait, 6 minutes]:
internal/poll.runtime_pollWait(0x17c7d78, 0x72, 0xffffffffffffffff)
/usr/local/Cellar/go/1.16.6/libexec/src/runtime/netpoll.go:222 +0x55
internal/poll.(*pollDesc).wait(0xc000589518, 0x72, 0x1000, 0x1000, 0xffffffffffffffff)
/usr/local/Cellar/go/1.16.6/libexec/src/internal/poll/fd_poll_runtime.go:87 +0x45
internal/poll.(*pollDesc).waitRead(...)
/usr/local/Cellar/go/1.16.6/libexec/src/internal/poll/fd_poll_runtime.go:92
internal/poll.(*FD).Read(0xc000589500, 0xc0005fd000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
/usr/local/Cellar/go/1.16.6/libexec/src/internal/poll/fd_unix.go:166 +0x1d5
net.(*netFD).Read(0xc000589500, 0xc0005fd000, 0x1000, 0x1000, 0xc0001bce88, 0xc0001bcd18, 0x2)
/usr/local/Cellar/go/1.16.6/libexec/src/net/fd_posix.go:55 +0x4f
net.(*conn).Read(0xc000586110, 0xc0005fd000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
/usr/local/Cellar/go/1.16.6/libexec/src/net/net.go:183 +0x91
net/http.(*persistConn).Read(0xc0005e6480, 0xc0005fd000, 0x1000, 0x1000, 0xc0001bcdc4, 0x2, 0x2)
/usr/local/Cellar/go/1.16.6/libexec/src/net/http/transport.go:1922 +0x77
bufio.(*Reader).fill(0xc0005fa300)
/usr/local/Cellar/go/1.16.6/libexec/src/bufio/bufio.go:101 +0x108
bufio.(*Reader).Peek(0xc0005fa300, 0x1, 0x0, 0x1, 0x1, 0x1, 0x0)
/usr/local/Cellar/go/1.16.6/libexec/src/bufio/bufio.go:139 +0x4f
net/http.(*persistConn).readLoop(0xc0005e6480)
/usr/local/Cellar/go/1.16.6/libexec/src/net/http/transport.go:2083 +0x1a8
created by net/http.(*Transport).dialConn
/usr/local/Cellar/go/1.16.6/libexec/src/net/http/transport.go:1743 +0xc77

goroutine 117 [select, 6 minutes]:
net/http.(*persistConn).writeLoop(0xc0005e6480)
/usr/local/Cellar/go/1.16.6/libexec/src/net/http/transport.go:2382 +0xf7
created by net/http.(*Transport).dialConn
/usr/local/Cellar/go/1.16.6/libexec/src/net/http/transport.go:1744 +0xc9c

goroutine 105 [select, 6 minutes]:
golang.org/x/crypto/ssh.(*handshakeTransport).kexLoop(0xc0004da9a0)
/Users/prologic/go/pkg/mod/golang.org/x/[email protected]/ssh/handshake.go:268 +0xd8
created by golang.org/x/crypto/ssh.newServerTransport
/Users/prologic/go/pkg/mod/golang.org/x/[email protected]/ssh/handshake.go:143 +0x107

goroutine 104 [IO wait, 6 minutes]:
internal/poll.runtime_pollWait(0x17c7e60, 0x72, 0xffffffffffffffff)
/usr/local/Cellar/go/1.16.6/libexec/src/runtime/netpoll.go:222 +0x55
internal/poll.(*pollDesc).wait(0xc0004e8c98, 0x72, 0x1000, 0x1000, 0xffffffffffffffff)
/usr/local/Cellar/go/1.16.6/libexec/src/internal/poll/fd_poll_runtime.go:87 +0x45
internal/poll.(*pollDesc).waitRead(...)
/usr/local/Cellar/go/1.16.6/libexec/src/internal/poll/fd_poll_runtime.go:92
internal/poll.(*FD).Read(0xc0004e8c80, 0xc000240000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
/usr/local/Cellar/go/1.16.6/libexec/src/internal/poll/fd_unix.go:166 +0x1d5
net.(*netFD).Read(0xc0004e8c80, 0xc000240000, 0x1000, 0x1000, 0xc0004ec080, 0x0, 0x0)
/usr/local/Cellar/go/1.16.6/libexec/src/net/fd_posix.go:55 +0x4f
net.(*conn).Read(0xc0004ec080, 0xc000240000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
/usr/local/Cellar/go/1.16.6/libexec/src/net/net.go:183 +0x91
github.com/gliderlabs/ssh.(*serverConn).Read(0xc00020e440, 0xc000240000, 0x1000, 0x1000, 0x1f23be8953cdea4, 0x7bd35152bd8eb815, 0xc0001b8b68)
/Users/prologic/go/pkg/mod/github.com/gliderlabs/[email protected]/conn.go:28 +0x63
bufio.(*Reader).Read(0xc0004cce40, 0xc000248000, 0x4, 0x6ec, 0x0, 0x0, 0x6ec)
/usr/local/Cellar/go/1.16.6/libexec/src/bufio/bufio.go:227 +0x222
io.ReadAtLeast(0x13ab120, 0xc0004cce40, 0xc000248000, 0x4, 0x6ec, 0x4, 0x20, 0xc0001b8d10, 0x0)
/usr/local/Cellar/go/1.16.6/libexec/src/io/io.go:328 +0x87
io.ReadFull(...)
/usr/local/Cellar/go/1.16.6/libexec/src/io/io.go:347
golang.org/x/crypto/ssh.(*chacha20Poly1305Cipher).readCipherPacket(0xc000510b40, 0xc00000000e, 0x13ab120, 0xc0004cce40, 0xc000248005, 0x6cf, 0x6e7, 0x0, 0xc0001b8e78)
/Users/prologic/go/pkg/mod/golang.org/x/[email protected]/ssh/cipher.go:675 +0x211
golang.org/x/crypto/ssh.(*connectionState).readPacket(0xc0004d0d80, 0xc0004cce40, 0x10071c5, 0xc0004ccf60, 0xc000186e40, 0xc0001b8fb0, 0xc0001b8f20)
/Users/prologic/go/pkg/mod/golang.org/x/[email protected]/ssh/transport.go:130 +0x68
golang.org/x/crypto/ssh.(*transport).readPacket(0xc0004d0d80, 0xc000248700, 0xc0004ccfb8, 0x6cf, 0x0, 0x0)
/Users/prologic/go/pkg/mod/golang.org/x/[email protected]/ssh/transport.go:114 +0x3b
golang.org/x/crypto/ssh.(*handshakeTransport).readOnePacket(0xc0004da9a0, 0xc0001b8f00, 0xc000248700, 0x6cf, 0x6cf, 0x0, 0x0)
/Users/prologic/go/pkg/mod/golang.org/x/[email protected]/ssh/handshake.go:374 +0x50
golang.org/x/crypto/ssh.(*handshakeTransport).readLoop(0xc0004da9a0)
/Users/prologic/go/pkg/mod/golang.org/x/[email protected]/ssh/handshake.go:197 +0x4d
created by golang.org/x/crypto/ssh.newServerTransport
/Users/prologic/go/pkg/mod/golang.org/x/[email protected]/ssh/handshake.go:142 +0xe5

goroutine 41 [chan receive, 6 minutes]:
main.(*StdioListener).Accept(0xc00051c270, 0xc0001bedd0, 0x18, 0xc00055a300, 0x123e13b)
/Users/prologic/Projects/go-http-hijack-bug/main.go:151 +0xa8
net/http.(*Server).Serve(0xc00052c0e0, 0x13afb30, 0xc00051c270, 0x0, 0x0)
/usr/local/Cellar/go/1.16.6/libexec/src/net/http/server.go:2961 +0x285
main.main.func1(0x13b3558, 0xc00055e000)
/Users/prologic/Projects/go-http-hijack-bug/main.go:203 +0x465
github.com/gliderlabs/ssh.(*session).handleRequests.func1(0xc00055e000)
/Users/prologic/go/pkg/mod/github.com/gliderlabs/[email protected]/session.go:262 +0x3b
created by github.com/gliderlabs/ssh.(*session).handleRequests
/Users/prologic/go/pkg/mod/github.com/gliderlabs/[email protected]/session.go:261 +0x49b

goroutine 120 [IO wait, 6 minutes]:
internal/poll.runtime_pollWait(0x17c7ac0, 0x72, 0xffffffffffffffff)
/usr/local/Cellar/go/1.16.6/libexec/src/runtime/netpoll.go:222 +0x55
internal/poll.(*pollDesc).wait(0xc000589718, 0x72, 0x1000, 0x1000, 0xffffffffffffffff)
/usr/local/Cellar/go/1.16.6/libexec/src/internal/poll/fd_poll_runtime.go:87 +0x45
internal/poll.(*pollDesc).waitRead(...)
/usr/local/Cellar/go/1.16.6/libexec/src/internal/poll/fd_poll_runtime.go:92
internal/poll.(*FD).Read(0xc000589700, 0xc00028b000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
/usr/local/Cellar/go/1.16.6/libexec/src/internal/poll/fd_unix.go:166 +0x1d5
net.(*netFD).Read(0xc000589700, 0xc00028b000, 0x1000, 0x1000, 0xc000586120, 0x0, 0x0)
/usr/local/Cellar/go/1.16.6/libexec/src/net/fd_posix.go:55 +0x4f
net.(*conn).Read(0xc000586120, 0xc00028b000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
/usr/local/Cellar/go/1.16.6/libexec/src/net/net.go:183 +0x91
github.com/gliderlabs/ssh.(*serverConn).Read(0xc000079640, 0xc00028b000, 0x1000, 0x1000, 0x54ddf60fb375596, 0x91bed412c3e05d8d, 0xc0001bfb68)
/Users/prologic/go/pkg/mod/github.com/gliderlabs/[email protected]/conn.go:28 +0x63
bufio.(*Reader).Read(0xc0005fa660, 0xc000312000, 0x4, 0x14c, 0x0, 0x0, 0x14c)
/usr/local/Cellar/go/1.16.6/libexec/src/bufio/bufio.go:227 +0x222
io.ReadAtLeast(0x13ab120, 0xc0005fa660, 0xc000312000, 0x4, 0x14c, 0x4, 0x20, 0xc0001bfd10, 0x0)
/usr/local/Cellar/go/1.16.6/libexec/src/io/io.go:328 +0x87
io.ReadFull(...)
/usr/local/Cellar/go/1.16.6/libexec/src/io/io.go:347
golang.org/x/crypto/ssh.(*chacha20Poly1305Cipher).readCipherPacket(0xc0005110e0, 0xc00000000d, 0x13ab120, 0xc0005fa660, 0xc000312005, 0x12d, 0x147, 0x0, 0x0)
/Users/prologic/go/pkg/mod/golang.org/x/[email protected]/ssh/cipher.go:675 +0x211
golang.org/x/crypto/ssh.(*connectionState).readPacket(0xc0005e65a0, 0xc0005fa660, 0x1007168, 0xc0005fa7d8, 0xc0002981f8, 0xc0001bffb0, 0x0)
/Users/prologic/go/pkg/mod/golang.org/x/[email protected]/ssh/transport.go:130 +0x68
golang.org/x/crypto/ssh.(*transport).readPacket(0xc0005e65a0, 0xc000309180, 0xc0005fa7d8, 0x12d, 0x0, 0x0)
/Users/prologic/go/pkg/mod/golang.org/x/[email protected]/ssh/transport.go:114 +0x3b
golang.org/x/crypto/ssh.(*handshakeTransport).readOnePacket(0xc0005978c0, 0xc0001bff00, 0xc000309180, 0x12d, 0x12d, 0x0, 0x0)
/Users/prologic/go/pkg/mod/golang.org/x/[email protected]/ssh/handshake.go:374 +0x50
golang.org/x/crypto/ssh.(*handshakeTransport).readLoop(0xc0005978c0)
/Users/prologic/go/pkg/mod/golang.org/x/[email protected]/ssh/handshake.go:197 +0x4d
created by golang.org/x/crypto/ssh.newServerTransport
/Users/prologic/go/pkg/mod/golang.org/x/[email protected]/ssh/handshake.go:142 +0xe5

goroutine 109 [sync.Cond.Wait, 6 minutes]:
sync.runtime_notifyListWait(0xc00020e9d0, 0x1)
/usr/local/Cellar/go/1.16.6/libexec/src/runtime/sema.go:513 +0xf8
sync.(*Cond).Wait(0xc00020e9c0)
/usr/local/Cellar/go/1.16.6/libexec/src/sync/cond.go:56 +0x99
net/http.(*connReader).abortPendingRead(0xc0004e6c00)
/usr/local/Cellar/go/1.16.6/libexec/src/net/http/server.go:720 +0xb2
net/http.(*response).finishRequest(0xc0004dc460)
/usr/local/Cellar/go/1.16.6/libexec/src/net/http/server.go:1613 +0x9a
net/http.(*conn).serve(0xc0004e23c0, 0x13b0300, 0xc00020e980)
/usr/local/Cellar/go/1.16.6/libexec/src/net/http/server.go:1937 +0x90b
created by net/http.(*Server).Serve
/usr/local/Cellar/go/1.16.6/libexec/src/net/http/server.go:2993 +0x39b

goroutine 49 [chan receive, 6 minutes]:
golang.org/x/crypto/ssh.(*handshakeTransport).readPacket(0xc0004da9a0, 0xc000248700, 0x6cf, 0x6cf, 0x0, 0x0)
/Users/prologic/go/pkg/mod/golang.org/x/[email protected]/ssh/handshake.go:187 +0x4e
golang.org/x/crypto/ssh.(*mux).onePacket(0xc000558070, 0x0, 0x0)
/Users/prologic/go/pkg/mod/golang.org/x/[email protected]/ssh/mux.go:215 +0x37
golang.org/x/crypto/ssh.(*mux).loop(0xc000558070)
/Users/prologic/go/pkg/mod/golang.org/x/[email protected]/ssh/mux.go:190 +0x35
created by golang.org/x/crypto/ssh.newMux
/Users/prologic/go/pkg/mod/golang.org/x/[email protected]/ssh/mux.go:128 +0x158

goroutine 130 [chan receive, 6 minutes]:
github.com/gliderlabs/ssh.(*Server).handleRequests(0xc00011a6c0, 0x13b2ce8, 0xc0004d8420, 0xc000510cc0)
/Users/prologic/go/pkg/mod/github.com/gliderlabs/[email protected]/server.go:310 +0x45
created by github.com/gliderlabs/ssh.(*Server).HandleConn
/Users/prologic/go/pkg/mod/github.com/gliderlabs/[email protected]/server.go:295 +0x2ed

goroutine 47 [IO wait, 6 minutes]:
internal/poll.runtime_pollWait(0x17c7c90, 0x72, 0xffffffffffffffff)
/usr/local/Cellar/go/1.16.6/libexec/src/runtime/netpoll.go:222 +0x55
internal/poll.(*pollDesc).wait(0xc000538318, 0x72, 0x1000, 0x1000, 0xffffffffffffffff)
/usr/local/Cellar/go/1.16.6/libexec/src/internal/poll/fd_poll_runtime.go:87 +0x45
internal/poll.(*pollDesc).waitRead(...)
/usr/local/Cellar/go/1.16.6/libexec/src/internal/poll/fd_poll_runtime.go:92
internal/poll.(*FD).Read(0xc000538300, 0xc000576000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
/usr/local/Cellar/go/1.16.6/libexec/src/internal/poll/fd_unix.go:166 +0x1d5
net.(*netFD).Read(0xc000538300, 0xc000576000, 0x1000, 0x1000, 0xc000567e88, 0xc000567d18, 0x2)
/usr/local/Cellar/go/1.16.6/libexec/src/net/fd_posix.go:55 +0x4f
net.(*conn).Read(0xc00050e030, 0xc000576000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
/usr/local/Cellar/go/1.16.6/libexec/src/net/net.go:183 +0x91
net/http.(*persistConn).Read(0xc00051e360, 0xc000576000, 0x1000, 0x1000, 0xc000567dc4, 0x2, 0x2)
/usr/local/Cellar/go/1.16.6/libexec/src/net/http/transport.go:1922 +0x77
bufio.(*Reader).fill(0xc0005108a0)
/usr/local/Cellar/go/1.16.6/libexec/src/bufio/bufio.go:101 +0x108
bufio.(*Reader).Peek(0xc0005108a0, 0x1, 0x0, 0x1, 0x1, 0x1, 0x0)
/usr/local/Cellar/go/1.16.6/libexec/src/bufio/bufio.go:139 +0x4f
net/http.(*persistConn).readLoop(0xc00051e360)
/usr/local/Cellar/go/1.16.6/libexec/src/net/http/transport.go:2083 +0x1a8
created by net/http.(*Transport).dialConn
/usr/local/Cellar/go/1.16.6/libexec/src/net/http/transport.go:1743 +0xc77

goroutine 48 [select, 6 minutes]:
net/http.(*persistConn).writeLoop(0xc00051e360)
/usr/local/Cellar/go/1.16.6/libexec/src/net/http/transport.go:2382 +0xf7
created by net/http.(*Transport).dialConn
/usr/local/Cellar/go/1.16.6/libexec/src/net/http/transport.go:1744 +0xc9c

goroutine 113 [IO wait, 6 minutes]:
internal/poll.runtime_pollWait(0x17c7ba8, 0x72, 0xffffffffffffffff)
/usr/local/Cellar/go/1.16.6/libexec/src/runtime/netpoll.go:222 +0x55
internal/poll.(*pollDesc).wait(0xc0004e9018, 0x72, 0x1000, 0x1000, 0xffffffffffffffff)
/usr/local/Cellar/go/1.16.6/libexec/src/internal/poll/fd_poll_runtime.go:87 +0x45
internal/poll.(*pollDesc).waitRead(...)
/usr/local/Cellar/go/1.16.6/libexec/src/internal/poll/fd_poll_runtime.go:92
internal/poll.(*FD).Read(0xc0004e9000, 0xc000246000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
/usr/local/Cellar/go/1.16.6/libexec/src/internal/poll/fd_unix.go:166 +0x1d5
net.(*netFD).Read(0xc0004e9000, 0xc000246000, 0x1000, 0x1000, 0x1039c3c, 0xc0001bdc38, 0x1065020)
/usr/local/Cellar/go/1.16.6/libexec/src/net/fd_posix.go:55 +0x4f
net.(*conn).Read(0xc0004ec0b0, 0xc000246000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
/usr/local/Cellar/go/1.16.6/libexec/src/net/net.go:183 +0x91
net/http.(*persistConn).Read(0xc0004d10e0, 0xc000246000, 0x1000, 0x1000, 0xc000202780, 0xc0001bdd40, 0x1006c55)
/usr/local/Cellar/go/1.16.6/libexec/src/net/http/transport.go:1922 +0x77
bufio.(*Reader).fill(0xc0004cd2c0)
/usr/local/Cellar/go/1.16.6/libexec/src/bufio/bufio.go:101 +0x108
bufio.(*Reader).Peek(0xc0004cd2c0, 0x1, 0x0, 0x1, 0x4, 0x1, 0x3)
/usr/local/Cellar/go/1.16.6/libexec/src/bufio/bufio.go:139 +0x4f
net/http.(*persistConn).readLoop(0xc0004d10e0)
/usr/local/Cellar/go/1.16.6/libexec/src/net/http/transport.go:2083 +0x1a8
created by net/http.(*Transport).dialConn
/usr/local/Cellar/go/1.16.6/libexec/src/net/http/transport.go:1743 +0xc77

goroutine 146 [select, 6 minutes]:
net/http.(*persistConn).writeLoop(0xc0004d10e0)
/usr/local/Cellar/go/1.16.6/libexec/src/net/http/transport.go:2382 +0xf7
created by net/http.(*Transport).dialConn
/usr/local/Cellar/go/1.16.6/libexec/src/net/http/transport.go:1744 +0xc9c

goroutine 119 [chan receive, 6 minutes]:
github.com/gliderlabs/ssh.(*Server).HandleConn(0xc00011a6c0, 0x13b2318, 0xc000586120)
/Users/prologic/go/pkg/mod/github.com/gliderlabs/[email protected]/server.go:296 +0x313
created by github.com/gliderlabs/ssh.(*Server).Serve
/Users/prologic/go/pkg/mod/github.com/gliderlabs/[email protected]/server.go:258 +0x19c

goroutine 131 [chan receive, 6 minutes]:
golang.org/x/crypto/ssh.(*handshakeTransport).readPacket(0xc0005978c0, 0xc000309180, 0x12d, 0x12d, 0x0, 0x0)
/Users/prologic/go/pkg/mod/golang.org/x/[email protected]/ssh/handshake.go:187 +0x4e
golang.org/x/crypto/ssh.(*mux).onePacket(0xc0005580e0, 0x0, 0x0)
/Users/prologic/go/pkg/mod/golang.org/x/[email protected]/ssh/mux.go:215 +0x37
golang.org/x/crypto/ssh.(*mux).loop(0xc0005580e0)
/Users/prologic/go/pkg/mod/golang.org/x/[email protected]/ssh/mux.go:190 +0x35
created by golang.org/x/crypto/ssh.newMux
/Users/prologic/go/pkg/mod/golang.org/x/[email protected]/ssh/mux.go:128 +0x158

goroutine 132 [chan receive, 6 minutes]:
github.com/gliderlabs/ssh.(*Server).handleRequests(0xc00011a6c0, 0x13b2ce8, 0xc00058e960, 0xc000511260)
/Users/prologic/go/pkg/mod/github.com/gliderlabs/[email protected]/server.go:310 +0x45
created by github.com/gliderlabs/ssh.(*Server).HandleConn
/Users/prologic/go/pkg/mod/github.com/gliderlabs/[email protected]/server.go:295 +0x2ed

goroutine 133 [chan receive, 6 minutes]:
github.com/gliderlabs/ssh.(*session).handleRequests(0xc00055e270, 0xc0005112c0)
/Users/prologic/go/pkg/mod/github.com/gliderlabs/[email protected]/session.go:238 +0x59
github.com/gliderlabs/ssh.DefaultSessionHandler(0xc00011a6c0, 0xc0005284f8, 0x13b0418, 0xc00055c0c0, 0x13b2ce8, 0xc00058e960)
/Users/prologic/go/pkg/mod/github.com/gliderlabs/[email protected]/session.go:107 +0x12a
created by github.com/gliderlabs/ssh.(*Server).HandleConn
/Users/prologic/go/pkg/mod/github.com/gliderlabs/[email protected]/server.go:305 +0x3f0

goroutine 134 [chan receive, 6 minutes]:
main.(*StdioListener).Accept(0xc00051c830, 0xc0001badd0, 0x18, 0xc00055b800, 0x123e13b)
/Users/prologic/Projects/go-http-hijack-bug/main.go:151 +0xa8
net/http.(*Server).Serve(0xc00052c460, 0x13afb30, 0xc00051c830, 0x0, 0x0)
/usr/local/Cellar/go/1.16.6/libexec/src/net/http/server.go:2961 +0x285
main.main.func1(0x13b3558, 0xc00055e270)
/Users/prologic/Projects/go-http-hijack-bug/main.go:203 +0x465
github.com/gliderlabs/ssh.(*session).handleRequests.func1(0xc00055e270)
/Users/prologic/go/pkg/mod/github.com/gliderlabs/[email protected]/session.go:262 +0x3b
created by github.com/gliderlabs/ssh.(*session).handleRequests
/Users/prologic/go/pkg/mod/github.com/gliderlabs/[email protected]/session.go:261 +0x49b

goroutine 136 [sync.Cond.Wait, 6 minutes]:
sync.runtime_notifyListWait(0xc000552cd0, 0x0)
/usr/local/Cellar/go/1.16.6/libexec/src/runtime/sema.go:513 +0xf8
sync.(*Cond).Wait(0xc000552cc0)
/usr/local/Cellar/go/1.16.6/libexec/src/sync/cond.go:56 +0x99
net/http.(*connReader).abortPendingRead(0xc000536ff0)
/usr/local/Cellar/go/1.16.6/libexec/src/net/http/server.go:720 +0xb2
net/http.(*conn).hijackLocked(0xc000532500, 0x0, 0xc000571760, 0x104208e, 0xc000571730, 0x1065760)
/usr/local/Cellar/go/1.16.6/libexec/src/net/http/server.go:315 +0x53
net/http.(*response).Hijack(0xc00052c540, 0x0, 0x0, 0x0, 0x0, 0x0)
/usr/local/Cellar/go/1.16.6/libexec/src/net/http/server.go:1999 +0xaa
net/http/httputil.(*ReverseProxy).handleUpgradeResponse(0xc0005345f0, 0x13afd40, 0xc00052c540, 0xc000556900, 0xc00052ed80)
/usr/local/Cellar/go/1.16.6/libexec/src/net/http/httputil/reverseproxy.go:572 +0x55a
net/http/httputil.(*ReverseProxy).ServeHTTP(0xc0005345f0, 0x13afd40, 0xc00052c540, 0xc000556800)
/usr/local/Cellar/go/1.16.6/libexec/src/net/http/httputil/reverseproxy.go:295 +0xf97
net/http.serverHandler.ServeHTTP(0xc00052c460, 0x13afd40, 0xc00052c540, 0xc000556800)
/usr/local/Cellar/go/1.16.6/libexec/src/net/http/server.go:2867 +0xa3
net/http.(*conn).serve(0xc000532500, 0x13b0300, 0xc000552c80)
/usr/local/Cellar/go/1.16.6/libexec/src/net/http/server.go:1932 +0x8cd
created by net/http.(*Server).Serve
/usr/local/Cellar/go/1.16.6/libexec/src/net/http/server.go:2993 +0x39b

goroutine 137 [sync.Cond.Wait, 6 minutes]:
sync.runtime_notifyListWait(0xc000552890, 0xc000000000)
/usr/local/Cellar/go/1.16.6/libexec/src/runtime/sema.go:513 +0xf8
sync.(*Cond).Wait(0xc000552880)
/usr/local/Cellar/go/1.16.6/libexec/src/sync/cond.go:56 +0x99
golang.org/x/crypto/ssh.(*buffer).Read(0xc00051a400, 0xc000537001, 0x1, 0x1, 0x0, 0x0, 0x0)
/Users/prologic/go/pkg/mod/golang.org/x/[email protected]/ssh/buffer.go:94 +0x1dc
golang.org/x/crypto/ssh.(*channel).ReadExtended(0xc00055c0c0, 0xc000537001, 0x1, 0x1, 0x0, 0x0, 0x0, 0xc000536ea0)
/Users/prologic/go/pkg/mod/golang.org/x/[email protected]/ssh/channel.go:351 +0x1fc
golang.org/x/crypto/ssh.(*channel).Read(0xc00055c0c0, 0xc000537001, 0x1, 0x1, 0x0, 0x13619d0, 0xc0005345a0)
/Users/prologic/go/pkg/mod/golang.org/x/[email protected]/ssh/channel.go:528 +0x5b
main.(*StdioConn).Read(0xc0005345a0, 0xc000537001, 0x1, 0x1, 0x0, 0xc000055fc8, 0x12a6dfb)
/Users/prologic/Projects/go-http-hijack-bug/main.go:80 +0xb6
net/http.(*connReader).backgroundRead(0xc000536ff0)
/usr/local/Cellar/go/1.16.6/libexec/src/net/http/server.go:672 +0x58
created by net/http.(*connReader).startBackgroundRead
/usr/local/Cellar/go/1.16.6/libexec/src/net/http/server.go:668 +0xd5

goroutine 138 [select, 6 minutes]:
net/http/httputil.(*ReverseProxy).ServeHTTP.func1(0xc000542230, 0xc00051c8c0, 0x13b0258, 0xc000552d40)
/usr/local/Cellar/go/1.16.6/libexec/src/net/http/httputil/reverseproxy.go:225 +0x87
created by net/http/httputil.(*ReverseProxy).ServeHTTP
/usr/local/Cellar/go/1.16.6/libexec/src/net/http/httputil/reverseproxy.go:224 +0x16dc

goroutine 142 [select, 6 minutes]:
net/http/httputil.(*ReverseProxy).handleUpgradeResponse.func1(0xc000556900, 0xc000512ae0, 0x13afd10, 0xc000528600)
/usr/local/Cellar/go/1.16.6/libexec/src/net/http/httputil/reverseproxy.go:563 +0x96
created by net/http/httputil.(*ReverseProxy).handleUpgradeResponse
/usr/local/Cellar/go/1.16.6/libexec/src/net/http/httputil/reverseproxy.go:560 +0x51f

rax 0x104
rbx 0xc543e00
rcx 0x7ffeefbfea48
rdx 0x9600
rdi 0x1549be0
rsi 0x960100009700
rbp 0x7ffeefbfeaf0
rsp 0x7ffeefbfea48
r8 0x0
r9 0xa0
r10 0x0
r11 0x246
r12 0x1549ba0
r13 0x16
r14 0x960100009700
r15 0x9600
rip 0x7fff2038ecde
rflags 0x247
cs 0x7
fs 0x0
gs 0x0

And in particular this struck goroutine:

goroutine 136 [sync.Cond.Wait, 6 minutes]:
sync.runtime_notifyListWait(0xc000552cd0, 0x0)
	/usr/local/Cellar/go/1.16.6/libexec/src/runtime/sema.go:513 +0xf8
sync.(*Cond).Wait(0xc000552cc0)
	/usr/local/Cellar/go/1.16.6/libexec/src/sync/cond.go:56 +0x99
net/http.(*connReader).abortPendingRead(0xc000536ff0)
	/usr/local/Cellar/go/1.16.6/libexec/src/net/http/server.go:720 +0xb2
net/http.(*conn).hijackLocked(0xc000532500, 0x0, 0xc000571760, 0x104208e, 0xc000571730, 0x1065760)
	/usr/local/Cellar/go/1.16.6/libexec/src/net/http/server.go:315 +0x53
net/http.(*response).Hijack(0xc00052c540, 0x0, 0x0, 0x0, 0x0, 0x0)
	/usr/local/Cellar/go/1.16.6/libexec/src/net/http/server.go:1999 +0xaa
net/http/httputil.(*ReverseProxy).handleUpgradeResponse(0xc0005345f0, 0x13afd40, 0xc00052c540, 0xc000556900, 0xc00052ed80)
	/usr/local/Cellar/go/1.16.6/libexec/src/net/http/httputil/reverseproxy.go:572 +0x55a
net/http/httputil.(*ReverseProxy).ServeHTTP(0xc0005345f0, 0x13afd40, 0xc00052c540, 0xc000556800)
	/usr/local/Cellar/go/1.16.6/libexec/src/net/http/httputil/reverseproxy.go:295 +0xf97
net/http.serverHandler.ServeHTTP(0xc00052c460, 0x13afd40, 0xc00052c540, 0xc000556800)
	/usr/local/Cellar/go/1.16.6/libexec/src/net/http/server.go:2867 +0xa3
net/http.(*conn).serve(0xc000532500, 0x13b0300, 0xc000552c80)
	/usr/local/Cellar/go/1.16.6/libexec/src/net/http/server.go:1932 +0x8cd
created by net/http.(*Server).Serve
	/usr/local/Cellar/go/1.16.6/libexec/src/net/http/server.go:2993 +0x39b

@seankhliao
Copy link
Member

Your net.Conn implementation has to actually satisfy the behavior described for the interface's methods, not just have stub methods, in particular see #20963 (comment)

@prologic
Copy link
Author

prologic commented Sep 3, 2021

Your net.Conn implementation has to actually satisfy the behavior described for the interface's methods, not just have stub methods, in particular see #20963 (comment)

After much hacking I actually did manage to do exactly that (very ugly though) and ran into another issue resulting in a http: proxy error: flush EOF error. So it's not as simple as just satisfying the interface requirements I'm afraid.

@golang golang locked and limited conversation to collaborators Sep 3, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants