| 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_TEST_URL_FETCHER_FACTORY_H_ | |
| 6 #define NET_URL_REQUEST_TEST_URL_FETCHER_FACTORY_H_ | |
| 7 | |
| 8 #include <list> | |
| 9 #include <map> | |
| 10 #include <string> | |
| 11 #include <utility> | |
| 12 | |
| 13 #include "base/basictypes.h" | |
| 14 #include "base/callback.h" | |
| 15 #include "base/compiler_specific.h" | |
| 16 #include "base/files/file_path.h" | |
| 17 #include "base/memory/scoped_ptr.h" | |
| 18 #include "base/memory/weak_ptr.h" | |
| 19 #include "base/threading/non_thread_safe.h" | |
| 20 #include "net/http/http_request_headers.h" | |
| 21 #include "net/http/http_status_code.h" | |
| 22 #include "net/url_request/url_fetcher_factory.h" | |
| 23 #include "net/url_request/url_request_status.h" | |
| 24 #include "url/gurl.h" | |
| 25 | |
| 26 namespace net { | |
| 27 | |
| 28 // Changes URLFetcher's Factory for the lifetime of the object. | |
| 29 // Note that this scoper cannot be nested (to make it even harder to misuse). | |
| 30 class ScopedURLFetcherFactory : public base::NonThreadSafe { | |
| 31 public: | |
| 32 explicit ScopedURLFetcherFactory(URLFetcherFactory* factory); | |
| 33 virtual ~ScopedURLFetcherFactory(); | |
| 34 | |
| 35 private: | |
| 36 DISALLOW_COPY_AND_ASSIGN(ScopedURLFetcherFactory); | |
| 37 }; | |
| 38 | |
| 39 // TestURLFetcher and TestURLFetcherFactory are used for testing consumers of | |
| 40 // URLFetcher. TestURLFetcherFactory is a URLFetcherFactory that creates | |
| 41 // TestURLFetchers. TestURLFetcher::Start is overriden to do nothing. It is | |
| 42 // expected that you'll grab the delegate from the TestURLFetcher and invoke | |
| 43 // the callback method when appropriate. In this way it's easy to mock a | |
| 44 // URLFetcher. | |
| 45 // Typical usage: | |
| 46 // // TestURLFetcher requires a MessageLoop. | |
| 47 // MessageLoop message_loop; | |
| 48 // // And an IO thread to release URLRequestContextGetter in URLFetcher::Core. | |
| 49 // BrowserThreadImpl io_thread(BrowserThread::IO, &message_loop); | |
| 50 // // Create factory (it automatically sets itself as URLFetcher's factory). | |
| 51 // TestURLFetcherFactory factory; | |
| 52 // // Do something that triggers creation of a URLFetcher. | |
| 53 // ... | |
| 54 // TestURLFetcher* fetcher = factory.GetFetcherByID(expected_id); | |
| 55 // DCHECK(fetcher); | |
| 56 // // Notify delegate with whatever data you want. | |
| 57 // fetcher->delegate()->OnURLFetchComplete(...); | |
| 58 // // Make sure consumer of URLFetcher does the right thing. | |
| 59 // ... | |
| 60 // | |
| 61 // Note: if you don't know when your request objects will be created you | |
| 62 // might want to use the FakeURLFetcher and FakeURLFetcherFactory classes | |
| 63 // below. | |
| 64 | |
| 65 class TestURLFetcherFactory; | |
| 66 class TestURLFetcher : public URLFetcher { | |
| 67 public: | |
| 68 // Interface for tests to intercept production code classes using URLFetcher. | |
| 69 // Allows even-driven mock server classes to analyze the correctness of | |
| 70 // requests / uploads events and forge responses back at the right moment. | |
| 71 class DelegateForTests { | |
| 72 public: | |
| 73 // Callback issued correspondingly to the call to the |Start()| method. | |
| 74 virtual void OnRequestStart(int fetcher_id) = 0; | |
| 75 | |
| 76 // Callback issued correspondingly to the call to |AppendChunkToUpload|. | |
| 77 // Uploaded chunks can be retrieved with the |upload_chunks()| getter. | |
| 78 virtual void OnChunkUpload(int fetcher_id) = 0; | |
| 79 | |
| 80 // Callback issued correspondingly to the destructor. | |
| 81 virtual void OnRequestEnd(int fetcher_id) = 0; | |
| 82 }; | |
| 83 | |
| 84 TestURLFetcher(int id, | |
| 85 const GURL& url, | |
| 86 URLFetcherDelegate* d); | |
| 87 ~TestURLFetcher() override; | |
| 88 | |
| 89 // URLFetcher implementation | |
| 90 void SetUploadData(const std::string& upload_content_type, | |
| 91 const std::string& upload_content) override; | |
| 92 void SetUploadFilePath( | |
| 93 const std::string& upload_content_type, | |
| 94 const base::FilePath& file_path, | |
| 95 uint64 range_offset, | |
| 96 uint64 range_length, | |
| 97 scoped_refptr<base::TaskRunner> file_task_runner) override; | |
| 98 void SetUploadStreamFactory( | |
| 99 const std::string& upload_content_type, | |
| 100 const CreateUploadStreamCallback& callback) override; | |
| 101 void SetChunkedUpload(const std::string& upload_content_type) override; | |
| 102 // Overriden to cache the chunks uploaded. Caller can read back the uploaded | |
| 103 // chunks with the upload_chunks() accessor. | |
| 104 void AppendChunkToUpload(const std::string& data, | |
| 105 bool is_last_chunk) override; | |
| 106 void SetLoadFlags(int load_flags) override; | |
| 107 int GetLoadFlags() const override; | |
| 108 void SetReferrer(const std::string& referrer) override; | |
| 109 void SetReferrerPolicy(URLRequest::ReferrerPolicy referrer_policy) override; | |
| 110 void SetExtraRequestHeaders( | |
| 111 const std::string& extra_request_headers) override; | |
| 112 void AddExtraRequestHeader(const std::string& header_line) override; | |
| 113 void SetRequestContext( | |
| 114 URLRequestContextGetter* request_context_getter) override; | |
| 115 void SetFirstPartyForCookies(const GURL& first_party_for_cookies) override; | |
| 116 void SetURLRequestUserData( | |
| 117 const void* key, | |
| 118 const CreateDataCallback& create_data_callback) override; | |
| 119 void SetStopOnRedirect(bool stop_on_redirect) override; | |
| 120 void SetAutomaticallyRetryOn5xx(bool retry) override; | |
| 121 void SetMaxRetriesOn5xx(int max_retries) override; | |
| 122 int GetMaxRetriesOn5xx() const override; | |
| 123 base::TimeDelta GetBackoffDelay() const override; | |
| 124 void SetAutomaticallyRetryOnNetworkChanges(int max_retries) override; | |
| 125 void SaveResponseToFileAtPath( | |
| 126 const base::FilePath& file_path, | |
| 127 scoped_refptr<base::SequencedTaskRunner> file_task_runner) override; | |
| 128 void SaveResponseToTemporaryFile( | |
| 129 scoped_refptr<base::SequencedTaskRunner> file_task_runner) override; | |
| 130 void SaveResponseWithWriter( | |
| 131 scoped_ptr<URLFetcherResponseWriter> response_writer) override; | |
| 132 HttpResponseHeaders* GetResponseHeaders() const override; | |
| 133 HostPortPair GetSocketAddress() const override; | |
| 134 bool WasFetchedViaProxy() const override; | |
| 135 void Start() override; | |
| 136 | |
| 137 // URL we were created with. Because of how we're using URLFetcher GetURL() | |
| 138 // always returns an empty URL. Chances are you'll want to use | |
| 139 // GetOriginalURL() in your tests. | |
| 140 const GURL& GetOriginalURL() const override; | |
| 141 const GURL& GetURL() const override; | |
| 142 const URLRequestStatus& GetStatus() const override; | |
| 143 int GetResponseCode() const override; | |
| 144 const ResponseCookies& GetCookies() const override; | |
| 145 void ReceivedContentWasMalformed() override; | |
| 146 // Override response access functions to return fake data. | |
| 147 bool GetResponseAsString(std::string* out_response_string) const override; | |
| 148 bool GetResponseAsFilePath(bool take_ownership, | |
| 149 base::FilePath* out_response_path) const override; | |
| 150 | |
| 151 void GetExtraRequestHeaders(HttpRequestHeaders* headers) const; | |
| 152 | |
| 153 // Sets owner of this class. Set it to a non-NULL value if you want | |
| 154 // to automatically unregister this fetcher from the owning factory | |
| 155 // upon destruction. | |
| 156 void set_owner(TestURLFetcherFactory* owner) { owner_ = owner; } | |
| 157 | |
| 158 // Unique ID in our factory. | |
| 159 int id() const { return id_; } | |
| 160 | |
| 161 // Returns the data uploaded on this URLFetcher. | |
| 162 const std::string& upload_content_type() const { | |
| 163 return upload_content_type_; | |
| 164 } | |
| 165 const std::string& upload_data() const { return upload_data_; } | |
| 166 const base::FilePath& upload_file_path() const { return upload_file_path_; } | |
| 167 | |
| 168 // Returns the chunks of data uploaded on this URLFetcher. | |
| 169 const std::list<std::string>& upload_chunks() const { return chunks_; } | |
| 170 | |
| 171 // Checks whether the last call to |AppendChunkToUpload(...)| was final. | |
| 172 bool did_receive_last_chunk() const { return did_receive_last_chunk_; } | |
| 173 | |
| 174 // Returns the delegate installed on the URLFetcher. | |
| 175 URLFetcherDelegate* delegate() const { return delegate_; } | |
| 176 | |
| 177 void set_url(const GURL& url) { fake_url_ = url; } | |
| 178 void set_status(const URLRequestStatus& status); | |
| 179 void set_response_code(int response_code) { | |
| 180 fake_response_code_ = response_code; | |
| 181 } | |
| 182 void set_cookies(const ResponseCookies& c) { fake_cookies_ = c; } | |
| 183 void set_was_fetched_via_proxy(bool flag); | |
| 184 void set_response_headers(scoped_refptr<HttpResponseHeaders> headers); | |
| 185 void set_backoff_delay(base::TimeDelta backoff_delay); | |
| 186 void SetDelegateForTests(DelegateForTests* delegate_for_tests); | |
| 187 | |
| 188 // Set string data. | |
| 189 void SetResponseString(const std::string& response); | |
| 190 | |
| 191 // Set File data. | |
| 192 void SetResponseFilePath(const base::FilePath& path); | |
| 193 | |
| 194 private: | |
| 195 enum ResponseDestinationType { | |
| 196 STRING, // Default: In a std::string | |
| 197 TEMP_FILE // Write to a temp file | |
| 198 }; | |
| 199 | |
| 200 TestURLFetcherFactory* owner_; | |
| 201 const int id_; | |
| 202 const GURL original_url_; | |
| 203 URLFetcherDelegate* delegate_; | |
| 204 DelegateForTests* delegate_for_tests_; | |
| 205 std::string upload_content_type_; | |
| 206 std::string upload_data_; | |
| 207 base::FilePath upload_file_path_; | |
| 208 std::list<std::string> chunks_; | |
| 209 bool did_receive_last_chunk_; | |
| 210 | |
| 211 // User can use set_* methods to provide values returned by getters. | |
| 212 // Setting the real values is not possible, because the real class | |
| 213 // has no setters. The data is a private member of a class defined | |
| 214 // in a .cc file, so we can't get at it with friendship. | |
| 215 int fake_load_flags_; | |
| 216 GURL fake_url_; | |
| 217 URLRequestStatus fake_status_; | |
| 218 int fake_response_code_; | |
| 219 ResponseCookies fake_cookies_; | |
| 220 ResponseDestinationType fake_response_destination_; | |
| 221 std::string fake_response_string_; | |
| 222 base::FilePath fake_response_file_path_; | |
| 223 bool fake_was_fetched_via_proxy_; | |
| 224 scoped_refptr<HttpResponseHeaders> fake_response_headers_; | |
| 225 HttpRequestHeaders fake_extra_request_headers_; | |
| 226 int fake_max_retries_; | |
| 227 base::TimeDelta fake_backoff_delay_; | |
| 228 scoped_ptr<URLFetcherResponseWriter> response_writer_; | |
| 229 | |
| 230 DISALLOW_COPY_AND_ASSIGN(TestURLFetcher); | |
| 231 }; | |
| 232 | |
| 233 typedef TestURLFetcher::DelegateForTests TestURLFetcherDelegateForTests; | |
| 234 | |
| 235 // Simple URLFetcherFactory method that creates TestURLFetchers. All fetchers | |
| 236 // are registered in a map by the id passed to the create method. | |
| 237 // Optionally, a fetcher may be automatically unregistered from the map upon | |
| 238 // its destruction. | |
| 239 class TestURLFetcherFactory : public URLFetcherFactory, | |
| 240 public ScopedURLFetcherFactory { | |
| 241 public: | |
| 242 TestURLFetcherFactory(); | |
| 243 ~TestURLFetcherFactory() override; | |
| 244 | |
| 245 URLFetcher* CreateURLFetcher(int id, | |
| 246 const GURL& url, | |
| 247 URLFetcher::RequestType request_type, | |
| 248 URLFetcherDelegate* d) override; | |
| 249 TestURLFetcher* GetFetcherByID(int id) const; | |
| 250 void RemoveFetcherFromMap(int id); | |
| 251 void SetDelegateForTests(TestURLFetcherDelegateForTests* delegate_for_tests); | |
| 252 void set_remove_fetcher_on_delete(bool remove_fetcher_on_delete) { | |
| 253 remove_fetcher_on_delete_ = remove_fetcher_on_delete; | |
| 254 } | |
| 255 | |
| 256 private: | |
| 257 // Maps from id passed to create to the returned URLFetcher. | |
| 258 typedef std::map<int, TestURLFetcher*> Fetchers; | |
| 259 Fetchers fetchers_; | |
| 260 TestURLFetcherDelegateForTests* delegate_for_tests_; | |
| 261 // Whether to automatically unregister a fetcher from this factory upon its | |
| 262 // destruction, false by default. | |
| 263 bool remove_fetcher_on_delete_; | |
| 264 | |
| 265 DISALLOW_COPY_AND_ASSIGN(TestURLFetcherFactory); | |
| 266 }; | |
| 267 | |
| 268 // The FakeURLFetcher and FakeURLFetcherFactory classes are similar to the | |
| 269 // ones above but don't require you to know when exactly the URLFetcher objects | |
| 270 // will be created. | |
| 271 // | |
| 272 // These classes let you set pre-baked HTTP responses for particular URLs. | |
| 273 // E.g., if the user requests http://a.com/ then respond with an HTTP/500. | |
| 274 // | |
| 275 // We assume that the thread that is calling Start() on the URLFetcher object | |
| 276 // has a message loop running. | |
| 277 | |
| 278 // FakeURLFetcher can be used to create a URLFetcher that will emit a fake | |
| 279 // response when started. This class can be used in place of an actual | |
| 280 // URLFetcher. | |
| 281 // | |
| 282 // Example usage: | |
| 283 // FakeURLFetcher fake_fetcher("http://a.com", some_delegate, | |
| 284 // "<html><body>hello world</body></html>", | |
| 285 // HTTP_OK); | |
| 286 // | |
| 287 // // Will schedule a call to some_delegate->OnURLFetchComplete(&fake_fetcher). | |
| 288 // fake_fetcher.Start(); | |
| 289 class FakeURLFetcher : public TestURLFetcher { | |
| 290 public: | |
| 291 // Normal URL fetcher constructor but also takes in a pre-baked response. | |
| 292 FakeURLFetcher(const GURL& url, | |
| 293 URLFetcherDelegate* d, | |
| 294 const std::string& response_data, | |
| 295 HttpStatusCode response_code, | |
| 296 URLRequestStatus::Status status); | |
| 297 | |
| 298 // Start the request. This will call the given delegate asynchronously | |
| 299 // with the pre-baked response as parameter. | |
| 300 void Start() override; | |
| 301 | |
| 302 const GURL& GetURL() const override; | |
| 303 | |
| 304 ~FakeURLFetcher() override; | |
| 305 | |
| 306 private: | |
| 307 // This is the method which actually calls the delegate that is passed in the | |
| 308 // constructor. | |
| 309 void RunDelegate(); | |
| 310 | |
| 311 base::WeakPtrFactory<FakeURLFetcher> weak_factory_; | |
| 312 | |
| 313 DISALLOW_COPY_AND_ASSIGN(FakeURLFetcher); | |
| 314 }; | |
| 315 | |
| 316 | |
| 317 // FakeURLFetcherFactory is a factory for FakeURLFetcher objects. When | |
| 318 // instantiated, it sets itself up as the default URLFetcherFactory. Fake | |
| 319 // responses for given URLs can be set using SetFakeResponse. | |
| 320 // | |
| 321 // This class is not thread-safe. You should not call SetFakeResponse or | |
| 322 // ClearFakeResponse at the same time you call CreateURLFetcher. However, it is | |
| 323 // OK to start URLFetcher objects while setting or clearing fake responses | |
| 324 // since already created URLFetcher objects will not be affected by any changes | |
| 325 // made to the fake responses (once a URLFetcher object is created you cannot | |
| 326 // change its fake response). | |
| 327 // | |
| 328 // Example usage: | |
| 329 // FakeURLFetcherFactory factory; | |
| 330 // | |
| 331 // // You know that class SomeService will request http://a.com/success and you | |
| 332 // // want to respond with a simple html page and an HTTP/200 code. | |
| 333 // factory.SetFakeResponse("http://a.com/success", | |
| 334 // "<html><body>hello world</body></html>", | |
| 335 // HTTP_OK, | |
| 336 // URLRequestStatus::SUCCESS); | |
| 337 // // You know that class SomeService will request url http://a.com/servererror | |
| 338 // // and you want to test the service class by returning a server error. | |
| 339 // factory.SetFakeResponse("http://a.com/servererror", | |
| 340 // "", | |
| 341 // HTTP_INTERNAL_SERVER_ERROR, | |
| 342 // URLRequestStatus::SUCCESS); | |
| 343 // // You know that class SomeService will request url http://a.com/autherror | |
| 344 // // and you want to test the service class by returning a specific error | |
| 345 // // code, say, a HTTP/401 error. | |
| 346 // factory.SetFakeResponse("http://a.com/autherror", | |
| 347 // "some_response", | |
| 348 // HTTP_UNAUTHORIZED, | |
| 349 // URLRequestStatus::SUCCESS); | |
| 350 // | |
| 351 // // You know that class SomeService will request url http://a.com/failure | |
| 352 // // and you want to test the service class by returning a failure in the | |
| 353 // // network layer. | |
| 354 // factory.SetFakeResponse("http://a.com/failure", | |
| 355 // "", | |
| 356 // HTTP_INTERNAL_SERVER_ERROR, | |
| 357 // URLRequestStatus::FAILURE); | |
| 358 // | |
| 359 // SomeService service; | |
| 360 // service.Run(); // Will eventually request these three URLs. | |
| 361 class FakeURLFetcherFactory : public URLFetcherFactory, | |
| 362 public ScopedURLFetcherFactory { | |
| 363 public: | |
| 364 // Parameters to FakeURLFetcherCreator: url, delegate, response_data, | |
| 365 // response_code | |
| 366 // |url| URL for instantiated FakeURLFetcher | |
| 367 // |delegate| Delegate for FakeURLFetcher | |
| 368 // |response_data| response data for FakeURLFetcher | |
| 369 // |response_code| response code for FakeURLFetcher | |
| 370 // |status| URL fetch status for FakeURLFetcher | |
| 371 // These arguments should by default be used in instantiating FakeURLFetcher | |
| 372 // like so: | |
| 373 // new FakeURLFetcher(url, delegate, response_data, response_code, status) | |
| 374 typedef base::Callback<scoped_ptr<FakeURLFetcher>( | |
| 375 const GURL&, | |
| 376 URLFetcherDelegate*, | |
| 377 const std::string&, | |
| 378 HttpStatusCode, | |
| 379 URLRequestStatus::Status)> FakeURLFetcherCreator; | |
| 380 | |
| 381 // |default_factory|, which can be NULL, is a URLFetcherFactory that | |
| 382 // will be used to construct a URLFetcher in case the URL being created | |
| 383 // has no pre-baked response. If it is NULL, a URLFetcherImpl will be | |
| 384 // created in this case. | |
| 385 explicit FakeURLFetcherFactory(URLFetcherFactory* default_factory); | |
| 386 | |
| 387 // |default_factory|, which can be NULL, is a URLFetcherFactory that | |
| 388 // will be used to construct a URLFetcher in case the URL being created | |
| 389 // has no pre-baked response. If it is NULL, a URLFetcherImpl will be | |
| 390 // created in this case. | |
| 391 // |creator| is a callback that returns will be called to create a | |
| 392 // FakeURLFetcher if a response is found to a given URL. It can be | |
| 393 // set to MakeFakeURLFetcher. | |
| 394 FakeURLFetcherFactory(URLFetcherFactory* default_factory, | |
| 395 const FakeURLFetcherCreator& creator); | |
| 396 | |
| 397 ~FakeURLFetcherFactory() override; | |
| 398 | |
| 399 // If no fake response is set for the given URL this method will delegate the | |
| 400 // call to |default_factory_| if it is not NULL, or return NULL if it is | |
| 401 // NULL. | |
| 402 // Otherwise, it will return a URLFetcher object which will respond with the | |
| 403 // pre-baked response that the client has set by calling SetFakeResponse(). | |
| 404 URLFetcher* CreateURLFetcher(int id, | |
| 405 const GURL& url, | |
| 406 URLFetcher::RequestType request_type, | |
| 407 URLFetcherDelegate* d) override; | |
| 408 | |
| 409 // Sets the fake response for a given URL. The |response_data| may be empty. | |
| 410 // The |response_code| may be any HttpStatusCode. For instance, HTTP_OK will | |
| 411 // return an HTTP/200 and HTTP_INTERNAL_SERVER_ERROR will return an HTTP/500. | |
| 412 // The |status| argument may be any URLRequestStatus::Status value. Typically, | |
| 413 // requests that return a valid HttpStatusCode have the SUCCESS status, while | |
| 414 // requests that indicate a failure to connect to the server have the FAILED | |
| 415 // status. | |
| 416 void SetFakeResponse(const GURL& url, | |
| 417 const std::string& response_data, | |
| 418 HttpStatusCode response_code, | |
| 419 URLRequestStatus::Status status); | |
| 420 | |
| 421 // Clear all the fake responses that were previously set via | |
| 422 // SetFakeResponse(). | |
| 423 void ClearFakeResponses(); | |
| 424 | |
| 425 private: | |
| 426 struct FakeURLResponse { | |
| 427 std::string response_data; | |
| 428 HttpStatusCode response_code; | |
| 429 URLRequestStatus::Status status; | |
| 430 }; | |
| 431 typedef std::map<GURL, FakeURLResponse> FakeResponseMap; | |
| 432 | |
| 433 const FakeURLFetcherCreator creator_; | |
| 434 FakeResponseMap fake_responses_; | |
| 435 URLFetcherFactory* const default_factory_; | |
| 436 | |
| 437 static scoped_ptr<FakeURLFetcher> DefaultFakeURLFetcherCreator( | |
| 438 const GURL& url, | |
| 439 URLFetcherDelegate* delegate, | |
| 440 const std::string& response_data, | |
| 441 HttpStatusCode response_code, | |
| 442 URLRequestStatus::Status status); | |
| 443 DISALLOW_COPY_AND_ASSIGN(FakeURLFetcherFactory); | |
| 444 }; | |
| 445 | |
| 446 // This is an implementation of URLFetcherFactory that will create a | |
| 447 // URLFetcherImpl. It can be use in conjunction with a FakeURLFetcherFactory in | |
| 448 // integration tests to control the behavior of some requests but execute | |
| 449 // all the other ones. | |
| 450 class URLFetcherImplFactory : public URLFetcherFactory { | |
| 451 public: | |
| 452 URLFetcherImplFactory(); | |
| 453 ~URLFetcherImplFactory() override; | |
| 454 | |
| 455 // This method will create a real URLFetcher. | |
| 456 URLFetcher* CreateURLFetcher(int id, | |
| 457 const GURL& url, | |
| 458 URLFetcher::RequestType request_type, | |
| 459 URLFetcherDelegate* d) override; | |
| 460 }; | |
| 461 | |
| 462 } // namespace net | |
| 463 | |
| 464 #endif // NET_URL_REQUEST_TEST_URL_FETCHER_FACTORY_H_ | |
| OLD | NEW |