aboutsummaryrefslogtreecommitdiff
path: root/src/net/http/transport.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/net/http/transport.go')
-rw-r--r--src/net/http/transport.go41
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}
}