diff options
Diffstat (limited to 'src/net/http/transport.go')
-rw-r--r-- | src/net/http/transport.go | 41 |
1 files changed, 34 insertions, 7 deletions
diff --git a/src/net/http/transport.go b/src/net/http/transport.go index b97c4268b5..29d7434f2a 100644 --- a/src/net/http/transport.go +++ b/src/net/http/transport.go @@ -44,7 +44,6 @@ var DefaultTransport RoundTripper = &Transport{ DialContext: (&net.Dialer{ Timeout: 30 * time.Second, KeepAlive: 30 * time.Second, - DualStack: true, }).DialContext, ForceAttemptHTTP2: true, MaxIdleConns: 100, @@ -240,8 +239,18 @@ type Transport struct { // ProxyConnectHeader optionally specifies headers to send to // proxies during CONNECT requests. + // To set the header dynamically, see GetProxyConnectHeader. ProxyConnectHeader Header + // GetProxyConnectHeader optionally specifies a func to return + // headers to send to proxyURL during a CONNECT request to the + // ip:port target. + // If it returns an error, the Transport's RoundTrip fails with + // that error. It can return (nil, nil) to not add headers. + // If GetProxyConnectHeader is non-nil, ProxyConnectHeader is + // ignored. + GetProxyConnectHeader func(ctx context.Context, proxyURL *url.URL, target string) (Header, error) + // MaxResponseHeaderBytes specifies a limit on how many // response bytes are allowed in the server's response // header. @@ -313,6 +322,7 @@ func (t *Transport) Clone() *Transport { ResponseHeaderTimeout: t.ResponseHeaderTimeout, ExpectContinueTimeout: t.ExpectContinueTimeout, ProxyConnectHeader: t.ProxyConnectHeader.Clone(), + GetProxyConnectHeader: t.GetProxyConnectHeader, MaxResponseHeaderBytes: t.MaxResponseHeaderBytes, ForceAttemptHTTP2: t.ForceAttemptHTTP2, WriteBufferSize: t.WriteBufferSize, @@ -613,7 +623,8 @@ var errCannotRewind = errors.New("net/http: cannot rewind body after connection type readTrackingBody struct { io.ReadCloser - didRead bool + didRead bool + didClose bool } func (r *readTrackingBody) Read(data []byte) (int, error) { @@ -621,6 +632,11 @@ func (r *readTrackingBody) Read(data []byte) (int, error) { return r.ReadCloser.Read(data) } +func (r *readTrackingBody) Close() error { + r.didClose = true + return r.ReadCloser.Close() +} + // setupRewindBody returns a new request with a custom body wrapper // that can report whether the body needs rewinding. // This lets rewindBody avoid an error result when the request @@ -639,10 +655,12 @@ func setupRewindBody(req *Request) *Request { // rewindBody takes care of closing req.Body when appropriate // (in all cases except when rewindBody returns req unmodified). func rewindBody(req *Request) (rewound *Request, err error) { - if req.Body == nil || req.Body == NoBody || !req.Body.(*readTrackingBody).didRead { + if req.Body == nil || req.Body == NoBody || (!req.Body.(*readTrackingBody).didRead && !req.Body.(*readTrackingBody).didClose) { return req, nil // nothing to rewind } - req.closeBody() + if !req.Body.(*readTrackingBody).didClose { + req.closeBody() + } if req.GetBody == nil { return nil, errCannotRewind } @@ -1623,7 +1641,17 @@ func (t *Transport) dialConn(ctx context.Context, cm connectMethod) (pconn *pers } case cm.targetScheme == "https": conn := pconn.conn - hdr := t.ProxyConnectHeader + var hdr Header + if t.GetProxyConnectHeader != nil { + var err error + hdr, err = t.GetProxyConnectHeader(ctx, cm.proxyURL, cm.targetAddr) + if err != nil { + conn.Close() + return nil, err + } + } else { + hdr = t.ProxyConnectHeader + } if hdr == nil { hdr = make(Header) } @@ -2359,7 +2387,7 @@ func (pc *persistConn) writeLoop() { // Request.Body are high priority. // Set it here before sending on the // channels below or calling - // pc.close() which tears town + // pc.close() which tears down // connections and causes other // errors. wr.req.setError(err) @@ -2368,7 +2396,6 @@ func (pc *persistConn) writeLoop() { err = pc.bw.Flush() } if err != nil { - wr.req.Request.closeBody() if pc.nwrite == startBytesWritten { err = nothingWrittenError{err} } |