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