diff options
Diffstat (limited to 'internal/proxy/proxy.go')
| -rw-r--r-- | internal/proxy/proxy.go | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/internal/proxy/proxy.go b/internal/proxy/proxy.go index fcf8c14..014c601 100644 --- a/internal/proxy/proxy.go +++ b/internal/proxy/proxy.go @@ -38,6 +38,10 @@ import ( "mitmux/internal/store" ) +// upstreamTimeout bounds the write-request/read-response phase of an +// upstream exchange, once dialing has already succeeded. +const upstreamTimeout = 60 * time.Second + // hopByHopHeaders are stripped before forwarding a request or response, // per RFC 7230 6.1 - they are meaningful only between a client and its // immediate next hop, not end-to-end. @@ -259,6 +263,14 @@ func (s *Server) forward(dial dialer, scheme, hostname string, w http.ResponseWr return } defer conn.Close() + // The dial itself is bounded (net.Dialer.Timeout / HandshakeContext); + // without this, a server that accepts the connection and then never + // writes or never finishes writing would hang the request forever - + // there's no other timeout covering the write-request/read-response + // phase. Bounds the whole exchange, so a legitimately slow multi- + // minute transfer would also get cut off; a fixed default is enough + // for now, not worth a config surface yet. + conn.SetDeadline(time.Now().Add(upstreamTimeout)) var resp *http.Response var upstreamTee *teeConn @@ -299,7 +311,7 @@ func (s *Server) forward(dial dialer, scheme, hostname string, w http.ResponseWr if upstreamTee != nil { respRaw, respExact = upstreamTee.Take(), true } else { - respRaw, respExact = captureResponse(resp, nil, respBodyCap) + respRaw, respExact = captureResponse(resp, respBodyCap) } s.record(started, duration, scheme, hostname, r, reqRaw, reqExact, respRaw, respExact, resp.StatusCode, "") |