OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 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 #ifndef NET_URL_REQUEST_URL_FETCHER_CORE_H_ | |
6 #define NET_URL_REQUEST_URL_FETCHER_CORE_H_ | |
7 | |
8 #include <set> | |
9 #include <string> | |
10 | |
11 #include "base/basictypes.h" | |
12 #include "base/compiler_specific.h" | |
13 #include "base/debug/stack_trace.h" | |
14 #include "base/files/file_path.h" | |
15 #include "base/lazy_instance.h" | |
16 #include "base/memory/ref_counted.h" | |
17 #include "base/memory/scoped_ptr.h" | |
18 #include "base/timer/timer.h" | |
19 #include "net/base/host_port_pair.h" | |
20 #include "net/http/http_request_headers.h" | |
21 #include "net/url_request/url_fetcher.h" | |
22 #include "net/url_request/url_request.h" | |
23 #include "net/url_request/url_request_status.h" | |
24 #include "url/gurl.h" | |
25 | |
26 namespace base { | |
27 class SingleThreadTaskRunner; | |
28 } // namespace base | |
29 | |
30 namespace net { | |
31 class DrainableIOBuffer; | |
32 class HttpResponseHeaders; | |
33 class IOBuffer; | |
34 class URLFetcherDelegate; | |
35 class URLFetcherResponseWriter; | |
36 class URLRequestContextGetter; | |
37 class URLRequestThrottlerEntryInterface; | |
38 | |
39 class URLFetcherCore | |
40 : public base::RefCountedThreadSafe<URLFetcherCore>, | |
41 public URLRequest::Delegate { | |
42 public: | |
43 URLFetcherCore(URLFetcher* fetcher, | |
44 const GURL& original_url, | |
45 URLFetcher::RequestType request_type, | |
46 URLFetcherDelegate* d); | |
47 | |
48 // Starts the load. It's important that this not happen in the constructor | |
49 // because it causes the IO thread to begin AddRef()ing and Release()ing | |
50 // us. If our caller hasn't had time to fully construct us and take a | |
51 // reference, the IO thread could interrupt things, run a task, Release() | |
52 // us, and destroy us, leaving the caller with an already-destroyed object | |
53 // when construction finishes. | |
54 void Start(); | |
55 | |
56 // Stops any in-progress load and ensures no callback will happen. It is | |
57 // safe to call this multiple times. | |
58 void Stop(); | |
59 | |
60 // URLFetcher-like functions. | |
61 | |
62 // For POST requests, set |content_type| to the MIME type of the | |
63 // content and set |content| to the data to upload. | |
64 void SetUploadData(const std::string& upload_content_type, | |
65 const std::string& upload_content); | |
66 void SetUploadFilePath(const std::string& upload_content_type, | |
67 const base::FilePath& file_path, | |
68 uint64 range_offset, | |
69 uint64 range_length, | |
70 scoped_refptr<base::TaskRunner> file_task_runner); | |
71 void SetUploadStreamFactory( | |
72 const std::string& upload_content_type, | |
73 const URLFetcher::CreateUploadStreamCallback& callback); | |
74 void SetChunkedUpload(const std::string& upload_content_type); | |
75 // Adds a block of data to be uploaded in a POST body. This can only be | |
76 // called after Start(). | |
77 void AppendChunkToUpload(const std::string& data, bool is_last_chunk); | |
78 // |flags| are flags to apply to the load operation--these should be | |
79 // one or more of the LOAD_* flags defined in net/base/load_flags.h. | |
80 void SetLoadFlags(int load_flags); | |
81 int GetLoadFlags() const; | |
82 void SetReferrer(const std::string& referrer); | |
83 void SetReferrerPolicy(URLRequest::ReferrerPolicy referrer_policy); | |
84 void SetExtraRequestHeaders(const std::string& extra_request_headers); | |
85 void AddExtraRequestHeader(const std::string& header_line); | |
86 void SetRequestContext(URLRequestContextGetter* request_context_getter); | |
87 // Set the URL that should be consulted for the third-party cookie | |
88 // blocking policy. | |
89 void SetFirstPartyForCookies(const GURL& first_party_for_cookies); | |
90 // Set the key and data callback that is used when setting the user | |
91 // data on any URLRequest objects this object creates. | |
92 void SetURLRequestUserData( | |
93 const void* key, | |
94 const URLFetcher::CreateDataCallback& create_data_callback); | |
95 void SetStopOnRedirect(bool stop_on_redirect); | |
96 void SetAutomaticallyRetryOn5xx(bool retry); | |
97 void SetMaxRetriesOn5xx(int max_retries); | |
98 int GetMaxRetriesOn5xx() const; | |
99 base::TimeDelta GetBackoffDelay() const; | |
100 void SetAutomaticallyRetryOnNetworkChanges(int max_retries); | |
101 void SaveResponseToFileAtPath( | |
102 const base::FilePath& file_path, | |
103 scoped_refptr<base::SequencedTaskRunner> file_task_runner); | |
104 void SaveResponseToTemporaryFile( | |
105 scoped_refptr<base::SequencedTaskRunner> file_task_runner); | |
106 void SaveResponseWithWriter( | |
107 scoped_ptr<URLFetcherResponseWriter> response_writer); | |
108 HttpResponseHeaders* GetResponseHeaders() const; | |
109 HostPortPair GetSocketAddress() const; | |
110 bool WasFetchedViaProxy() const; | |
111 const GURL& GetOriginalURL() const; | |
112 const GURL& GetURL() const; | |
113 const URLRequestStatus& GetStatus() const; | |
114 int GetResponseCode() const; | |
115 const ResponseCookies& GetCookies() const; | |
116 // Reports that the received content was malformed (i.e. failed parsing | |
117 // or validation). This makes the throttling logic that does exponential | |
118 // back-off when servers are having problems treat the current request as | |
119 // a failure. Your call to this method will be ignored if your request is | |
120 // already considered a failure based on the HTTP response code or response | |
121 // headers. | |
122 void ReceivedContentWasMalformed(); | |
123 bool GetResponseAsString(std::string* out_response_string) const; | |
124 bool GetResponseAsFilePath(bool take_ownership, | |
125 base::FilePath* out_response_path); | |
126 | |
127 // Overridden from URLRequest::Delegate: | |
128 void OnReceivedRedirect(URLRequest* request, | |
129 const RedirectInfo& redirect_info, | |
130 bool* defer_redirect) override; | |
131 void OnResponseStarted(URLRequest* request) override; | |
132 void OnReadCompleted(URLRequest* request, int bytes_read) override; | |
133 void OnCertificateRequested(URLRequest* request, | |
134 SSLCertRequestInfo* cert_request_info) override; | |
135 | |
136 URLFetcherDelegate* delegate() const { return delegate_; } | |
137 static void CancelAll(); | |
138 static int GetNumFetcherCores(); | |
139 static void SetEnableInterceptionForTests(bool enabled); | |
140 static void SetIgnoreCertificateRequests(bool ignored); | |
141 | |
142 private: | |
143 friend class base::RefCountedThreadSafe<URLFetcherCore>; | |
144 | |
145 class Registry { | |
146 public: | |
147 Registry(); | |
148 ~Registry(); | |
149 | |
150 void AddURLFetcherCore(URLFetcherCore* core); | |
151 void RemoveURLFetcherCore(URLFetcherCore* core); | |
152 | |
153 void CancelAll(); | |
154 | |
155 int size() const { | |
156 return fetchers_.size(); | |
157 } | |
158 | |
159 private: | |
160 std::set<URLFetcherCore*> fetchers_; | |
161 | |
162 DISALLOW_COPY_AND_ASSIGN(Registry); | |
163 }; | |
164 | |
165 ~URLFetcherCore() override; | |
166 | |
167 // Wrapper functions that allow us to ensure actions happen on the right | |
168 // thread. | |
169 void StartOnIOThread(); | |
170 void StartURLRequest(); | |
171 void DidInitializeWriter(int result); | |
172 void StartURLRequestWhenAppropriate(); | |
173 void CancelURLRequest(int error); | |
174 void OnCompletedURLRequest(base::TimeDelta backoff_delay); | |
175 void InformDelegateFetchIsComplete(); | |
176 void NotifyMalformedContent(); | |
177 void DidFinishWriting(int result); | |
178 void RetryOrCompleteUrlFetch(); | |
179 | |
180 // Deletes the request, removes it from the registry, and removes the | |
181 // destruction observer. | |
182 void ReleaseRequest(); | |
183 | |
184 // Returns the max value of exponential back-off release time for | |
185 // |original_url_| and |url_|. | |
186 base::TimeTicks GetBackoffReleaseTime(); | |
187 | |
188 void CompleteAddingUploadDataChunk(const std::string& data, | |
189 bool is_last_chunk); | |
190 | |
191 // Writes all bytes stored in |data| with |response_writer_|. | |
192 // Returns OK if all bytes in |data| get written synchronously. Otherwise, | |
193 // returns ERR_IO_PENDING or a network error code. | |
194 int WriteBuffer(scoped_refptr<DrainableIOBuffer> data); | |
195 | |
196 // Used to implement WriteBuffer(). | |
197 void DidWriteBuffer(scoped_refptr<DrainableIOBuffer> data, int result); | |
198 | |
199 // Read response bytes from the request. | |
200 void ReadResponse(); | |
201 | |
202 // Notify Delegate about the progress of upload/download. | |
203 void InformDelegateUploadProgress(); | |
204 void InformDelegateUploadProgressInDelegateThread(int64 current, int64 total); | |
205 void InformDelegateDownloadProgress(); | |
206 void InformDelegateDownloadProgressInDelegateThread(int64 current, | |
207 int64 total); | |
208 | |
209 // Check if any upload data is set or not. | |
210 void AssertHasNoUploadData() const; | |
211 | |
212 URLFetcher* fetcher_; // Corresponding fetcher object | |
213 GURL original_url_; // The URL we were asked to fetch | |
214 GURL url_; // The URL we eventually wound up at | |
215 URLFetcher::RequestType request_type_; // What type of request is this? | |
216 URLRequestStatus status_; // Status of the request | |
217 URLFetcherDelegate* delegate_; // Object to notify on completion | |
218 // Task runner for the creating thread. Used to interact with the delegate. | |
219 scoped_refptr<base::SingleThreadTaskRunner> delegate_task_runner_; | |
220 // Task runner for network operations. | |
221 scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_; | |
222 // Task runner for upload file access. | |
223 scoped_refptr<base::TaskRunner> upload_file_task_runner_; | |
224 scoped_ptr<URLRequest> request_; // The actual request this wraps | |
225 int load_flags_; // Flags for the load operation | |
226 int response_code_; // HTTP status code for the request | |
227 scoped_refptr<IOBuffer> buffer_; | |
228 // Read buffer | |
229 scoped_refptr<URLRequestContextGetter> request_context_getter_; | |
230 // Cookie/cache info for the request | |
231 GURL first_party_for_cookies_; // The first party URL for the request | |
232 // The user data to add to each newly-created URLRequest. | |
233 const void* url_request_data_key_; | |
234 URLFetcher::CreateDataCallback url_request_create_data_callback_; | |
235 ResponseCookies cookies_; // Response cookies | |
236 HttpRequestHeaders extra_request_headers_; | |
237 scoped_refptr<HttpResponseHeaders> response_headers_; | |
238 bool was_fetched_via_proxy_; | |
239 HostPortPair socket_address_; | |
240 | |
241 bool upload_content_set_; // SetUploadData has been called | |
242 std::string upload_content_; // HTTP POST payload | |
243 base::FilePath upload_file_path_; // Path to file containing POST payload | |
244 uint64 upload_range_offset_; // Offset from the beginning of the file | |
245 // to be uploaded. | |
246 uint64 upload_range_length_; // The length of the part of file to be | |
247 // uploaded. | |
248 URLFetcher::CreateUploadStreamCallback | |
249 upload_stream_factory_; // Callback to create HTTP POST payload. | |
250 std::string upload_content_type_; // MIME type of POST payload | |
251 std::string referrer_; // HTTP Referer header value and policy | |
252 URLRequest::ReferrerPolicy referrer_policy_; | |
253 bool is_chunked_upload_; // True if using chunked transfer encoding | |
254 | |
255 // Used to determine how long to wait before making a request or doing a | |
256 // retry. | |
257 // | |
258 // Both of them can only be accessed on the IO thread. | |
259 // | |
260 // To determine the proper backoff timing, throttler entries for | |
261 // both |original_URL| and |url| are needed. For example, consider | |
262 // the case that URL A redirects to URL B, for which the server | |
263 // returns a 500 response. In this case, the exponential back-off | |
264 // release time of URL A won't increase. If only the backoff | |
265 // constraints for URL A are considered, too many requests for URL A | |
266 // may be sent in a short period of time. | |
267 // | |
268 // Both of these will be NULL if | |
269 // URLRequestContext::throttler_manager() is NULL. | |
270 scoped_refptr<URLRequestThrottlerEntryInterface> | |
271 original_url_throttler_entry_; | |
272 scoped_refptr<URLRequestThrottlerEntryInterface> url_throttler_entry_; | |
273 | |
274 // True if the URLFetcher has been cancelled. | |
275 bool was_cancelled_; | |
276 | |
277 // Writer object to write response to the destination like file and string. | |
278 scoped_ptr<URLFetcherResponseWriter> response_writer_; | |
279 | |
280 // By default any server-initiated redirects are automatically followed. If | |
281 // this flag is set to true, however, a redirect will halt the fetch and call | |
282 // back to to the delegate immediately. | |
283 bool stop_on_redirect_; | |
284 // True when we're actually stopped due to a redirect halted by the above. We | |
285 // use this to ensure that |url_| is set to the redirect destination rather | |
286 // than the originally-fetched URL. | |
287 bool stopped_on_redirect_; | |
288 | |
289 // If |automatically_retry_on_5xx_| is false, 5xx responses will be | |
290 // propagated to the observer, if it is true URLFetcher will automatically | |
291 // re-execute the request, after the back-off delay has expired. | |
292 // true by default. | |
293 bool automatically_retry_on_5xx_; | |
294 // |num_retries_on_5xx_| indicates how many times we've failed to successfully | |
295 // fetch this URL due to 5xx responses. Once this value exceeds the maximum | |
296 // number of retries specified by the owner URLFetcher instance, | |
297 // we'll give up. | |
298 int num_retries_on_5xx_; | |
299 // Maximum retries allowed when 5xx responses are received. | |
300 int max_retries_on_5xx_; | |
301 // Back-off time delay. 0 by default. | |
302 base::TimeDelta backoff_delay_; | |
303 | |
304 // The number of retries that have been attempted due to ERR_NETWORK_CHANGED. | |
305 int num_retries_on_network_changes_; | |
306 // Maximum retries allowed when the request fails with ERR_NETWORK_CHANGED. | |
307 // 0 by default. | |
308 int max_retries_on_network_changes_; | |
309 | |
310 // Timer to poll the progress of uploading for POST and PUT requests. | |
311 // When crbug.com/119629 is fixed, scoped_ptr is not necessary here. | |
312 scoped_ptr<base::RepeatingTimer<URLFetcherCore> > | |
313 upload_progress_checker_timer_; | |
314 // Number of bytes sent so far. | |
315 int64 current_upload_bytes_; | |
316 // Number of bytes received so far. | |
317 int64 current_response_bytes_; | |
318 // Total expected bytes to receive (-1 if it cannot be determined). | |
319 int64 total_response_bytes_; | |
320 | |
321 // TODO(willchan): Get rid of this after debugging crbug.com/90971. | |
322 base::debug::StackTrace stack_trace_; | |
323 | |
324 static base::LazyInstance<Registry> g_registry; | |
325 | |
326 DISALLOW_COPY_AND_ASSIGN(URLFetcherCore); | |
327 }; | |
328 | |
329 } // namespace net | |
330 | |
331 #endif // NET_URL_REQUEST_URL_FETCHER_CORE_H_ | |
OLD | NEW |