OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 // This file contains URLFetcher, a wrapper around net::URLRequest that handles | |
6 // low-level details like thread safety, ref counting, and incremental buffer | |
7 // reading. This is useful for callers who simply want to get the data from a | |
8 // URL and don't care about all the nitty-gritty details. | |
9 // | |
10 // NOTE(willchan): Only one "IO" thread is supported for URLFetcher. This is a | |
11 // temporary situation. We will work on allowing support for multiple "io" | |
12 // threads per process. | |
13 | |
14 #ifndef CHROME_COMMON_NET_URL_FETCHER_H_ | |
15 #define CHROME_COMMON_NET_URL_FETCHER_H_ | |
16 #pragma once | |
17 | |
18 #include <string> | |
19 #include <vector> | |
20 | |
21 #include "base/memory/ref_counted.h" | |
22 #include "base/message_loop.h" | |
23 #include "base/platform_file.h" | |
24 #include "base/time.h" | |
25 | |
26 class FilePath; | |
27 class GURL; | |
28 | |
29 namespace base { | |
30 class MessageLoopProxy; | |
31 } // namespace base | |
32 | |
33 namespace net { | |
34 class HostPortPair; | |
35 class HttpResponseHeaders; | |
36 class URLRequestContextGetter; | |
37 class URLRequestStatus; | |
38 typedef std::vector<std::string> ResponseCookies; | |
39 } // namespace net | |
40 | |
41 // To use this class, create an instance with the desired URL and a pointer to | |
42 // the object to be notified when the URL has been loaded: | |
43 // URLFetcher* fetcher = new URLFetcher("http://www.google.com", | |
44 // URLFetcher::GET, this); | |
45 // | |
46 // Then, optionally set properties on this object, like the request context or | |
47 // extra headers: | |
48 // fetcher->SetExtraRequestHeaders("X-Foo: bar"); | |
49 // | |
50 // Finally, start the request: | |
51 // fetcher->Start(); | |
52 // | |
53 // | |
54 // The object you supply as a delegate must inherit from URLFetcher::Delegate; | |
55 // when the fetch is completed, OnURLFetchComplete() will be called with a | |
56 // pointer to the URLFetcher. From that point until the original URLFetcher | |
57 // instance is destroyed, you may use accessor methods to see the result of | |
58 // the fetch. You should copy these objects if you need them to live longer | |
59 // than the URLFetcher instance. If the URLFetcher instance is destroyed | |
60 // before the callback happens, the fetch will be canceled and no callback | |
61 // will occur. | |
62 // | |
63 // You may create the URLFetcher instance on any thread; OnURLFetchComplete() | |
64 // will be called back on the same thread you use to create the instance. | |
65 // | |
66 // | |
67 // NOTE: By default URLFetcher requests are NOT intercepted, except when | |
68 // interception is explicitly enabled in tests. | |
69 | |
70 class URLFetcher { | |
71 public: | |
72 enum RequestType { | |
73 GET, | |
74 POST, | |
75 HEAD, | |
76 }; | |
77 | |
78 // Imposible http response code. Used to signal that no http response code | |
79 // was received. | |
80 static const int kInvalidHttpResponseCode; | |
81 | |
82 class Delegate { | |
83 public: | |
84 // TODO(skerner): This will be removed in favor of the |source|-only | |
85 // version below. Leaving this for now to make the initial code review | |
86 // easy to read. | |
87 virtual void OnURLFetchComplete(const URLFetcher* source, | |
88 const GURL& url, | |
89 const net::URLRequestStatus& status, | |
90 int response_code, | |
91 const net::ResponseCookies& cookies, | |
92 const std::string& data); | |
93 | |
94 // This will be called when the URL has been fetched, successfully or not. | |
95 // Use accessor methods on |source| to get the results. | |
96 virtual void OnURLFetchComplete(const URLFetcher* source); | |
97 | |
98 protected: | |
99 virtual ~Delegate() {} | |
100 }; | |
101 | |
102 // URLFetcher::Create uses the currently registered Factory to create the | |
103 // URLFetcher. Factory is intended for testing. | |
104 class Factory { | |
105 public: | |
106 virtual URLFetcher* CreateURLFetcher(int id, | |
107 const GURL& url, | |
108 RequestType request_type, | |
109 Delegate* d) = 0; | |
110 | |
111 protected: | |
112 virtual ~Factory() {} | |
113 }; | |
114 | |
115 // |url| is the URL to send the request to. | |
116 // |request_type| is the type of request to make. | |
117 // |d| the object that will receive the callback on fetch completion. | |
118 URLFetcher(const GURL& url, RequestType request_type, Delegate* d); | |
119 | |
120 virtual ~URLFetcher(); | |
121 | |
122 // Sets the factory used by the static method Create to create a URLFetcher. | |
123 // URLFetcher does not take ownership of |factory|. A value of NULL results | |
124 // in a URLFetcher being created directly. | |
125 #if defined(UNIT_TEST) | |
126 static void set_factory(Factory* factory) { factory_ = factory; } | |
127 #endif | |
128 | |
129 // Normally interception is disabled for URLFetcher, but you can use this | |
130 // to enable it for tests. Also see the set_factory method for another way | |
131 // of testing code that uses an URLFetcher. | |
132 static void enable_interception_for_tests(bool enabled) { | |
133 g_interception_enabled = enabled; | |
134 } | |
135 | |
136 // Creates a URLFetcher, ownership returns to the caller. If there is no | |
137 // Factory (the default) this creates and returns a new URLFetcher. See the | |
138 // constructor for a description of the args. |id| may be used during testing | |
139 // to identify who is creating the URLFetcher. | |
140 static URLFetcher* Create(int id, const GURL& url, RequestType request_type, | |
141 Delegate* d); | |
142 | |
143 // Sets data only needed by POSTs. All callers making POST requests should | |
144 // call this before the request is started. |upload_content_type| is the MIME | |
145 // type of the content, while |upload_content| is the data to be sent (the | |
146 // Content-Length header value will be set to the length of this data). | |
147 void set_upload_data(const std::string& upload_content_type, | |
148 const std::string& upload_content); | |
149 | |
150 // Indicates that the POST data is sent via chunked transfer encoding. | |
151 // This may only be called before calling Start(). | |
152 // Use AppendChunkToUpload() to give the data chunks after calling Start(). | |
153 void set_chunked_upload(const std::string& upload_content_type); | |
154 | |
155 // Adds the given bytes to a request's POST data transmitted using chunked | |
156 // transfer encoding. | |
157 // This method should be called ONLY after calling Start(). | |
158 virtual void AppendChunkToUpload(const std::string& data, bool is_last_chunk); | |
159 | |
160 // Set one or more load flags as defined in net/base/load_flags.h. Must be | |
161 // called before the request is started. | |
162 void set_load_flags(int load_flags); | |
163 | |
164 // Returns the current load flags. | |
165 int load_flags() const; | |
166 | |
167 // The referrer URL for the request. Must be called before the request is | |
168 // started. | |
169 void set_referrer(const std::string& referrer); | |
170 | |
171 // Set extra headers on the request. Must be called before the request | |
172 // is started. | |
173 void set_extra_request_headers(const std::string& extra_request_headers); | |
174 | |
175 // Set the net::URLRequestContext on the request. Must be called before the | |
176 // request is started. | |
177 void set_request_context( | |
178 net::URLRequestContextGetter* request_context_getter); | |
179 | |
180 // If |retry| is false, 5xx responses will be propagated to the observer, | |
181 // if it is true URLFetcher will automatically re-execute the request, | |
182 // after backoff_delay() elapses. URLFetcher has it set to true by default. | |
183 void set_automatically_retry_on_5xx(bool retry); | |
184 | |
185 int max_retries() const { return max_retries_; } | |
186 | |
187 void set_max_retries(int max_retries) { max_retries_ = max_retries; } | |
188 | |
189 // Returns the back-off delay before the request will be retried, | |
190 // when a 5xx response was received. | |
191 base::TimeDelta backoff_delay() const { return backoff_delay_; } | |
192 | |
193 // Sets the back-off delay, allowing to mock 5xx requests in unit-tests. | |
194 #if defined(UNIT_TEST) | |
195 void set_backoff_delay(base::TimeDelta backoff_delay) { | |
196 backoff_delay_ = backoff_delay; | |
197 } | |
198 #endif // defined(UNIT_TEST) | |
199 | |
200 // By default, the response is saved in a string. Call this method to save the | |
201 // response to a temporary file instead. Must be called before Start(). | |
202 // |file_message_loop_proxy| will be used for all file operations. | |
203 void SaveResponseToTemporaryFile( | |
204 scoped_refptr<base::MessageLoopProxy> file_message_loop_proxy); | |
205 | |
206 // Retrieve the response headers from the request. Must only be called after | |
207 // the OnURLFetchComplete callback has run. | |
208 virtual net::HttpResponseHeaders* response_headers() const; | |
209 | |
210 // Retrieve the remote socket address from the request. Must only | |
211 // be called after the OnURLFetchComplete callback has run and if | |
212 // the request has not failed. | |
213 net::HostPortPair socket_address() const; | |
214 | |
215 // Returns true if the request was delivered through a proxy. Must only | |
216 // be called after the OnURLFetchComplete callback has run and the request | |
217 // has not failed. | |
218 bool was_fetched_via_proxy() const; | |
219 | |
220 // Start the request. After this is called, you may not change any other | |
221 // settings. | |
222 virtual void Start(); | |
223 | |
224 // Return the URL that this fetcher is processing. | |
225 virtual const GURL& url() const; | |
226 | |
227 // The status of the URL fetch. | |
228 virtual const net::URLRequestStatus& status() const; | |
229 | |
230 // The http response code received. Will return | |
231 // URLFetcher::kInvalidHttpResponseCode if an error prevented any response | |
232 // from being received. | |
233 virtual int response_code() const; | |
234 | |
235 // Cookies recieved. | |
236 virtual const net::ResponseCookies& cookies() const; | |
237 | |
238 // Return true if any file system operation failed. If so, set |error_code| | |
239 // to the error code. File system errors are only possible if user called | |
240 // SaveResponseToTemporaryFile(). | |
241 virtual bool FileErrorOccurred(base::PlatformFileError* out_error_code) const; | |
242 | |
243 // Reports that the received content was malformed. | |
244 void ReceivedContentWasMalformed(); | |
245 | |
246 // Get the response as a string. Return false if the fetcher was not | |
247 // set to store the response as a string. | |
248 virtual bool GetResponseAsString(std::string* out_response_string) const; | |
249 | |
250 // Get the path to the file containing the response body. Returns false | |
251 // if the response body was not saved to a file. If take_ownership is | |
252 // true, caller takes responsibility for the temp file, and it will not | |
253 // be removed once the URLFetcher is destroyed. | |
254 virtual bool GetResponseAsFilePath(bool take_ownership, | |
255 FilePath* out_response_path) const; | |
256 | |
257 // Cancels all existing URLFetchers. Will notify the URLFetcher::Delegates. | |
258 // Note that any new URLFetchers created while this is running will not be | |
259 // cancelled. Typically, one would call this in the CleanUp() method of an IO | |
260 // thread, so that no new URLRequests would be able to start on the IO thread | |
261 // anyway. This doesn't prevent new URLFetchers from trying to post to the IO | |
262 // thread though, even though the task won't ever run. | |
263 static void CancelAll(); | |
264 | |
265 protected: | |
266 // How should the response be stored? | |
267 enum ResponseDestinationType { | |
268 STRING, // Default: In a std::string | |
269 TEMP_FILE // Write to a temp file | |
270 }; | |
271 | |
272 // Returns the delegate. | |
273 Delegate* delegate() const; | |
274 | |
275 // Used by tests. | |
276 const std::string& upload_data() const; | |
277 | |
278 // Return a reference to the string data fetched. Response type must | |
279 // be STRING, or this will CHECK. This method exists to support the | |
280 // old signiture to OnURLFetchComplete(), and will be removed as part | |
281 // of crbug.com/83592 . | |
282 const std::string& GetResponseStringRef() const; | |
283 | |
284 void SetResponseDestinationForTesting(ResponseDestinationType); | |
285 ResponseDestinationType GetResponseDestinationForTesting() const; | |
286 | |
287 private: | |
288 friend class URLFetcherTest; | |
289 friend class TestURLFetcher; | |
290 | |
291 // Only used by URLFetcherTest, returns the number of URLFetcher::Core objects | |
292 // actively running. | |
293 static int GetNumFetcherCores(); | |
294 | |
295 class Core; | |
296 scoped_refptr<Core> core_; | |
297 | |
298 static Factory* factory_; | |
299 | |
300 // If |automatically_retry_on_5xx_| is false, 5xx responses will be | |
301 // propagated to the observer, if it is true URLFetcher will automatically | |
302 // re-execute the request, after the back-off delay has expired. | |
303 // true by default. | |
304 bool automatically_retry_on_5xx_; | |
305 // Back-off time delay. 0 by default. | |
306 base::TimeDelta backoff_delay_; | |
307 // Maximum retries allowed. | |
308 int max_retries_; | |
309 | |
310 static bool g_interception_enabled; | |
311 | |
312 DISALLOW_COPY_AND_ASSIGN(URLFetcher); | |
313 }; | |
314 | |
315 #endif // CHROME_COMMON_NET_URL_FETCHER_H_ | |
OLD | NEW |