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