Home | History | Annotate | Download | only in http
      1 // Copyright 2011 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 // HTTP client implementation. See RFC 2616.
      6 //
      7 // This is the low-level Transport implementation of RoundTripper.
      8 // The high-level interface is in client.go.
      9 
     10 package http
     11 
     12 import (
     13 	"bufio"
     14 	"compress/gzip"
     15 	"crypto/tls"
     16 	"errors"
     17 	"fmt"
     18 	"io"
     19 	"log"
     20 	"net"
     21 	"net/url"
     22 	"os"
     23 	"strings"
     24 	"sync"
     25 	"time"
     26 )
     27 
     28 // DefaultTransport is the default implementation of Transport and is
     29 // used by DefaultClient. It establishes network connections as needed
     30 // and caches them for reuse by subsequent calls. It uses HTTP proxies
     31 // as directed by the $HTTP_PROXY and $NO_PROXY (or $http_proxy and
     32 // $no_proxy) environment variables.
     33 var DefaultTransport RoundTripper = &Transport{
     34 	Proxy: ProxyFromEnvironment,
     35 	Dial: (&net.Dialer{
     36 		Timeout:   30 * time.Second,
     37 		KeepAlive: 30 * time.Second,
     38 	}).Dial,
     39 	TLSHandshakeTimeout: 10 * time.Second,
     40 }
     41 
     42 // DefaultMaxIdleConnsPerHost is the default value of Transport's
     43 // MaxIdleConnsPerHost.
     44 const DefaultMaxIdleConnsPerHost = 2
     45 
     46 // Transport is an implementation of RoundTripper that supports HTTP,
     47 // HTTPS, and HTTP proxies (for either HTTP or HTTPS with CONNECT).
     48 // Transport can also cache connections for future re-use.
     49 type Transport struct {
     50 	idleMu     sync.Mutex
     51 	wantIdle   bool // user has requested to close all idle conns
     52 	idleConn   map[connectMethodKey][]*persistConn
     53 	idleConnCh map[connectMethodKey]chan *persistConn
     54 
     55 	reqMu       sync.Mutex
     56 	reqCanceler map[*Request]func()
     57 
     58 	altMu    sync.RWMutex
     59 	altProto map[string]RoundTripper // nil or map of URI scheme => RoundTripper
     60 
     61 	// Proxy specifies a function to return a proxy for a given
     62 	// Request. If the function returns a non-nil error, the
     63 	// request is aborted with the provided error.
     64 	// If Proxy is nil or returns a nil *URL, no proxy is used.
     65 	Proxy func(*Request) (*url.URL, error)
     66 
     67 	// Dial specifies the dial function for creating unencrypted
     68 	// TCP connections.
     69 	// If Dial is nil, net.Dial is used.
     70 	Dial func(network, addr string) (net.Conn, error)
     71 
     72 	// DialTLS specifies an optional dial function for creating
     73 	// TLS connections for non-proxied HTTPS requests.
     74 	//
     75 	// If DialTLS is nil, Dial and TLSClientConfig are used.
     76 	//
     77 	// If DialTLS is set, the Dial hook is not used for HTTPS
     78 	// requests and the TLSClientConfig and TLSHandshakeTimeout
     79 	// are ignored. The returned net.Conn is assumed to already be
     80 	// past the TLS handshake.
     81 	DialTLS func(network, addr string) (net.Conn, error)
     82 
     83 	// TLSClientConfig specifies the TLS configuration to use with
     84 	// tls.Client. If nil, the default configuration is used.
     85 	TLSClientConfig *tls.Config
     86 
     87 	// TLSHandshakeTimeout specifies the maximum amount of time waiting to
     88 	// wait for a TLS handshake. Zero means no timeout.
     89 	TLSHandshakeTimeout time.Duration
     90 
     91 	// DisableKeepAlives, if true, prevents re-use of TCP connections
     92 	// between different HTTP requests.
     93 	DisableKeepAlives bool
     94 
     95 	// DisableCompression, if true, prevents the Transport from
     96 	// requesting compression with an "Accept-Encoding: gzip"
     97 	// request header when the Request contains no existing
     98 	// Accept-Encoding value. If the Transport requests gzip on
     99 	// its own and gets a gzipped response, it's transparently
    100 	// decoded in the Response.Body. However, if the user
    101 	// explicitly requested gzip it is not automatically
    102 	// uncompressed.
    103 	DisableCompression bool
    104 
    105 	// MaxIdleConnsPerHost, if non-zero, controls the maximum idle
    106 	// (keep-alive) to keep per-host.  If zero,
    107 	// DefaultMaxIdleConnsPerHost is used.
    108 	MaxIdleConnsPerHost int
    109 
    110 	// ResponseHeaderTimeout, if non-zero, specifies the amount of
    111 	// time to wait for a server's response headers after fully
    112 	// writing the request (including its body, if any). This
    113 	// time does not include the time to read the response body.
    114 	ResponseHeaderTimeout time.Duration
    115 
    116 	// TODO: tunable on global max cached connections
    117 	// TODO: tunable on timeout on cached connections
    118 }
    119 
    120 // ProxyFromEnvironment returns the URL of the proxy to use for a
    121 // given request, as indicated by the environment variables
    122 // HTTP_PROXY, HTTPS_PROXY and NO_PROXY (or the lowercase versions
    123 // thereof). HTTPS_PROXY takes precedence over HTTP_PROXY for https
    124 // requests.
    125 //
    126 // The environment values may be either a complete URL or a
    127 // "host[:port]", in which case the "http" scheme is assumed.
    128 // An error is returned if the value is a different form.
    129 //
    130 // A nil URL and nil error are returned if no proxy is defined in the
    131 // environment, or a proxy should not be used for the given request,
    132 // as defined by NO_PROXY.
    133 //
    134 // As a special case, if req.URL.Host is "localhost" (with or without
    135 // a port number), then a nil URL and nil error will be returned.
    136 func ProxyFromEnvironment(req *Request) (*url.URL, error) {
    137 	var proxy string
    138 	if req.URL.Scheme == "https" {
    139 		proxy = httpsProxyEnv.Get()
    140 	}
    141 	if proxy == "" {
    142 		proxy = httpProxyEnv.Get()
    143 	}
    144 	if proxy == "" {
    145 		return nil, nil
    146 	}
    147 	if !useProxy(canonicalAddr(req.URL)) {
    148 		return nil, nil
    149 	}
    150 	proxyURL, err := url.Parse(proxy)
    151 	if err != nil || !strings.HasPrefix(proxyURL.Scheme, "http") {
    152 		// proxy was bogus. Try prepending "http://" to it and
    153 		// see if that parses correctly. If not, we fall
    154 		// through and complain about the original one.
    155 		if proxyURL, err := url.Parse("http://" + proxy); err == nil {
    156 			return proxyURL, nil
    157 		}
    158 	}
    159 	if err != nil {
    160 		return nil, fmt.Errorf("invalid proxy address %q: %v", proxy, err)
    161 	}
    162 	return proxyURL, nil
    163 }
    164 
    165 // ProxyURL returns a proxy function (for use in a Transport)
    166 // that always returns the same URL.
    167 func ProxyURL(fixedURL *url.URL) func(*Request) (*url.URL, error) {
    168 	return func(*Request) (*url.URL, error) {
    169 		return fixedURL, nil
    170 	}
    171 }
    172 
    173 // transportRequest is a wrapper around a *Request that adds
    174 // optional extra headers to write.
    175 type transportRequest struct {
    176 	*Request        // original request, not to be mutated
    177 	extra    Header // extra headers to write, or nil
    178 }
    179 
    180 func (tr *transportRequest) extraHeaders() Header {
    181 	if tr.extra == nil {
    182 		tr.extra = make(Header)
    183 	}
    184 	return tr.extra
    185 }
    186 
    187 // RoundTrip implements the RoundTripper interface.
    188 //
    189 // For higher-level HTTP client support (such as handling of cookies
    190 // and redirects), see Get, Post, and the Client type.
    191 func (t *Transport) RoundTrip(req *Request) (resp *Response, err error) {
    192 	if req.URL == nil {
    193 		req.closeBody()
    194 		return nil, errors.New("http: nil Request.URL")
    195 	}
    196 	if req.Header == nil {
    197 		req.closeBody()
    198 		return nil, errors.New("http: nil Request.Header")
    199 	}
    200 	if req.URL.Scheme != "http" && req.URL.Scheme != "https" {
    201 		t.altMu.RLock()
    202 		var rt RoundTripper
    203 		if t.altProto != nil {
    204 			rt = t.altProto[req.URL.Scheme]
    205 		}
    206 		t.altMu.RUnlock()
    207 		if rt == nil {
    208 			req.closeBody()
    209 			return nil, &badStringError{"unsupported protocol scheme", req.URL.Scheme}
    210 		}
    211 		return rt.RoundTrip(req)
    212 	}
    213 	if req.URL.Host == "" {
    214 		req.closeBody()
    215 		return nil, errors.New("http: no Host in request URL")
    216 	}
    217 	treq := &transportRequest{Request: req}
    218 	cm, err := t.connectMethodForRequest(treq)
    219 	if err != nil {
    220 		req.closeBody()
    221 		return nil, err
    222 	}
    223 
    224 	// Get the cached or newly-created connection to either the
    225 	// host (for http or https), the http proxy, or the http proxy
    226 	// pre-CONNECTed to https server.  In any case, we'll be ready
    227 	// to send it requests.
    228 	pconn, err := t.getConn(req, cm)
    229 	if err != nil {
    230 		t.setReqCanceler(req, nil)
    231 		req.closeBody()
    232 		return nil, err
    233 	}
    234 
    235 	return pconn.roundTrip(treq)
    236 }
    237 
    238 // RegisterProtocol registers a new protocol with scheme.
    239 // The Transport will pass requests using the given scheme to rt.
    240 // It is rt's responsibility to simulate HTTP request semantics.
    241 //
    242 // RegisterProtocol can be used by other packages to provide
    243 // implementations of protocol schemes like "ftp" or "file".
    244 func (t *Transport) RegisterProtocol(scheme string, rt RoundTripper) {
    245 	if scheme == "http" || scheme == "https" {
    246 		panic("protocol " + scheme + " already registered")
    247 	}
    248 	t.altMu.Lock()
    249 	defer t.altMu.Unlock()
    250 	if t.altProto == nil {
    251 		t.altProto = make(map[string]RoundTripper)
    252 	}
    253 	if _, exists := t.altProto[scheme]; exists {
    254 		panic("protocol " + scheme + " already registered")
    255 	}
    256 	t.altProto[scheme] = rt
    257 }
    258 
    259 // CloseIdleConnections closes any connections which were previously
    260 // connected from previous requests but are now sitting idle in
    261 // a "keep-alive" state. It does not interrupt any connections currently
    262 // in use.
    263 func (t *Transport) CloseIdleConnections() {
    264 	t.idleMu.Lock()
    265 	m := t.idleConn
    266 	t.idleConn = nil
    267 	t.idleConnCh = nil
    268 	t.wantIdle = true
    269 	t.idleMu.Unlock()
    270 	for _, conns := range m {
    271 		for _, pconn := range conns {
    272 			pconn.close()
    273 		}
    274 	}
    275 }
    276 
    277 // CancelRequest cancels an in-flight request by closing its connection.
    278 // CancelRequest should only be called after RoundTrip has returned.
    279 func (t *Transport) CancelRequest(req *Request) {
    280 	t.reqMu.Lock()
    281 	cancel := t.reqCanceler[req]
    282 	delete(t.reqCanceler, req)
    283 	t.reqMu.Unlock()
    284 	if cancel != nil {
    285 		cancel()
    286 	}
    287 }
    288 
    289 //
    290 // Private implementation past this point.
    291 //
    292 
    293 var (
    294 	httpProxyEnv = &envOnce{
    295 		names: []string{"HTTP_PROXY", "http_proxy"},
    296 	}
    297 	httpsProxyEnv = &envOnce{
    298 		names: []string{"HTTPS_PROXY", "https_proxy"},
    299 	}
    300 	noProxyEnv = &envOnce{
    301 		names: []string{"NO_PROXY", "no_proxy"},
    302 	}
    303 )
    304 
    305 // envOnce looks up an environment variable (optionally by multiple
    306 // names) once. It mitigates expensive lookups on some platforms
    307 // (e.g. Windows).
    308 type envOnce struct {
    309 	names []string
    310 	once  sync.Once
    311 	val   string
    312 }
    313 
    314 func (e *envOnce) Get() string {
    315 	e.once.Do(e.init)
    316 	return e.val
    317 }
    318 
    319 func (e *envOnce) init() {
    320 	for _, n := range e.names {
    321 		e.val = os.Getenv(n)
    322 		if e.val != "" {
    323 			return
    324 		}
    325 	}
    326 }
    327 
    328 // reset is used by tests
    329 func (e *envOnce) reset() {
    330 	e.once = sync.Once{}
    331 	e.val = ""
    332 }
    333 
    334 func (t *Transport) connectMethodForRequest(treq *transportRequest) (cm connectMethod, err error) {
    335 	cm.targetScheme = treq.URL.Scheme
    336 	cm.targetAddr = canonicalAddr(treq.URL)
    337 	if t.Proxy != nil {
    338 		cm.proxyURL, err = t.Proxy(treq.Request)
    339 	}
    340 	return cm, err
    341 }
    342 
    343 // proxyAuth returns the Proxy-Authorization header to set
    344 // on requests, if applicable.
    345 func (cm *connectMethod) proxyAuth() string {
    346 	if cm.proxyURL == nil {
    347 		return ""
    348 	}
    349 	if u := cm.proxyURL.User; u != nil {
    350 		username := u.Username()
    351 		password, _ := u.Password()
    352 		return "Basic " + basicAuth(username, password)
    353 	}
    354 	return ""
    355 }
    356 
    357 // putIdleConn adds pconn to the list of idle persistent connections awaiting
    358 // a new request.
    359 // If pconn is no longer needed or not in a good state, putIdleConn
    360 // returns false.
    361 func (t *Transport) putIdleConn(pconn *persistConn) bool {
    362 	if t.DisableKeepAlives || t.MaxIdleConnsPerHost < 0 {
    363 		pconn.close()
    364 		return false
    365 	}
    366 	if pconn.isBroken() {
    367 		return false
    368 	}
    369 	key := pconn.cacheKey
    370 	max := t.MaxIdleConnsPerHost
    371 	if max == 0 {
    372 		max = DefaultMaxIdleConnsPerHost
    373 	}
    374 	t.idleMu.Lock()
    375 
    376 	waitingDialer := t.idleConnCh[key]
    377 	select {
    378 	case waitingDialer <- pconn:
    379 		// We're done with this pconn and somebody else is
    380 		// currently waiting for a conn of this type (they're
    381 		// actively dialing, but this conn is ready
    382 		// first). Chrome calls this socket late binding.  See
    383 		// https://insouciant.org/tech/connection-management-in-chromium/
    384 		t.idleMu.Unlock()
    385 		return true
    386 	default:
    387 		if waitingDialer != nil {
    388 			// They had populated this, but their dial won
    389 			// first, so we can clean up this map entry.
    390 			delete(t.idleConnCh, key)
    391 		}
    392 	}
    393 	if t.wantIdle {
    394 		t.idleMu.Unlock()
    395 		pconn.close()
    396 		return false
    397 	}
    398 	if t.idleConn == nil {
    399 		t.idleConn = make(map[connectMethodKey][]*persistConn)
    400 	}
    401 	if len(t.idleConn[key]) >= max {
    402 		t.idleMu.Unlock()
    403 		pconn.close()
    404 		return false
    405 	}
    406 	for _, exist := range t.idleConn[key] {
    407 		if exist == pconn {
    408 			log.Fatalf("dup idle pconn %p in freelist", pconn)
    409 		}
    410 	}
    411 	t.idleConn[key] = append(t.idleConn[key], pconn)
    412 	t.idleMu.Unlock()
    413 	return true
    414 }
    415 
    416 // getIdleConnCh returns a channel to receive and return idle
    417 // persistent connection for the given connectMethod.
    418 // It may return nil, if persistent connections are not being used.
    419 func (t *Transport) getIdleConnCh(cm connectMethod) chan *persistConn {
    420 	if t.DisableKeepAlives {
    421 		return nil
    422 	}
    423 	key := cm.key()
    424 	t.idleMu.Lock()
    425 	defer t.idleMu.Unlock()
    426 	t.wantIdle = false
    427 	if t.idleConnCh == nil {
    428 		t.idleConnCh = make(map[connectMethodKey]chan *persistConn)
    429 	}
    430 	ch, ok := t.idleConnCh[key]
    431 	if !ok {
    432 		ch = make(chan *persistConn)
    433 		t.idleConnCh[key] = ch
    434 	}
    435 	return ch
    436 }
    437 
    438 func (t *Transport) getIdleConn(cm connectMethod) (pconn *persistConn) {
    439 	key := cm.key()
    440 	t.idleMu.Lock()
    441 	defer t.idleMu.Unlock()
    442 	if t.idleConn == nil {
    443 		return nil
    444 	}
    445 	for {
    446 		pconns, ok := t.idleConn[key]
    447 		if !ok {
    448 			return nil
    449 		}
    450 		if len(pconns) == 1 {
    451 			pconn = pconns[0]
    452 			delete(t.idleConn, key)
    453 		} else {
    454 			// 2 or more cached connections; pop last
    455 			// TODO: queue?
    456 			pconn = pconns[len(pconns)-1]
    457 			t.idleConn[key] = pconns[:len(pconns)-1]
    458 		}
    459 		if !pconn.isBroken() {
    460 			return
    461 		}
    462 	}
    463 }
    464 
    465 func (t *Transport) setReqCanceler(r *Request, fn func()) {
    466 	t.reqMu.Lock()
    467 	defer t.reqMu.Unlock()
    468 	if t.reqCanceler == nil {
    469 		t.reqCanceler = make(map[*Request]func())
    470 	}
    471 	if fn != nil {
    472 		t.reqCanceler[r] = fn
    473 	} else {
    474 		delete(t.reqCanceler, r)
    475 	}
    476 }
    477 
    478 // replaceReqCanceler replaces an existing cancel function. If there is no cancel function
    479 // for the request, we don't set the function and return false.
    480 // Since CancelRequest will clear the canceler, we can use the return value to detect if
    481 // the request was canceled since the last setReqCancel call.
    482 func (t *Transport) replaceReqCanceler(r *Request, fn func()) bool {
    483 	t.reqMu.Lock()
    484 	defer t.reqMu.Unlock()
    485 	_, ok := t.reqCanceler[r]
    486 	if !ok {
    487 		return false
    488 	}
    489 	if fn != nil {
    490 		t.reqCanceler[r] = fn
    491 	} else {
    492 		delete(t.reqCanceler, r)
    493 	}
    494 	return true
    495 }
    496 
    497 func (t *Transport) dial(network, addr string) (c net.Conn, err error) {
    498 	if t.Dial != nil {
    499 		return t.Dial(network, addr)
    500 	}
    501 	return net.Dial(network, addr)
    502 }
    503 
    504 // Testing hooks:
    505 var prePendingDial, postPendingDial func()
    506 
    507 // getConn dials and creates a new persistConn to the target as
    508 // specified in the connectMethod.  This includes doing a proxy CONNECT
    509 // and/or setting up TLS.  If this doesn't return an error, the persistConn
    510 // is ready to write requests to.
    511 func (t *Transport) getConn(req *Request, cm connectMethod) (*persistConn, error) {
    512 	if pc := t.getIdleConn(cm); pc != nil {
    513 		// set request canceler to some non-nil function so we
    514 		// can detect whether it was cleared between now and when
    515 		// we enter roundTrip
    516 		t.setReqCanceler(req, func() {})
    517 		return pc, nil
    518 	}
    519 
    520 	type dialRes struct {
    521 		pc  *persistConn
    522 		err error
    523 	}
    524 	dialc := make(chan dialRes)
    525 
    526 	// Copy these hooks so we don't race on the postPendingDial in
    527 	// the goroutine we launch. Issue 11136.
    528 	prePendingDial := prePendingDial
    529 	postPendingDial := postPendingDial
    530 
    531 	handlePendingDial := func() {
    532 		if prePendingDial != nil {
    533 			prePendingDial()
    534 		}
    535 		go func() {
    536 			if v := <-dialc; v.err == nil {
    537 				t.putIdleConn(v.pc)
    538 			}
    539 			if postPendingDial != nil {
    540 				postPendingDial()
    541 			}
    542 		}()
    543 	}
    544 
    545 	cancelc := make(chan struct{})
    546 	t.setReqCanceler(req, func() { close(cancelc) })
    547 
    548 	go func() {
    549 		pc, err := t.dialConn(cm)
    550 		dialc <- dialRes{pc, err}
    551 	}()
    552 
    553 	idleConnCh := t.getIdleConnCh(cm)
    554 	select {
    555 	case v := <-dialc:
    556 		// Our dial finished.
    557 		return v.pc, v.err
    558 	case pc := <-idleConnCh:
    559 		// Another request finished first and its net.Conn
    560 		// became available before our dial. Or somebody
    561 		// else's dial that they didn't use.
    562 		// But our dial is still going, so give it away
    563 		// when it finishes:
    564 		handlePendingDial()
    565 		return pc, nil
    566 	case <-req.Cancel:
    567 		handlePendingDial()
    568 		return nil, errors.New("net/http: request canceled while waiting for connection")
    569 	case <-cancelc:
    570 		handlePendingDial()
    571 		return nil, errors.New("net/http: request canceled while waiting for connection")
    572 	}
    573 }
    574 
    575 func (t *Transport) dialConn(cm connectMethod) (*persistConn, error) {
    576 	pconn := &persistConn{
    577 		t:          t,
    578 		cacheKey:   cm.key(),
    579 		reqch:      make(chan requestAndChan, 1),
    580 		writech:    make(chan writeRequest, 1),
    581 		closech:    make(chan struct{}),
    582 		writeErrCh: make(chan error, 1),
    583 	}
    584 	tlsDial := t.DialTLS != nil && cm.targetScheme == "https" && cm.proxyURL == nil
    585 	if tlsDial {
    586 		var err error
    587 		pconn.conn, err = t.DialTLS("tcp", cm.addr())
    588 		if err != nil {
    589 			return nil, err
    590 		}
    591 		if tc, ok := pconn.conn.(*tls.Conn); ok {
    592 			cs := tc.ConnectionState()
    593 			pconn.tlsState = &cs
    594 		}
    595 	} else {
    596 		conn, err := t.dial("tcp", cm.addr())
    597 		if err != nil {
    598 			if cm.proxyURL != nil {
    599 				err = fmt.Errorf("http: error connecting to proxy %s: %v", cm.proxyURL, err)
    600 			}
    601 			return nil, err
    602 		}
    603 		pconn.conn = conn
    604 	}
    605 
    606 	// Proxy setup.
    607 	switch {
    608 	case cm.proxyURL == nil:
    609 		// Do nothing. Not using a proxy.
    610 	case cm.targetScheme == "http":
    611 		pconn.isProxy = true
    612 		if pa := cm.proxyAuth(); pa != "" {
    613 			pconn.mutateHeaderFunc = func(h Header) {
    614 				h.Set("Proxy-Authorization", pa)
    615 			}
    616 		}
    617 	case cm.targetScheme == "https":
    618 		conn := pconn.conn
    619 		connectReq := &Request{
    620 			Method: "CONNECT",
    621 			URL:    &url.URL{Opaque: cm.targetAddr},
    622 			Host:   cm.targetAddr,
    623 			Header: make(Header),
    624 		}
    625 		if pa := cm.proxyAuth(); pa != "" {
    626 			connectReq.Header.Set("Proxy-Authorization", pa)
    627 		}
    628 		connectReq.Write(conn)
    629 
    630 		// Read response.
    631 		// Okay to use and discard buffered reader here, because
    632 		// TLS server will not speak until spoken to.
    633 		br := bufio.NewReader(conn)
    634 		resp, err := ReadResponse(br, connectReq)
    635 		if err != nil {
    636 			conn.Close()
    637 			return nil, err
    638 		}
    639 		if resp.StatusCode != 200 {
    640 			f := strings.SplitN(resp.Status, " ", 2)
    641 			conn.Close()
    642 			return nil, errors.New(f[1])
    643 		}
    644 	}
    645 
    646 	if cm.targetScheme == "https" && !tlsDial {
    647 		// Initiate TLS and check remote host name against certificate.
    648 		cfg := cloneTLSClientConfig(t.TLSClientConfig)
    649 		if cfg.ServerName == "" {
    650 			cfg.ServerName = cm.tlsHost()
    651 		}
    652 		plainConn := pconn.conn
    653 		tlsConn := tls.Client(plainConn, cfg)
    654 		errc := make(chan error, 2)
    655 		var timer *time.Timer // for canceling TLS handshake
    656 		if d := t.TLSHandshakeTimeout; d != 0 {
    657 			timer = time.AfterFunc(d, func() {
    658 				errc <- tlsHandshakeTimeoutError{}
    659 			})
    660 		}
    661 		go func() {
    662 			err := tlsConn.Handshake()
    663 			if timer != nil {
    664 				timer.Stop()
    665 			}
    666 			errc <- err
    667 		}()
    668 		if err := <-errc; err != nil {
    669 			plainConn.Close()
    670 			return nil, err
    671 		}
    672 		if !cfg.InsecureSkipVerify {
    673 			if err := tlsConn.VerifyHostname(cfg.ServerName); err != nil {
    674 				plainConn.Close()
    675 				return nil, err
    676 			}
    677 		}
    678 		cs := tlsConn.ConnectionState()
    679 		pconn.tlsState = &cs
    680 		pconn.conn = tlsConn
    681 	}
    682 
    683 	pconn.br = bufio.NewReader(noteEOFReader{pconn.conn, &pconn.sawEOF})
    684 	pconn.bw = bufio.NewWriter(pconn.conn)
    685 	go pconn.readLoop()
    686 	go pconn.writeLoop()
    687 	return pconn, nil
    688 }
    689 
    690 // useProxy reports whether requests to addr should use a proxy,
    691 // according to the NO_PROXY or no_proxy environment variable.
    692 // addr is always a canonicalAddr with a host and port.
    693 func useProxy(addr string) bool {
    694 	if len(addr) == 0 {
    695 		return true
    696 	}
    697 	host, _, err := net.SplitHostPort(addr)
    698 	if err != nil {
    699 		return false
    700 	}
    701 	if host == "localhost" {
    702 		return false
    703 	}
    704 	if ip := net.ParseIP(host); ip != nil {
    705 		if ip.IsLoopback() {
    706 			return false
    707 		}
    708 	}
    709 
    710 	no_proxy := noProxyEnv.Get()
    711 	if no_proxy == "*" {
    712 		return false
    713 	}
    714 
    715 	addr = strings.ToLower(strings.TrimSpace(addr))
    716 	if hasPort(addr) {
    717 		addr = addr[:strings.LastIndex(addr, ":")]
    718 	}
    719 
    720 	for _, p := range strings.Split(no_proxy, ",") {
    721 		p = strings.ToLower(strings.TrimSpace(p))
    722 		if len(p) == 0 {
    723 			continue
    724 		}
    725 		if hasPort(p) {
    726 			p = p[:strings.LastIndex(p, ":")]
    727 		}
    728 		if addr == p {
    729 			return false
    730 		}
    731 		if p[0] == '.' && (strings.HasSuffix(addr, p) || addr == p[1:]) {
    732 			// no_proxy ".foo.com" matches "bar.foo.com" or "foo.com"
    733 			return false
    734 		}
    735 		if p[0] != '.' && strings.HasSuffix(addr, p) && addr[len(addr)-len(p)-1] == '.' {
    736 			// no_proxy "foo.com" matches "bar.foo.com"
    737 			return false
    738 		}
    739 	}
    740 	return true
    741 }
    742 
    743 // connectMethod is the map key (in its String form) for keeping persistent
    744 // TCP connections alive for subsequent HTTP requests.
    745 //
    746 // A connect method may be of the following types:
    747 //
    748 // Cache key form                Description
    749 // -----------------             -------------------------
    750 // |http|foo.com                 http directly to server, no proxy
    751 // |https|foo.com                https directly to server, no proxy
    752 // http://proxy.com|https|foo.com  http to proxy, then CONNECT to foo.com
    753 // http://proxy.com|http           http to proxy, http to anywhere after that
    754 //
    755 // Note: no support to https to the proxy yet.
    756 //
    757 type connectMethod struct {
    758 	proxyURL     *url.URL // nil for no proxy, else full proxy URL
    759 	targetScheme string   // "http" or "https"
    760 	targetAddr   string   // Not used if proxy + http targetScheme (4th example in table)
    761 }
    762 
    763 func (cm *connectMethod) key() connectMethodKey {
    764 	proxyStr := ""
    765 	targetAddr := cm.targetAddr
    766 	if cm.proxyURL != nil {
    767 		proxyStr = cm.proxyURL.String()
    768 		if cm.targetScheme == "http" {
    769 			targetAddr = ""
    770 		}
    771 	}
    772 	return connectMethodKey{
    773 		proxy:  proxyStr,
    774 		scheme: cm.targetScheme,
    775 		addr:   targetAddr,
    776 	}
    777 }
    778 
    779 // addr returns the first hop "host:port" to which we need to TCP connect.
    780 func (cm *connectMethod) addr() string {
    781 	if cm.proxyURL != nil {
    782 		return canonicalAddr(cm.proxyURL)
    783 	}
    784 	return cm.targetAddr
    785 }
    786 
    787 // tlsHost returns the host name to match against the peer's
    788 // TLS certificate.
    789 func (cm *connectMethod) tlsHost() string {
    790 	h := cm.targetAddr
    791 	if hasPort(h) {
    792 		h = h[:strings.LastIndex(h, ":")]
    793 	}
    794 	return h
    795 }
    796 
    797 // connectMethodKey is the map key version of connectMethod, with a
    798 // stringified proxy URL (or the empty string) instead of a pointer to
    799 // a URL.
    800 type connectMethodKey struct {
    801 	proxy, scheme, addr string
    802 }
    803 
    804 func (k connectMethodKey) String() string {
    805 	// Only used by tests.
    806 	return fmt.Sprintf("%s|%s|%s", k.proxy, k.scheme, k.addr)
    807 }
    808 
    809 // persistConn wraps a connection, usually a persistent one
    810 // (but may be used for non-keep-alive requests as well)
    811 type persistConn struct {
    812 	t        *Transport
    813 	cacheKey connectMethodKey
    814 	conn     net.Conn
    815 	tlsState *tls.ConnectionState
    816 	br       *bufio.Reader       // from conn
    817 	sawEOF   bool                // whether we've seen EOF from conn; owned by readLoop
    818 	bw       *bufio.Writer       // to conn
    819 	reqch    chan requestAndChan // written by roundTrip; read by readLoop
    820 	writech  chan writeRequest   // written by roundTrip; read by writeLoop
    821 	closech  chan struct{}       // closed when conn closed
    822 	isProxy  bool
    823 	// writeErrCh passes the request write error (usually nil)
    824 	// from the writeLoop goroutine to the readLoop which passes
    825 	// it off to the res.Body reader, which then uses it to decide
    826 	// whether or not a connection can be reused. Issue 7569.
    827 	writeErrCh chan error
    828 
    829 	lk                   sync.Mutex // guards following fields
    830 	numExpectedResponses int
    831 	closed               bool // whether conn has been closed
    832 	broken               bool // an error has happened on this connection; marked broken so it's not reused.
    833 	canceled             bool // whether this conn was broken due a CancelRequest
    834 	// mutateHeaderFunc is an optional func to modify extra
    835 	// headers on each outbound request before it's written. (the
    836 	// original Request given to RoundTrip is not modified)
    837 	mutateHeaderFunc func(Header)
    838 }
    839 
    840 // isBroken reports whether this connection is in a known broken state.
    841 func (pc *persistConn) isBroken() bool {
    842 	pc.lk.Lock()
    843 	b := pc.broken
    844 	pc.lk.Unlock()
    845 	return b
    846 }
    847 
    848 // isCanceled reports whether this connection was closed due to CancelRequest.
    849 func (pc *persistConn) isCanceled() bool {
    850 	pc.lk.Lock()
    851 	defer pc.lk.Unlock()
    852 	return pc.canceled
    853 }
    854 
    855 func (pc *persistConn) cancelRequest() {
    856 	pc.lk.Lock()
    857 	defer pc.lk.Unlock()
    858 	pc.canceled = true
    859 	pc.closeLocked()
    860 }
    861 
    862 func (pc *persistConn) readLoop() {
    863 	// eofc is used to block http.Handler goroutines reading from Response.Body
    864 	// at EOF until this goroutines has (potentially) added the connection
    865 	// back to the idle pool.
    866 	eofc := make(chan struct{})
    867 	defer close(eofc) // unblock reader on errors
    868 
    869 	// Read this once, before loop starts. (to avoid races in tests)
    870 	testHookMu.Lock()
    871 	testHookReadLoopBeforeNextRead := testHookReadLoopBeforeNextRead
    872 	testHookMu.Unlock()
    873 
    874 	alive := true
    875 	for alive {
    876 		pb, err := pc.br.Peek(1)
    877 
    878 		pc.lk.Lock()
    879 		if pc.numExpectedResponses == 0 {
    880 			if !pc.closed {
    881 				pc.closeLocked()
    882 				if len(pb) > 0 {
    883 					log.Printf("Unsolicited response received on idle HTTP channel starting with %q; err=%v",
    884 						string(pb), err)
    885 				}
    886 			}
    887 			pc.lk.Unlock()
    888 			return
    889 		}
    890 		pc.lk.Unlock()
    891 
    892 		rc := <-pc.reqch
    893 
    894 		var resp *Response
    895 		if err == nil {
    896 			resp, err = ReadResponse(pc.br, rc.req)
    897 			if err == nil && resp.StatusCode == 100 {
    898 				// Skip any 100-continue for now.
    899 				// TODO(bradfitz): if rc.req had "Expect: 100-continue",
    900 				// actually block the request body write and signal the
    901 				// writeLoop now to begin sending it. (Issue 2184) For now we
    902 				// eat it, since we're never expecting one.
    903 				resp, err = ReadResponse(pc.br, rc.req)
    904 			}
    905 		}
    906 
    907 		if resp != nil {
    908 			resp.TLS = pc.tlsState
    909 		}
    910 
    911 		hasBody := resp != nil && rc.req.Method != "HEAD" && resp.ContentLength != 0
    912 
    913 		if err != nil {
    914 			pc.close()
    915 		} else {
    916 			if rc.addedGzip && hasBody && resp.Header.Get("Content-Encoding") == "gzip" {
    917 				resp.Header.Del("Content-Encoding")
    918 				resp.Header.Del("Content-Length")
    919 				resp.ContentLength = -1
    920 				resp.Body = &gzipReader{body: resp.Body}
    921 			}
    922 			resp.Body = &bodyEOFSignal{body: resp.Body}
    923 		}
    924 
    925 		if err != nil || resp.Close || rc.req.Close || resp.StatusCode <= 199 {
    926 			// Don't do keep-alive on error if either party requested a close
    927 			// or we get an unexpected informational (1xx) response.
    928 			// StatusCode 100 is already handled above.
    929 			alive = false
    930 		}
    931 
    932 		var waitForBodyRead chan bool // channel is nil when there's no body
    933 		if hasBody {
    934 			waitForBodyRead = make(chan bool, 2)
    935 			resp.Body.(*bodyEOFSignal).earlyCloseFn = func() error {
    936 				waitForBodyRead <- false
    937 				return nil
    938 			}
    939 			resp.Body.(*bodyEOFSignal).fn = func(err error) error {
    940 				isEOF := err == io.EOF
    941 				waitForBodyRead <- isEOF
    942 				if isEOF {
    943 					<-eofc // see comment at top
    944 				} else if err != nil && pc.isCanceled() {
    945 					return errRequestCanceled
    946 				}
    947 				return err
    948 			}
    949 		} else {
    950 			// Before send on rc.ch, as client might re-use the
    951 			// same *Request pointer, and we don't want to set this
    952 			// on t from this persistConn while the Transport
    953 			// potentially spins up a different persistConn for the
    954 			// caller's subsequent request.
    955 			pc.t.setReqCanceler(rc.req, nil)
    956 		}
    957 
    958 		pc.lk.Lock()
    959 		pc.numExpectedResponses--
    960 		pc.lk.Unlock()
    961 
    962 		// The connection might be going away when we put the
    963 		// idleConn below. When that happens, we close the response channel to signal
    964 		// to roundTrip that the connection is gone. roundTrip waits for
    965 		// both closing and a response in a select, so it might choose
    966 		// the close channel, rather than the response.
    967 		// We send the response first so that roundTrip can check
    968 		// if there is a pending one with a non-blocking select
    969 		// on the response channel before erroring out.
    970 		rc.ch <- responseAndError{resp, err}
    971 
    972 		if hasBody {
    973 			// To avoid a race, wait for the just-returned
    974 			// response body to be fully consumed before peek on
    975 			// the underlying bufio reader.
    976 			select {
    977 			case <-rc.req.Cancel:
    978 				alive = false
    979 				pc.t.CancelRequest(rc.req)
    980 			case bodyEOF := <-waitForBodyRead:
    981 				pc.t.setReqCanceler(rc.req, nil) // before pc might return to idle pool
    982 				alive = alive &&
    983 					bodyEOF &&
    984 					!pc.sawEOF &&
    985 					pc.wroteRequest() &&
    986 					pc.t.putIdleConn(pc)
    987 				if bodyEOF {
    988 					eofc <- struct{}{}
    989 				}
    990 			case <-pc.closech:
    991 				alive = false
    992 			}
    993 		} else {
    994 			alive = alive &&
    995 				!pc.sawEOF &&
    996 				pc.wroteRequest() &&
    997 				pc.t.putIdleConn(pc)
    998 		}
    999 
   1000 		if hook := testHookReadLoopBeforeNextRead; hook != nil {
   1001 			hook()
   1002 		}
   1003 	}
   1004 	pc.close()
   1005 }
   1006 
   1007 func (pc *persistConn) writeLoop() {
   1008 	for {
   1009 		select {
   1010 		case wr := <-pc.writech:
   1011 			if pc.isBroken() {
   1012 				wr.ch <- errors.New("http: can't write HTTP request on broken connection")
   1013 				continue
   1014 			}
   1015 			err := wr.req.Request.write(pc.bw, pc.isProxy, wr.req.extra)
   1016 			if err == nil {
   1017 				err = pc.bw.Flush()
   1018 			}
   1019 			if err != nil {
   1020 				pc.markBroken()
   1021 				wr.req.Request.closeBody()
   1022 			}
   1023 			pc.writeErrCh <- err // to the body reader, which might recycle us
   1024 			wr.ch <- err         // to the roundTrip function
   1025 		case <-pc.closech:
   1026 			return
   1027 		}
   1028 	}
   1029 }
   1030 
   1031 // wroteRequest is a check before recycling a connection that the previous write
   1032 // (from writeLoop above) happened and was successful.
   1033 func (pc *persistConn) wroteRequest() bool {
   1034 	select {
   1035 	case err := <-pc.writeErrCh:
   1036 		// Common case: the write happened well before the response, so
   1037 		// avoid creating a timer.
   1038 		return err == nil
   1039 	default:
   1040 		// Rare case: the request was written in writeLoop above but
   1041 		// before it could send to pc.writeErrCh, the reader read it
   1042 		// all, processed it, and called us here. In this case, give the
   1043 		// write goroutine a bit of time to finish its send.
   1044 		//
   1045 		// Less rare case: We also get here in the legitimate case of
   1046 		// Issue 7569, where the writer is still writing (or stalled),
   1047 		// but the server has already replied. In this case, we don't
   1048 		// want to wait too long, and we want to return false so this
   1049 		// connection isn't re-used.
   1050 		select {
   1051 		case err := <-pc.writeErrCh:
   1052 			return err == nil
   1053 		case <-time.After(50 * time.Millisecond):
   1054 			return false
   1055 		}
   1056 	}
   1057 }
   1058 
   1059 type responseAndError struct {
   1060 	res *Response
   1061 	err error
   1062 }
   1063 
   1064 type requestAndChan struct {
   1065 	req *Request
   1066 	ch  chan responseAndError
   1067 
   1068 	// did the Transport (as opposed to the client code) add an
   1069 	// Accept-Encoding gzip header? only if it we set it do
   1070 	// we transparently decode the gzip.
   1071 	addedGzip bool
   1072 }
   1073 
   1074 // A writeRequest is sent by the readLoop's goroutine to the
   1075 // writeLoop's goroutine to write a request while the read loop
   1076 // concurrently waits on both the write response and the server's
   1077 // reply.
   1078 type writeRequest struct {
   1079 	req *transportRequest
   1080 	ch  chan<- error
   1081 }
   1082 
   1083 type httpError struct {
   1084 	err     string
   1085 	timeout bool
   1086 }
   1087 
   1088 func (e *httpError) Error() string   { return e.err }
   1089 func (e *httpError) Timeout() bool   { return e.timeout }
   1090 func (e *httpError) Temporary() bool { return true }
   1091 
   1092 var errTimeout error = &httpError{err: "net/http: timeout awaiting response headers", timeout: true}
   1093 var errClosed error = &httpError{err: "net/http: transport closed before response was received"}
   1094 var errRequestCanceled = errors.New("net/http: request canceled")
   1095 
   1096 // nil except for tests
   1097 var (
   1098 	testHookPersistConnClosedGotRes func()
   1099 	testHookEnterRoundTrip          func()
   1100 	testHookMu                      sync.Locker = fakeLocker{} // guards following
   1101 	testHookReadLoopBeforeNextRead  func()
   1102 )
   1103 
   1104 func (pc *persistConn) roundTrip(req *transportRequest) (resp *Response, err error) {
   1105 	if hook := testHookEnterRoundTrip; hook != nil {
   1106 		hook()
   1107 	}
   1108 	if !pc.t.replaceReqCanceler(req.Request, pc.cancelRequest) {
   1109 		pc.t.putIdleConn(pc)
   1110 		return nil, errRequestCanceled
   1111 	}
   1112 	pc.lk.Lock()
   1113 	pc.numExpectedResponses++
   1114 	headerFn := pc.mutateHeaderFunc
   1115 	pc.lk.Unlock()
   1116 
   1117 	if headerFn != nil {
   1118 		headerFn(req.extraHeaders())
   1119 	}
   1120 
   1121 	// Ask for a compressed version if the caller didn't set their
   1122 	// own value for Accept-Encoding. We only attempt to
   1123 	// uncompress the gzip stream if we were the layer that
   1124 	// requested it.
   1125 	requestedGzip := false
   1126 	if !pc.t.DisableCompression &&
   1127 		req.Header.Get("Accept-Encoding") == "" &&
   1128 		req.Header.Get("Range") == "" &&
   1129 		req.Method != "HEAD" {
   1130 		// Request gzip only, not deflate. Deflate is ambiguous and
   1131 		// not as universally supported anyway.
   1132 		// See: http://www.gzip.org/zlib/zlib_faq.html#faq38
   1133 		//
   1134 		// Note that we don't request this for HEAD requests,
   1135 		// due to a bug in nginx:
   1136 		//   http://trac.nginx.org/nginx/ticket/358
   1137 		//   https://golang.org/issue/5522
   1138 		//
   1139 		// We don't request gzip if the request is for a range, since
   1140 		// auto-decoding a portion of a gzipped document will just fail
   1141 		// anyway. See https://golang.org/issue/8923
   1142 		requestedGzip = true
   1143 		req.extraHeaders().Set("Accept-Encoding", "gzip")
   1144 	}
   1145 
   1146 	if pc.t.DisableKeepAlives {
   1147 		req.extraHeaders().Set("Connection", "close")
   1148 	}
   1149 
   1150 	// Write the request concurrently with waiting for a response,
   1151 	// in case the server decides to reply before reading our full
   1152 	// request body.
   1153 	writeErrCh := make(chan error, 1)
   1154 	pc.writech <- writeRequest{req, writeErrCh}
   1155 
   1156 	resc := make(chan responseAndError, 1)
   1157 	pc.reqch <- requestAndChan{req.Request, resc, requestedGzip}
   1158 
   1159 	var re responseAndError
   1160 	var respHeaderTimer <-chan time.Time
   1161 	cancelChan := req.Request.Cancel
   1162 WaitResponse:
   1163 	for {
   1164 		select {
   1165 		case err := <-writeErrCh:
   1166 			if isNetWriteError(err) {
   1167 				// Issue 11745. If we failed to write the request
   1168 				// body, it's possible the server just heard enough
   1169 				// and already wrote to us. Prioritize the server's
   1170 				// response over returning a body write error.
   1171 				select {
   1172 				case re = <-resc:
   1173 					pc.close()
   1174 					break WaitResponse
   1175 				case <-time.After(50 * time.Millisecond):
   1176 					// Fall through.
   1177 				}
   1178 			}
   1179 			if err != nil {
   1180 				re = responseAndError{nil, err}
   1181 				pc.close()
   1182 				break WaitResponse
   1183 			}
   1184 			if d := pc.t.ResponseHeaderTimeout; d > 0 {
   1185 				timer := time.NewTimer(d)
   1186 				defer timer.Stop() // prevent leaks
   1187 				respHeaderTimer = timer.C
   1188 			}
   1189 		case <-pc.closech:
   1190 			// The persist connection is dead. This shouldn't
   1191 			// usually happen (only with Connection: close responses
   1192 			// with no response bodies), but if it does happen it
   1193 			// means either a) the remote server hung up on us
   1194 			// prematurely, or b) the readLoop sent us a response &
   1195 			// closed its closech at roughly the same time, and we
   1196 			// selected this case first. If we got a response, readLoop makes sure
   1197 			// to send it before it puts the conn and closes the channel.
   1198 			// That way, we can fetch the response, if there is one,
   1199 			// with a non-blocking receive.
   1200 			select {
   1201 			case re = <-resc:
   1202 				if fn := testHookPersistConnClosedGotRes; fn != nil {
   1203 					fn()
   1204 				}
   1205 			default:
   1206 				re = responseAndError{err: errClosed}
   1207 				if pc.isCanceled() {
   1208 					re = responseAndError{err: errRequestCanceled}
   1209 				}
   1210 			}
   1211 			break WaitResponse
   1212 		case <-respHeaderTimer:
   1213 			pc.close()
   1214 			re = responseAndError{err: errTimeout}
   1215 			break WaitResponse
   1216 		case re = <-resc:
   1217 			break WaitResponse
   1218 		case <-cancelChan:
   1219 			pc.t.CancelRequest(req.Request)
   1220 			cancelChan = nil
   1221 		}
   1222 	}
   1223 
   1224 	if re.err != nil {
   1225 		pc.t.setReqCanceler(req.Request, nil)
   1226 	}
   1227 	return re.res, re.err
   1228 }
   1229 
   1230 // markBroken marks a connection as broken (so it's not reused).
   1231 // It differs from close in that it doesn't close the underlying
   1232 // connection for use when it's still being read.
   1233 func (pc *persistConn) markBroken() {
   1234 	pc.lk.Lock()
   1235 	defer pc.lk.Unlock()
   1236 	pc.broken = true
   1237 }
   1238 
   1239 func (pc *persistConn) close() {
   1240 	pc.lk.Lock()
   1241 	defer pc.lk.Unlock()
   1242 	pc.closeLocked()
   1243 }
   1244 
   1245 func (pc *persistConn) closeLocked() {
   1246 	pc.broken = true
   1247 	if !pc.closed {
   1248 		pc.conn.Close()
   1249 		pc.closed = true
   1250 		close(pc.closech)
   1251 	}
   1252 	pc.mutateHeaderFunc = nil
   1253 }
   1254 
   1255 var portMap = map[string]string{
   1256 	"http":  "80",
   1257 	"https": "443",
   1258 }
   1259 
   1260 // canonicalAddr returns url.Host but always with a ":port" suffix
   1261 func canonicalAddr(url *url.URL) string {
   1262 	addr := url.Host
   1263 	if !hasPort(addr) {
   1264 		return addr + ":" + portMap[url.Scheme]
   1265 	}
   1266 	return addr
   1267 }
   1268 
   1269 // bodyEOFSignal wraps a ReadCloser but runs fn (if non-nil) at most
   1270 // once, right before its final (error-producing) Read or Close call
   1271 // returns. fn should return the new error to return from Read or Close.
   1272 //
   1273 // If earlyCloseFn is non-nil and Close is called before io.EOF is
   1274 // seen, earlyCloseFn is called instead of fn, and its return value is
   1275 // the return value from Close.
   1276 type bodyEOFSignal struct {
   1277 	body         io.ReadCloser
   1278 	mu           sync.Mutex        // guards following 4 fields
   1279 	closed       bool              // whether Close has been called
   1280 	rerr         error             // sticky Read error
   1281 	fn           func(error) error // err will be nil on Read io.EOF
   1282 	earlyCloseFn func() error      // optional alt Close func used if io.EOF not seen
   1283 }
   1284 
   1285 func (es *bodyEOFSignal) Read(p []byte) (n int, err error) {
   1286 	es.mu.Lock()
   1287 	closed, rerr := es.closed, es.rerr
   1288 	es.mu.Unlock()
   1289 	if closed {
   1290 		return 0, errors.New("http: read on closed response body")
   1291 	}
   1292 	if rerr != nil {
   1293 		return 0, rerr
   1294 	}
   1295 
   1296 	n, err = es.body.Read(p)
   1297 	if err != nil {
   1298 		es.mu.Lock()
   1299 		defer es.mu.Unlock()
   1300 		if es.rerr == nil {
   1301 			es.rerr = err
   1302 		}
   1303 		err = es.condfn(err)
   1304 	}
   1305 	return
   1306 }
   1307 
   1308 func (es *bodyEOFSignal) Close() error {
   1309 	es.mu.Lock()
   1310 	defer es.mu.Unlock()
   1311 	if es.closed {
   1312 		return nil
   1313 	}
   1314 	es.closed = true
   1315 	if es.earlyCloseFn != nil && es.rerr != io.EOF {
   1316 		return es.earlyCloseFn()
   1317 	}
   1318 	err := es.body.Close()
   1319 	return es.condfn(err)
   1320 }
   1321 
   1322 // caller must hold es.mu.
   1323 func (es *bodyEOFSignal) condfn(err error) error {
   1324 	if es.fn == nil {
   1325 		return err
   1326 	}
   1327 	err = es.fn(err)
   1328 	es.fn = nil
   1329 	return err
   1330 }
   1331 
   1332 // gzipReader wraps a response body so it can lazily
   1333 // call gzip.NewReader on the first call to Read
   1334 type gzipReader struct {
   1335 	body io.ReadCloser // underlying Response.Body
   1336 	zr   io.Reader     // lazily-initialized gzip reader
   1337 }
   1338 
   1339 func (gz *gzipReader) Read(p []byte) (n int, err error) {
   1340 	if gz.zr == nil {
   1341 		gz.zr, err = gzip.NewReader(gz.body)
   1342 		if err != nil {
   1343 			return 0, err
   1344 		}
   1345 	}
   1346 	return gz.zr.Read(p)
   1347 }
   1348 
   1349 func (gz *gzipReader) Close() error {
   1350 	return gz.body.Close()
   1351 }
   1352 
   1353 type readerAndCloser struct {
   1354 	io.Reader
   1355 	io.Closer
   1356 }
   1357 
   1358 type tlsHandshakeTimeoutError struct{}
   1359 
   1360 func (tlsHandshakeTimeoutError) Timeout() bool   { return true }
   1361 func (tlsHandshakeTimeoutError) Temporary() bool { return true }
   1362 func (tlsHandshakeTimeoutError) Error() string   { return "net/http: TLS handshake timeout" }
   1363 
   1364 type noteEOFReader struct {
   1365 	r      io.Reader
   1366 	sawEOF *bool
   1367 }
   1368 
   1369 func (nr noteEOFReader) Read(p []byte) (n int, err error) {
   1370 	n, err = nr.r.Read(p)
   1371 	if err == io.EOF {
   1372 		*nr.sawEOF = true
   1373 	}
   1374 	return
   1375 }
   1376 
   1377 // fakeLocker is a sync.Locker which does nothing. It's used to guard
   1378 // test-only fields when not under test, to avoid runtime atomic
   1379 // overhead.
   1380 type fakeLocker struct{}
   1381 
   1382 func (fakeLocker) Lock()   {}
   1383 func (fakeLocker) Unlock() {}
   1384 
   1385 func isNetWriteError(err error) bool {
   1386 	switch e := err.(type) {
   1387 	case *url.Error:
   1388 		return isNetWriteError(e.Err)
   1389 	case *net.OpError:
   1390 		return e.Op == "write"
   1391 	default:
   1392 		return false
   1393 	}
   1394 }
   1395 
   1396 // cloneTLSConfig returns a shallow clone of the exported
   1397 // fields of cfg, ignoring the unexported sync.Once, which
   1398 // contains a mutex and must not be copied.
   1399 //
   1400 // The cfg must not be in active use by tls.Server, or else
   1401 // there can still be a race with tls.Server updating SessionTicketKey
   1402 // and our copying it, and also a race with the server setting
   1403 // SessionTicketsDisabled=false on failure to set the random
   1404 // ticket key.
   1405 //
   1406 // If cfg is nil, a new zero tls.Config is returned.
   1407 func cloneTLSConfig(cfg *tls.Config) *tls.Config {
   1408 	if cfg == nil {
   1409 		return &tls.Config{}
   1410 	}
   1411 	return &tls.Config{
   1412 		Rand:                     cfg.Rand,
   1413 		Time:                     cfg.Time,
   1414 		Certificates:             cfg.Certificates,
   1415 		NameToCertificate:        cfg.NameToCertificate,
   1416 		GetCertificate:           cfg.GetCertificate,
   1417 		RootCAs:                  cfg.RootCAs,
   1418 		NextProtos:               cfg.NextProtos,
   1419 		ServerName:               cfg.ServerName,
   1420 		ClientAuth:               cfg.ClientAuth,
   1421 		ClientCAs:                cfg.ClientCAs,
   1422 		InsecureSkipVerify:       cfg.InsecureSkipVerify,
   1423 		CipherSuites:             cfg.CipherSuites,
   1424 		PreferServerCipherSuites: cfg.PreferServerCipherSuites,
   1425 		SessionTicketsDisabled:   cfg.SessionTicketsDisabled,
   1426 		SessionTicketKey:         cfg.SessionTicketKey,
   1427 		ClientSessionCache:       cfg.ClientSessionCache,
   1428 		MinVersion:               cfg.MinVersion,
   1429 		MaxVersion:               cfg.MaxVersion,
   1430 		CurvePreferences:         cfg.CurvePreferences,
   1431 	}
   1432 }
   1433 
   1434 // cloneTLSClientConfig is like cloneTLSConfig but omits
   1435 // the fields SessionTicketsDisabled and SessionTicketKey.
   1436 // This makes it safe to call cloneTLSClientConfig on a config
   1437 // in active use by a server.
   1438 func cloneTLSClientConfig(cfg *tls.Config) *tls.Config {
   1439 	if cfg == nil {
   1440 		return &tls.Config{}
   1441 	}
   1442 	return &tls.Config{
   1443 		Rand:                     cfg.Rand,
   1444 		Time:                     cfg.Time,
   1445 		Certificates:             cfg.Certificates,
   1446 		NameToCertificate:        cfg.NameToCertificate,
   1447 		GetCertificate:           cfg.GetCertificate,
   1448 		RootCAs:                  cfg.RootCAs,
   1449 		NextProtos:               cfg.NextProtos,
   1450 		ServerName:               cfg.ServerName,
   1451 		ClientAuth:               cfg.ClientAuth,
   1452 		ClientCAs:                cfg.ClientCAs,
   1453 		InsecureSkipVerify:       cfg.InsecureSkipVerify,
   1454 		CipherSuites:             cfg.CipherSuites,
   1455 		PreferServerCipherSuites: cfg.PreferServerCipherSuites,
   1456 		ClientSessionCache:       cfg.ClientSessionCache,
   1457 		MinVersion:               cfg.MinVersion,
   1458 		MaxVersion:               cfg.MaxVersion,
   1459 		CurvePreferences:         cfg.CurvePreferences,
   1460 	}
   1461 }
   1462