...
Run Format

Source file src/net/http/client.go

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

View as plain text