github.com/euank/go@v0.0.0-20160829210321-495514729181/src/net/http/client.go (about)

     1  // Copyright 2009 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. See RFC 2616.
     6  //
     7  // This is the high-level Client interface.
     8  // The low-level implementation is in transport.go.
     9  
    10  package http
    11  
    12  import (
    13  	"crypto/tls"
    14  	"encoding/base64"
    15  	"errors"
    16  	"fmt"
    17  	"io"
    18  	"io/ioutil"
    19  	"log"
    20  	"net/url"
    21  	"strings"
    22  	"sync"
    23  	"time"
    24  )
    25  
    26  // A Client is an HTTP client. Its zero value (DefaultClient) is a
    27  // usable client that uses DefaultTransport.
    28  //
    29  // The Client's Transport typically has internal state (cached TCP
    30  // connections), so Clients should be reused instead of created as
    31  // needed. Clients are safe for concurrent use by multiple goroutines.
    32  //
    33  // A Client is higher-level than a RoundTripper (such as Transport)
    34  // and additionally handles HTTP details such as cookies and
    35  // redirects.
    36  type Client struct {
    37  	// Transport specifies the mechanism by which individual
    38  	// HTTP requests are made.
    39  	// If nil, DefaultTransport is used.
    40  	Transport RoundTripper
    41  
    42  	// CheckRedirect specifies the policy for handling redirects.
    43  	// If CheckRedirect is not nil, the client calls it before
    44  	// following an HTTP redirect. The arguments req and via are
    45  	// the upcoming request and the requests made already, oldest
    46  	// first. If CheckRedirect returns an error, the Client's Get
    47  	// method returns both the previous Response (with its Body
    48  	// closed) and CheckRedirect's error (wrapped in a url.Error)
    49  	// instead of issuing the Request req.
    50  	// As a special case, if CheckRedirect returns ErrUseLastResponse,
    51  	// then the most recent response is returned with its body
    52  	// unclosed, along with a nil error.
    53  	//
    54  	// If CheckRedirect is nil, the Client uses its default policy,
    55  	// which is to stop after 10 consecutive requests.
    56  	CheckRedirect func(req *Request, via []*Request) error
    57  
    58  	// Jar specifies the cookie jar.
    59  	// If Jar is nil, cookies are not sent in requests and ignored
    60  	// in responses.
    61  	Jar CookieJar
    62  
    63  	// Timeout specifies a time limit for requests made by this
    64  	// Client. The timeout includes connection time, any
    65  	// redirects, and reading the response body. The timer remains
    66  	// running after Get, Head, Post, or Do return and will
    67  	// interrupt reading of the Response.Body.
    68  	//
    69  	// A Timeout of zero means no timeout.
    70  	//
    71  	// The Client cancels requests to the underlying Transport
    72  	// using the Request.Cancel mechanism. Requests passed
    73  	// to Client.Do may still set Request.Cancel; both will
    74  	// cancel the request.
    75  	//
    76  	// For compatibility, the Client will also use the deprecated
    77  	// CancelRequest method on Transport if found. New
    78  	// RoundTripper implementations should use Request.Cancel
    79  	// instead of implementing CancelRequest.
    80  	Timeout time.Duration
    81  }
    82  
    83  // DefaultClient is the default Client and is used by Get, Head, and Post.
    84  var DefaultClient = &Client{}
    85  
    86  // RoundTripper is an interface representing the ability to execute a
    87  // single HTTP transaction, obtaining the Response for a given Request.
    88  //
    89  // A RoundTripper must be safe for concurrent use by multiple
    90  // goroutines.
    91  type RoundTripper interface {
    92  	// RoundTrip executes a single HTTP transaction, returning
    93  	// a Response for the provided Request.
    94  	//
    95  	// RoundTrip should not attempt to interpret the response. In
    96  	// particular, RoundTrip must return err == nil if it obtained
    97  	// a response, regardless of the response's HTTP status code.
    98  	// A non-nil err should be reserved for failure to obtain a
    99  	// response. Similarly, RoundTrip should not attempt to
   100  	// handle higher-level protocol details such as redirects,
   101  	// authentication, or cookies.
   102  	//
   103  	// RoundTrip should not modify the request, except for
   104  	// consuming and closing the Request's Body.
   105  	//
   106  	// RoundTrip must always close the body, including on errors,
   107  	// but depending on the implementation may do so in a separate
   108  	// goroutine even after RoundTrip returns. This means that
   109  	// callers wanting to reuse the body for subsequent requests
   110  	// must arrange to wait for the Close call before doing so.
   111  	//
   112  	// The Request's URL and Header fields must be initialized.
   113  	RoundTrip(*Request) (*Response, error)
   114  }
   115  
   116  // refererForURL returns a referer without any authentication info or
   117  // an empty string if lastReq scheme is https and newReq scheme is http.
   118  func refererForURL(lastReq, newReq *url.URL) string {
   119  	// https://tools.ietf.org/html/rfc7231#section-5.5.2
   120  	//   "Clients SHOULD NOT include a Referer header field in a
   121  	//    (non-secure) HTTP request if the referring page was
   122  	//    transferred with a secure protocol."
   123  	if lastReq.Scheme == "https" && newReq.Scheme == "http" {
   124  		return ""
   125  	}
   126  	referer := lastReq.String()
   127  	if lastReq.User != nil {
   128  		// This is not very efficient, but is the best we can
   129  		// do without:
   130  		// - introducing a new method on URL
   131  		// - creating a race condition
   132  		// - copying the URL struct manually, which would cause
   133  		//   maintenance problems down the line
   134  		auth := lastReq.User.String() + "@"
   135  		referer = strings.Replace(referer, auth, "", 1)
   136  	}
   137  	return referer
   138  }
   139  
   140  func (c *Client) send(req *Request, deadline time.Time) (*Response, error) {
   141  	if c.Jar != nil {
   142  		for _, cookie := range c.Jar.Cookies(req.URL) {
   143  			req.AddCookie(cookie)
   144  		}
   145  	}
   146  	resp, err := send(req, c.transport(), deadline)
   147  	if err != nil {
   148  		return nil, err
   149  	}
   150  	if c.Jar != nil {
   151  		if rc := resp.Cookies(); len(rc) > 0 {
   152  			c.Jar.SetCookies(req.URL, rc)
   153  		}
   154  	}
   155  	return resp, nil
   156  }
   157  
   158  // Do sends an HTTP request and returns an HTTP response, following
   159  // policy (such as redirects, cookies, auth) as configured on the
   160  // client.
   161  //
   162  // An error is returned if caused by client policy (such as
   163  // CheckRedirect), or failure to speak HTTP (such as a network
   164  // connectivity problem). A non-2xx status code doesn't cause an
   165  // error.
   166  //
   167  // If the returned error is nil, the Response will contain a non-nil
   168  // Body which the user is expected to close. If the Body is not
   169  // closed, the Client's underlying RoundTripper (typically Transport)
   170  // may not be able to re-use a persistent TCP connection to the server
   171  // for a subsequent "keep-alive" request.
   172  //
   173  // The request Body, if non-nil, will be closed by the underlying
   174  // Transport, even on errors.
   175  //
   176  // On error, any Response can be ignored. A non-nil Response with a
   177  // non-nil error only occurs when CheckRedirect fails, and even then
   178  // the returned Response.Body is already closed.
   179  //
   180  // Generally Get, Post, or PostForm will be used instead of Do.
   181  func (c *Client) Do(req *Request) (*Response, error) {
   182  	method := valueOrDefault(req.Method, "GET")
   183  	if method == "GET" || method == "HEAD" {
   184  		return c.doFollowingRedirects(req, shouldRedirectGet)
   185  	}
   186  	if method == "POST" || method == "PUT" {
   187  		return c.doFollowingRedirects(req, shouldRedirectPost)
   188  	}
   189  	return c.send(req, c.deadline())
   190  }
   191  
   192  func (c *Client) deadline() time.Time {
   193  	if c.Timeout > 0 {
   194  		return time.Now().Add(c.Timeout)
   195  	}
   196  	return time.Time{}
   197  }
   198  
   199  func (c *Client) transport() RoundTripper {
   200  	if c.Transport != nil {
   201  		return c.Transport
   202  	}
   203  	return DefaultTransport
   204  }
   205  
   206  // send issues an HTTP request.
   207  // Caller should close resp.Body when done reading from it.
   208  func send(ireq *Request, rt RoundTripper, deadline time.Time) (*Response, error) {
   209  	req := ireq // req is either the original request, or a modified fork
   210  
   211  	if rt == nil {
   212  		req.closeBody()
   213  		return nil, errors.New("http: no Client.Transport or DefaultTransport")
   214  	}
   215  
   216  	if req.URL == nil {
   217  		req.closeBody()
   218  		return nil, errors.New("http: nil Request.URL")
   219  	}
   220  
   221  	if req.RequestURI != "" {
   222  		req.closeBody()
   223  		return nil, errors.New("http: Request.RequestURI can't be set in client requests.")
   224  	}
   225  
   226  	// forkReq forks req into a shallow clone of ireq the first
   227  	// time it's called.
   228  	forkReq := func() {
   229  		if ireq == req {
   230  			req = new(Request)
   231  			*req = *ireq // shallow clone
   232  		}
   233  	}
   234  
   235  	// Most the callers of send (Get, Post, et al) don't need
   236  	// Headers, leaving it uninitialized. We guarantee to the
   237  	// Transport that this has been initialized, though.
   238  	if req.Header == nil {
   239  		forkReq()
   240  		req.Header = make(Header)
   241  	}
   242  
   243  	if u := req.URL.User; u != nil && req.Header.Get("Authorization") == "" {
   244  		username := u.Username()
   245  		password, _ := u.Password()
   246  		forkReq()
   247  		req.Header = cloneHeader(ireq.Header)
   248  		req.Header.Set("Authorization", "Basic "+basicAuth(username, password))
   249  	}
   250  
   251  	if !deadline.IsZero() {
   252  		forkReq()
   253  	}
   254  	stopTimer, wasCanceled := setRequestCancel(req, rt, deadline)
   255  
   256  	resp, err := rt.RoundTrip(req)
   257  	if err != nil {
   258  		stopTimer()
   259  		if resp != nil {
   260  			log.Printf("RoundTripper returned a response & error; ignoring response")
   261  		}
   262  		if tlsErr, ok := err.(tls.RecordHeaderError); ok {
   263  			// If we get a bad TLS record header, check to see if the
   264  			// response looks like HTTP and give a more helpful error.
   265  			// See golang.org/issue/11111.
   266  			if string(tlsErr.RecordHeader[:]) == "HTTP/" {
   267  				err = errors.New("http: server gave HTTP response to HTTPS client")
   268  			}
   269  		}
   270  		return nil, err
   271  	}
   272  	if !deadline.IsZero() {
   273  		resp.Body = &cancelTimerBody{
   274  			stop:           stopTimer,
   275  			rc:             resp.Body,
   276  			reqWasCanceled: wasCanceled,
   277  		}
   278  	}
   279  	return resp, nil
   280  }
   281  
   282  // setRequestCancel sets the Cancel field of req, if deadline is
   283  // non-zero. The RoundTripper's type is used to determine whether the legacy
   284  // CancelRequest behavior should be used.
   285  func setRequestCancel(req *Request, rt RoundTripper, deadline time.Time) (stopTimer func(), wasCanceled func() bool) {
   286  	if deadline.IsZero() {
   287  		return nop, alwaysFalse
   288  	}
   289  
   290  	initialReqCancel := req.Cancel // the user's original Request.Cancel, if any
   291  
   292  	cancel := make(chan struct{})
   293  	req.Cancel = cancel
   294  
   295  	wasCanceled = func() bool {
   296  		select {
   297  		case <-cancel:
   298  			return true
   299  		default:
   300  			return false
   301  		}
   302  	}
   303  
   304  	doCancel := func() {
   305  		// The new way:
   306  		close(cancel)
   307  
   308  		// The legacy compatibility way, used only
   309  		// for RoundTripper implementations written
   310  		// before Go 1.5 or Go 1.6.
   311  		type canceler interface {
   312  			CancelRequest(*Request)
   313  		}
   314  		switch v := rt.(type) {
   315  		case *Transport, *http2Transport:
   316  			// Do nothing. The net/http package's transports
   317  			// support the new Request.Cancel channel
   318  		case canceler:
   319  			v.CancelRequest(req)
   320  		}
   321  	}
   322  
   323  	stopTimerCh := make(chan struct{})
   324  	var once sync.Once
   325  	stopTimer = func() { once.Do(func() { close(stopTimerCh) }) }
   326  
   327  	timer := time.NewTimer(deadline.Sub(time.Now()))
   328  	go func() {
   329  		select {
   330  		case <-initialReqCancel:
   331  			doCancel()
   332  		case <-timer.C:
   333  			doCancel()
   334  		case <-stopTimerCh:
   335  			timer.Stop()
   336  		}
   337  	}()
   338  
   339  	return stopTimer, wasCanceled
   340  }
   341  
   342  // See 2 (end of page 4) http://www.ietf.org/rfc/rfc2617.txt
   343  // "To receive authorization, the client sends the userid and password,
   344  // separated by a single colon (":") character, within a base64
   345  // encoded string in the credentials."
   346  // It is not meant to be urlencoded.
   347  func basicAuth(username, password string) string {
   348  	auth := username + ":" + password
   349  	return base64.StdEncoding.EncodeToString([]byte(auth))
   350  }
   351  
   352  // True if the specified HTTP status code is one for which the Get utility should
   353  // automatically redirect.
   354  func shouldRedirectGet(statusCode int) bool {
   355  	switch statusCode {
   356  	case StatusMovedPermanently, StatusFound, StatusSeeOther, StatusTemporaryRedirect:
   357  		return true
   358  	}
   359  	return false
   360  }
   361  
   362  // True if the specified HTTP status code is one for which the Post utility should
   363  // automatically redirect.
   364  func shouldRedirectPost(statusCode int) bool {
   365  	switch statusCode {
   366  	case StatusFound, StatusSeeOther:
   367  		return true
   368  	}
   369  	return false
   370  }
   371  
   372  // Get issues a GET to the specified URL. If the response is one of
   373  // the following redirect codes, Get follows the redirect, up to a
   374  // maximum of 10 redirects:
   375  //
   376  //    301 (Moved Permanently)
   377  //    302 (Found)
   378  //    303 (See Other)
   379  //    307 (Temporary Redirect)
   380  //
   381  // An error is returned if there were too many redirects or if there
   382  // was an HTTP protocol error. A non-2xx response doesn't cause an
   383  // error.
   384  //
   385  // When err is nil, resp always contains a non-nil resp.Body.
   386  // Caller should close resp.Body when done reading from it.
   387  //
   388  // Get is a wrapper around DefaultClient.Get.
   389  //
   390  // To make a request with custom headers, use NewRequest and
   391  // DefaultClient.Do.
   392  func Get(url string) (resp *Response, err error) {
   393  	return DefaultClient.Get(url)
   394  }
   395  
   396  // Get issues a GET to the specified URL. If the response is one of the
   397  // following redirect codes, Get follows the redirect after calling the
   398  // Client's CheckRedirect function:
   399  //
   400  //    301 (Moved Permanently)
   401  //    302 (Found)
   402  //    303 (See Other)
   403  //    307 (Temporary Redirect)
   404  //
   405  // An error is returned if the Client's CheckRedirect function fails
   406  // or if there was an HTTP protocol error. A non-2xx response doesn't
   407  // cause an error.
   408  //
   409  // When err is nil, resp always contains a non-nil resp.Body.
   410  // Caller should close resp.Body when done reading from it.
   411  //
   412  // To make a request with custom headers, use NewRequest and Client.Do.
   413  func (c *Client) Get(url string) (resp *Response, err error) {
   414  	req, err := NewRequest("GET", url, nil)
   415  	if err != nil {
   416  		return nil, err
   417  	}
   418  	return c.doFollowingRedirects(req, shouldRedirectGet)
   419  }
   420  
   421  func alwaysFalse() bool { return false }
   422  
   423  // ErrUseLastResponse can be returned by Client.CheckRedirect hooks to
   424  // control how redirects are processed. If returned, the next request
   425  // is not sent and the most recent response is returned with its body
   426  // unclosed.
   427  var ErrUseLastResponse = errors.New("net/http: use last response")
   428  
   429  // checkRedirect calls either the user's configured CheckRedirect
   430  // function, or the default.
   431  func (c *Client) checkRedirect(req *Request, via []*Request) error {
   432  	fn := c.CheckRedirect
   433  	if fn == nil {
   434  		fn = defaultCheckRedirect
   435  	}
   436  	return fn(req, via)
   437  }
   438  
   439  func (c *Client) doFollowingRedirects(req *Request, shouldRedirect func(int) bool) (*Response, error) {
   440  	if req.URL == nil {
   441  		req.closeBody()
   442  		return nil, errors.New("http: nil Request.URL")
   443  	}
   444  
   445  	var (
   446  		deadline = c.deadline()
   447  		reqs     []*Request
   448  		resp     *Response
   449  	)
   450  	uerr := func(err error) error {
   451  		req.closeBody()
   452  		method := valueOrDefault(reqs[0].Method, "GET")
   453  		var urlStr string
   454  		if resp != nil && resp.Request != nil {
   455  			urlStr = resp.Request.URL.String()
   456  		} else {
   457  			urlStr = req.URL.String()
   458  		}
   459  		return &url.Error{
   460  			Op:  method[:1] + strings.ToLower(method[1:]),
   461  			URL: urlStr,
   462  			Err: err,
   463  		}
   464  	}
   465  	for {
   466  		// For all but the first request, create the next
   467  		// request hop and replace req.
   468  		if len(reqs) > 0 {
   469  			loc := resp.Header.Get("Location")
   470  			if loc == "" {
   471  				return nil, uerr(fmt.Errorf("%d response missing Location header", resp.StatusCode))
   472  			}
   473  			u, err := req.URL.Parse(loc)
   474  			if err != nil {
   475  				return nil, uerr(fmt.Errorf("failed to parse Location header %q: %v", loc, err))
   476  			}
   477  			ireq := reqs[0]
   478  			req = &Request{
   479  				Method:   ireq.Method,
   480  				Response: resp,
   481  				URL:      u,
   482  				Header:   make(Header),
   483  				Cancel:   ireq.Cancel,
   484  				ctx:      ireq.ctx,
   485  			}
   486  			if ireq.Method == "POST" || ireq.Method == "PUT" {
   487  				req.Method = "GET"
   488  			}
   489  			// Add the Referer header from the most recent
   490  			// request URL to the new one, if it's not https->http:
   491  			if ref := refererForURL(reqs[len(reqs)-1].URL, req.URL); ref != "" {
   492  				req.Header.Set("Referer", ref)
   493  			}
   494  			err = c.checkRedirect(req, reqs)
   495  
   496  			// Sentinel error to let users select the
   497  			// previous response, without closing its
   498  			// body. See Issue 10069.
   499  			if err == ErrUseLastResponse {
   500  				return resp, nil
   501  			}
   502  
   503  			// Close the previous response's body. But
   504  			// read at least some of the body so if it's
   505  			// small the underlying TCP connection will be
   506  			// re-used. No need to check for errors: if it
   507  			// fails, the Transport won't reuse it anyway.
   508  			const maxBodySlurpSize = 2 << 10
   509  			if resp.ContentLength == -1 || resp.ContentLength <= maxBodySlurpSize {
   510  				io.CopyN(ioutil.Discard, resp.Body, maxBodySlurpSize)
   511  			}
   512  			resp.Body.Close()
   513  
   514  			if err != nil {
   515  				// Special case for Go 1 compatibility: return both the response
   516  				// and an error if the CheckRedirect function failed.
   517  				// See https://golang.org/issue/3795
   518  				// The resp.Body has already been closed.
   519  				ue := uerr(err)
   520  				ue.(*url.Error).URL = loc
   521  				return resp, ue
   522  			}
   523  		}
   524  
   525  		reqs = append(reqs, req)
   526  
   527  		var err error
   528  		if resp, err = c.send(req, deadline); err != nil {
   529  			if !deadline.IsZero() && !time.Now().Before(deadline) {
   530  				err = &httpError{
   531  					err:     err.Error() + " (Client.Timeout exceeded while awaiting headers)",
   532  					timeout: true,
   533  				}
   534  			}
   535  			return nil, uerr(err)
   536  		}
   537  
   538  		if !shouldRedirect(resp.StatusCode) {
   539  			return resp, nil
   540  		}
   541  	}
   542  }
   543  
   544  func defaultCheckRedirect(req *Request, via []*Request) error {
   545  	if len(via) >= 10 {
   546  		return errors.New("stopped after 10 redirects")
   547  	}
   548  	return nil
   549  }
   550  
   551  // Post issues a POST to the specified URL.
   552  //
   553  // Caller should close resp.Body when done reading from it.
   554  //
   555  // If the provided body is an io.Closer, it is closed after the
   556  // request.
   557  //
   558  // Post is a wrapper around DefaultClient.Post.
   559  //
   560  // To set custom headers, use NewRequest and DefaultClient.Do.
   561  func Post(url string, bodyType string, body io.Reader) (resp *Response, err error) {
   562  	return DefaultClient.Post(url, bodyType, body)
   563  }
   564  
   565  // Post issues a POST to the specified URL.
   566  //
   567  // Caller should close resp.Body when done reading from it.
   568  //
   569  // If the provided body is an io.Closer, it is closed after the
   570  // request.
   571  //
   572  // To set custom headers, use NewRequest and Client.Do.
   573  func (c *Client) Post(url string, bodyType string, body io.Reader) (resp *Response, err error) {
   574  	req, err := NewRequest("POST", url, body)
   575  	if err != nil {
   576  		return nil, err
   577  	}
   578  	req.Header.Set("Content-Type", bodyType)
   579  	return c.doFollowingRedirects(req, shouldRedirectPost)
   580  }
   581  
   582  // PostForm issues a POST to the specified URL, with data's keys and
   583  // values URL-encoded as the request body.
   584  //
   585  // The Content-Type header is set to application/x-www-form-urlencoded.
   586  // To set other headers, use NewRequest and DefaultClient.Do.
   587  //
   588  // When err is nil, resp always contains a non-nil resp.Body.
   589  // Caller should close resp.Body when done reading from it.
   590  //
   591  // PostForm is a wrapper around DefaultClient.PostForm.
   592  func PostForm(url string, data url.Values) (resp *Response, err error) {
   593  	return DefaultClient.PostForm(url, data)
   594  }
   595  
   596  // PostForm issues a POST to the specified URL,
   597  // with data's keys and values URL-encoded as the request body.
   598  //
   599  // The Content-Type header is set to application/x-www-form-urlencoded.
   600  // To set other headers, use NewRequest and DefaultClient.Do.
   601  //
   602  // When err is nil, resp always contains a non-nil resp.Body.
   603  // Caller should close resp.Body when done reading from it.
   604  func (c *Client) PostForm(url string, data url.Values) (resp *Response, err error) {
   605  	return c.Post(url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode()))
   606  }
   607  
   608  // Head issues a HEAD to the specified URL.  If the response is one of
   609  // the following redirect codes, Head follows the redirect, up to a
   610  // maximum of 10 redirects:
   611  //
   612  //    301 (Moved Permanently)
   613  //    302 (Found)
   614  //    303 (See Other)
   615  //    307 (Temporary Redirect)
   616  //
   617  // Head is a wrapper around DefaultClient.Head
   618  func Head(url string) (resp *Response, err error) {
   619  	return DefaultClient.Head(url)
   620  }
   621  
   622  // Head issues a HEAD to the specified URL.  If the response is one of the
   623  // following redirect codes, Head follows the redirect after calling the
   624  // Client's CheckRedirect function:
   625  //
   626  //    301 (Moved Permanently)
   627  //    302 (Found)
   628  //    303 (See Other)
   629  //    307 (Temporary Redirect)
   630  func (c *Client) Head(url string) (resp *Response, err error) {
   631  	req, err := NewRequest("HEAD", url, nil)
   632  	if err != nil {
   633  		return nil, err
   634  	}
   635  	return c.doFollowingRedirects(req, shouldRedirectGet)
   636  }
   637  
   638  // cancelTimerBody is an io.ReadCloser that wraps rc with two features:
   639  // 1) on Read error or close, the stop func is called.
   640  // 2) On Read failure, if reqWasCanceled is true, the error is wrapped and
   641  //    marked as net.Error that hit its timeout.
   642  type cancelTimerBody struct {
   643  	stop           func() // stops the time.Timer waiting to cancel the request
   644  	rc             io.ReadCloser
   645  	reqWasCanceled func() bool
   646  }
   647  
   648  func (b *cancelTimerBody) Read(p []byte) (n int, err error) {
   649  	n, err = b.rc.Read(p)
   650  	if err == nil {
   651  		return n, nil
   652  	}
   653  	b.stop()
   654  	if err == io.EOF {
   655  		return n, err
   656  	}
   657  	if b.reqWasCanceled() {
   658  		err = &httpError{
   659  			err:     err.Error() + " (Client.Timeout exceeded while reading body)",
   660  			timeout: true,
   661  		}
   662  	}
   663  	return n, err
   664  }
   665  
   666  func (b *cancelTimerBody) Close() error {
   667  	err := b.rc.Close()
   668  	b.stop()
   669  	return err
   670  }