Skip to content

Commit

Permalink
martian: when handling 101 response panic on response read after ucon…
Browse files Browse the repository at this point in the history
…n extraction

The std http package returns the underlying connection in body of 101 response. The response body needs to be removed form the response.
Make reads from the replaced body panic to ensure that it's always handled correctly.
  • Loading branch information
mmatczuk committed Nov 21, 2024
1 parent 5b97b40 commit 4d0dc65
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 4 deletions.
9 changes: 9 additions & 0 deletions internal/martian/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"context"
"crypto/tls"
"errors"
"io"
"net"
"net/http"
"net/url"
Expand Down Expand Up @@ -388,3 +389,11 @@ func upgradeType(h http.Header) string {
}
return h.Get("Upgrade")
}

type panicReader struct{}

func (panicReader) Read(p []byte) (int, error) {
panic("unexpected read")
}

var panicBody = io.NopCloser(panicReader{})
3 changes: 1 addition & 2 deletions internal/martian/proxy_conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,8 +259,7 @@ func (p *proxyConn) handleUpgradeResponse(res *http.Response) error {
log.Errorf(res.Request.Context(), "internal error: switching protocols response with non-writable body")
return errClose
}

res.Body = nil
res.Body = panicBody

if err := p.tunnel(resUpType, res, uconn); err != nil {
log.Errorf(res.Request.Context(), "%s tunnel: %v", resUpType, err)
Expand Down
3 changes: 1 addition & 2 deletions internal/martian/proxy_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,7 @@ func (p proxyHandler) handleUpgradeResponse(rw http.ResponseWriter, req *http.Re
log.Errorf(ctx, "%s tunnel: internal error: switching protocols response with non-ReadWriteCloser body", resUpType)
panic(http.ErrAbortHandler)
}

res.Body = nil
res.Body = panicBody

if err := p.tunnel(resUpType, rw, req, res, uconn); err != nil {
log.Errorf(ctx, "%s tunnel: %v", resUpType, err)
Expand Down

0 comments on commit 4d0dc65

Please sign in to comment.