LEFT | RIGHT |
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 // Primitive HTTP client. See RFC 2616. | 5 // Primitive HTTP client. See RFC 2616. |
6 | 6 |
7 package http | 7 package http |
8 | 8 |
9 import ( | 9 import ( |
10 "encoding/base64" | 10 "encoding/base64" |
11 "fmt" | 11 "fmt" |
12 "io" | 12 "io" |
13 "os" | 13 "os" |
14 "strings" | 14 "strings" |
15 ) | 15 ) |
16 | 16 |
17 // A Client is an HTTP client. Its zero value (DefaultClient) is a usable client | 17 // A Client is an HTTP client. Its zero value (DefaultClient) is a usable client |
18 // that uses DefaultTransport. | 18 // that uses DefaultTransport. |
| 19 // |
| 20 // The Client's Transport typically has internal state (cached |
| 21 // TCP connections), so Clients should be reused instead of created as |
| 22 // needed. Clients are safe for concurrent use by multiple goroutines. |
| 23 // |
19 // Client is not yet very configurable. | 24 // Client is not yet very configurable. |
20 type Client struct { | 25 type Client struct { |
21 Transport RoundTripper // if nil, DefaultTransport is used | 26 Transport RoundTripper // if nil, DefaultTransport is used |
22 | 27 |
23 // If CheckRedirect is not nil, the client calls it before | 28 // If CheckRedirect is not nil, the client calls it before |
24 // following an HTTP redirect. The arguments req and via | 29 // following an HTTP redirect. The arguments req and via |
25 // are the upcoming request and the requests made already, | 30 // are the upcoming request and the requests made already, |
26 // oldest first. If CheckRedirect returns an error, the client | 31 // oldest first. If CheckRedirect returns an error, the client |
27 // returns that error instead of issue the Request req. | 32 // returns that error instead of issue the Request req. |
28 // | 33 // |
29 // If CheckRedirect is nil, the Client uses its default policy, | 34 // If CheckRedirect is nil, the Client uses its default policy, |
30 // which is to stop after 10 consecutive requests. | 35 // which is to stop after 10 consecutive requests. |
31 CheckRedirect func(req *Request, via []*Request) os.Error | 36 CheckRedirect func(req *Request, via []*Request) os.Error |
32 } | 37 } |
33 | 38 |
34 // DefaultClient is the default Client and is used by Get, Head, and Post. | 39 // DefaultClient is the default Client and is used by Get, Head, and Post. |
35 var DefaultClient = &Client{} | 40 var DefaultClient = &Client{} |
36 | 41 |
37 // RoundTripper is an interface representing the ability to execute a | 42 // RoundTripper is an interface representing the ability to execute a |
38 // single HTTP transaction, obtaining the Response for a given Request. | 43 // single HTTP transaction, obtaining the Response for a given Request. |
| 44 // |
| 45 // A RoundTripper must be safe for concurrent use by multiple |
| 46 // goroutines. |
39 type RoundTripper interface { | 47 type RoundTripper interface { |
40 // RoundTrip executes a single HTTP transaction, returning | 48 // RoundTrip executes a single HTTP transaction, returning |
41 // the Response for the request req. RoundTrip should not | 49 // the Response for the request req. RoundTrip should not |
42 // attempt to interpret the response. In particular, | 50 // attempt to interpret the response. In particular, |
43 // RoundTrip must return err == nil if it obtained a response, | 51 // RoundTrip must return err == nil if it obtained a response, |
44 // regardless of the response's HTTP status code. A non-nil | 52 // regardless of the response's HTTP status code. A non-nil |
45 // err should be reserved for failure to obtain a response. | 53 // err should be reserved for failure to obtain a response. |
46 // Similarly, RoundTrip should not attempt to handle | 54 // Similarly, RoundTrip should not attempt to handle |
47 // higher-level protocol details such as redirects, | 55 // higher-level protocol details such as redirects, |
48 // authentication, or cookies. | 56 // authentication, or cookies. |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
166 req.Method = ireq.Method | 174 req.Method = ireq.Method |
167 req.Header = make(Header) | 175 req.Header = make(Header) |
168 req.URL, err = base.ParseURL(url) | 176 req.URL, err = base.ParseURL(url) |
169 if err != nil { | 177 if err != nil { |
170 break | 178 break |
171 } | 179 } |
172 if len(via) > 0 { | 180 if len(via) > 0 { |
173 // Add the Referer header. | 181 // Add the Referer header. |
174 lastReq := via[len(via)-1] | 182 lastReq := via[len(via)-1] |
175 if lastReq.URL.Scheme != "https" { | 183 if lastReq.URL.Scheme != "https" { |
176 » » » » » req.Referer = lastReq.URL.String() | 184 » » » » » req.Header.Set("Referer", lastReq.URL.St
ring()) |
177 } | 185 } |
178 | 186 |
179 err = redirectChecker(req, via) | 187 err = redirectChecker(req, via) |
180 if err != nil { | 188 if err != nil { |
181 break | 189 break |
182 } | 190 } |
183 } | 191 } |
184 } | 192 } |
185 | 193 |
186 url = req.URL.String() | 194 url = req.URL.String() |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
273 // 302 (Found) | 281 // 302 (Found) |
274 // 303 (See Other) | 282 // 303 (See Other) |
275 // 307 (Temporary Redirect) | 283 // 307 (Temporary Redirect) |
276 func (c *Client) Head(url string) (r *Response, err os.Error) { | 284 func (c *Client) Head(url string) (r *Response, err os.Error) { |
277 req, err := NewRequest("HEAD", url, nil) | 285 req, err := NewRequest("HEAD", url, nil) |
278 if err != nil { | 286 if err != nil { |
279 return nil, err | 287 return nil, err |
280 } | 288 } |
281 return c.doFollowingRedirects(req) | 289 return c.doFollowingRedirects(req) |
282 } | 290 } |
LEFT | RIGHT |