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