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