OLD | NEW |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // HTTP client. See RFC 2616. | 5 // HTTP client. See RFC 2616. |
6 //· | 6 //· |
7 // This is the high-level Client interface. | 7 // This is the high-level Client interface. |
8 // The low-level implementation is in transport.go. | 8 // The low-level implementation is in transport.go. |
9 | 9 |
10 package http | 10 package http |
(...skipping 20 matching lines...) Expand all Loading... |
31 | 31 |
32 // If CheckRedirect is not nil, the client calls it before | 32 // If CheckRedirect is not nil, the client calls it before |
33 // following an HTTP redirect. The arguments req and via | 33 // following an HTTP redirect. The arguments req and via |
34 // are the upcoming request and the requests made already, | 34 // are the upcoming request and the requests made already, |
35 // oldest first. If CheckRedirect returns an error, the client | 35 // oldest first. If CheckRedirect returns an error, the client |
36 // returns that error instead of issue the Request req. | 36 // returns that error instead of issue the Request req. |
37 // | 37 // |
38 // If CheckRedirect is nil, the Client uses its default policy, | 38 // If CheckRedirect is nil, the Client uses its default policy, |
39 // which is to stop after 10 consecutive requests. | 39 // which is to stop after 10 consecutive requests. |
40 CheckRedirect func(req *Request, via []*Request) error | 40 CheckRedirect func(req *Request, via []*Request) error |
| 41 |
| 42 // Jar specifies the cookie jar.· |
| 43 // If Jar is nil, cookies are not sent in requests and ignored· |
| 44 // in responses. |
| 45 Jar CookieJar |
41 } | 46 } |
42 | 47 |
43 // DefaultClient is the default Client and is used by Get, Head, and Post. | 48 // DefaultClient is the default Client and is used by Get, Head, and Post. |
44 var DefaultClient = &Client{} | 49 var DefaultClient = &Client{} |
45 | 50 |
46 // RoundTripper is an interface representing the ability to execute a | 51 // RoundTripper is an interface representing the ability to execute a |
47 // single HTTP transaction, obtaining the Response for a given Request. | 52 // single HTTP transaction, obtaining the Response for a given Request. |
48 // | 53 // |
49 // A RoundTripper must be safe for concurrent use by multiple | 54 // A RoundTripper must be safe for concurrent use by multiple |
50 // goroutines. | 55 // goroutines. |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
173 redirectChecker := c.CheckRedirect | 178 redirectChecker := c.CheckRedirect |
174 if redirectChecker == nil { | 179 if redirectChecker == nil { |
175 redirectChecker = defaultCheckRedirect | 180 redirectChecker = defaultCheckRedirect |
176 } | 181 } |
177 var via []*Request | 182 var via []*Request |
178 | 183 |
179 if ireq.URL == nil { | 184 if ireq.URL == nil { |
180 return nil, errors.New("http: nil Request.URL") | 185 return nil, errors.New("http: nil Request.URL") |
181 } | 186 } |
182 | 187 |
| 188 jar := c.Jar |
| 189 if jar == nil { |
| 190 jar = blackHoleJar{} |
| 191 } |
| 192 |
183 req := ireq | 193 req := ireq |
184 urlStr := "" // next relative or absolute URL to fetch (after first requ
est) | 194 urlStr := "" // next relative or absolute URL to fetch (after first requ
est) |
185 for redirect := 0; ; redirect++ { | 195 for redirect := 0; ; redirect++ { |
186 if redirect != 0 { | 196 if redirect != 0 { |
187 req = new(Request) | 197 req = new(Request) |
188 req.Method = ireq.Method | 198 req.Method = ireq.Method |
189 req.Header = make(Header) | 199 req.Header = make(Header) |
190 req.URL, err = base.Parse(urlStr) | 200 req.URL, err = base.Parse(urlStr) |
191 if err != nil { | 201 if err != nil { |
192 break | 202 break |
193 } | 203 } |
194 if len(via) > 0 { | 204 if len(via) > 0 { |
195 // Add the Referer header. | 205 // Add the Referer header. |
196 lastReq := via[len(via)-1] | 206 lastReq := via[len(via)-1] |
197 if lastReq.URL.Scheme != "https" { | 207 if lastReq.URL.Scheme != "https" { |
198 req.Header.Set("Referer", lastReq.URL.St
ring()) | 208 req.Header.Set("Referer", lastReq.URL.St
ring()) |
199 } | 209 } |
200 | 210 |
201 err = redirectChecker(req, via) | 211 err = redirectChecker(req, via) |
202 if err != nil { | 212 if err != nil { |
203 break | 213 break |
204 } | 214 } |
205 } | 215 } |
| 216 for _, cookie := range jar.Cookies(req.URL) { |
| 217 req.AddCookie(cookie) |
| 218 } |
206 } | 219 } |
207 | 220 |
208 urlStr = req.URL.String() | 221 urlStr = req.URL.String() |
209 if r, err = send(req, c.Transport); err != nil { | 222 if r, err = send(req, c.Transport); err != nil { |
210 break | 223 break |
211 } | 224 } |
| 225 if c := r.Cookies(); len(c) > 0 { |
| 226 jar.SetCookies(req.URL, c) |
| 227 } |
| 228 |
212 if shouldRedirect(r.StatusCode) { | 229 if shouldRedirect(r.StatusCode) { |
213 r.Body.Close() | 230 r.Body.Close() |
214 if urlStr = r.Header.Get("Location"); urlStr == "" { | 231 if urlStr = r.Header.Get("Location"); urlStr == "" { |
215 err = errors.New(fmt.Sprintf("%d response missin
g Location header", r.StatusCode)) | 232 err = errors.New(fmt.Sprintf("%d response missin
g Location header", r.StatusCode)) |
216 break | 233 break |
217 } | 234 } |
218 base = req.URL | 235 base = req.URL |
219 via = append(via, req) | 236 via = append(via, req) |
220 continue | 237 continue |
221 } | 238 } |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
295 // 302 (Found) | 312 // 302 (Found) |
296 // 303 (See Other) | 313 // 303 (See Other) |
297 // 307 (Temporary Redirect) | 314 // 307 (Temporary Redirect) |
298 func (c *Client) Head(url string) (r *Response, err error) { | 315 func (c *Client) Head(url string) (r *Response, err error) { |
299 req, err := NewRequest("HEAD", url, nil) | 316 req, err := NewRequest("HEAD", url, nil) |
300 if err != nil { | 317 if err != nil { |
301 return nil, err | 318 return nil, err |
302 } | 319 } |
303 return c.doFollowingRedirects(req) | 320 return c.doFollowingRedirects(req) |
304 } | 321 } |
OLD | NEW |