| 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 |