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 |