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