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 #include "net/url_request/test_url_fetcher_factory.h" | |
6 | |
7 #include <string> | |
8 | |
9 #include "base/bind.h" | |
10 #include "base/compiler_specific.h" | |
11 #include "base/files/file_util.h" | |
12 #include "base/memory/weak_ptr.h" | |
13 #include "base/message_loop/message_loop.h" | |
14 #include "base/threading/thread_restrictions.h" | |
15 #include "net/base/host_port_pair.h" | |
16 #include "net/base/io_buffer.h" | |
17 #include "net/base/net_errors.h" | |
18 #include "net/base/upload_data_stream.h" | |
19 #include "net/http/http_response_headers.h" | |
20 #include "net/url_request/url_fetcher_delegate.h" | |
21 #include "net/url_request/url_fetcher_impl.h" | |
22 #include "net/url_request/url_fetcher_response_writer.h" | |
23 #include "net/url_request/url_request_status.h" | |
24 | |
25 namespace net { | |
26 | |
27 ScopedURLFetcherFactory::ScopedURLFetcherFactory( | |
28 URLFetcherFactory* factory) { | |
29 DCHECK(!URLFetcherImpl::factory()); | |
30 URLFetcherImpl::set_factory(factory); | |
31 } | |
32 | |
33 ScopedURLFetcherFactory::~ScopedURLFetcherFactory() { | |
34 DCHECK(URLFetcherImpl::factory()); | |
35 URLFetcherImpl::set_factory(NULL); | |
36 } | |
37 | |
38 TestURLFetcher::TestURLFetcher(int id, | |
39 const GURL& url, | |
40 URLFetcherDelegate* d) | |
41 : owner_(NULL), | |
42 id_(id), | |
43 original_url_(url), | |
44 delegate_(d), | |
45 delegate_for_tests_(NULL), | |
46 did_receive_last_chunk_(false), | |
47 fake_load_flags_(0), | |
48 fake_response_code_(-1), | |
49 fake_response_destination_(STRING), | |
50 fake_was_fetched_via_proxy_(false), | |
51 fake_max_retries_(0) { | |
52 CHECK(original_url_.is_valid()); | |
53 } | |
54 | |
55 TestURLFetcher::~TestURLFetcher() { | |
56 if (delegate_for_tests_) | |
57 delegate_for_tests_->OnRequestEnd(id_); | |
58 if (owner_) | |
59 owner_->RemoveFetcherFromMap(id_); | |
60 } | |
61 | |
62 void TestURLFetcher::SetUploadData(const std::string& upload_content_type, | |
63 const std::string& upload_content) { | |
64 upload_content_type_ = upload_content_type; | |
65 upload_data_ = upload_content; | |
66 } | |
67 | |
68 void TestURLFetcher::SetUploadFilePath( | |
69 const std::string& upload_content_type, | |
70 const base::FilePath& file_path, | |
71 uint64 range_offset, | |
72 uint64 range_length, | |
73 scoped_refptr<base::TaskRunner> file_task_runner) { | |
74 upload_file_path_ = file_path; | |
75 } | |
76 | |
77 void TestURLFetcher::SetUploadStreamFactory( | |
78 const std::string& upload_content_type, | |
79 const CreateUploadStreamCallback& factory) { | |
80 } | |
81 | |
82 void TestURLFetcher::SetChunkedUpload(const std::string& upload_content_type) { | |
83 } | |
84 | |
85 void TestURLFetcher::AppendChunkToUpload(const std::string& data, | |
86 bool is_last_chunk) { | |
87 DCHECK(!did_receive_last_chunk_); | |
88 did_receive_last_chunk_ = is_last_chunk; | |
89 chunks_.push_back(data); | |
90 if (delegate_for_tests_) | |
91 delegate_for_tests_->OnChunkUpload(id_); | |
92 } | |
93 | |
94 void TestURLFetcher::SetLoadFlags(int load_flags) { | |
95 fake_load_flags_= load_flags; | |
96 } | |
97 | |
98 int TestURLFetcher::GetLoadFlags() const { | |
99 return fake_load_flags_; | |
100 } | |
101 | |
102 void TestURLFetcher::SetReferrer(const std::string& referrer) { | |
103 } | |
104 | |
105 void TestURLFetcher::SetReferrerPolicy( | |
106 URLRequest::ReferrerPolicy referrer_policy) { | |
107 } | |
108 | |
109 void TestURLFetcher::SetExtraRequestHeaders( | |
110 const std::string& extra_request_headers) { | |
111 fake_extra_request_headers_.Clear(); | |
112 fake_extra_request_headers_.AddHeadersFromString(extra_request_headers); | |
113 } | |
114 | |
115 void TestURLFetcher::AddExtraRequestHeader(const std::string& header_line) { | |
116 fake_extra_request_headers_.AddHeaderFromString(header_line); | |
117 } | |
118 | |
119 void TestURLFetcher::SetRequestContext( | |
120 URLRequestContextGetter* request_context_getter) { | |
121 } | |
122 | |
123 void TestURLFetcher::SetFirstPartyForCookies( | |
124 const GURL& first_party_for_cookies) { | |
125 } | |
126 | |
127 void TestURLFetcher::SetURLRequestUserData( | |
128 const void* key, | |
129 const CreateDataCallback& create_data_callback) { | |
130 } | |
131 | |
132 void TestURLFetcher::SetStopOnRedirect(bool stop_on_redirect) { | |
133 } | |
134 | |
135 void TestURLFetcher::SetAutomaticallyRetryOn5xx(bool retry) { | |
136 } | |
137 | |
138 void TestURLFetcher::SetMaxRetriesOn5xx(int max_retries) { | |
139 fake_max_retries_ = max_retries; | |
140 } | |
141 | |
142 int TestURLFetcher::GetMaxRetriesOn5xx() const { | |
143 return fake_max_retries_; | |
144 } | |
145 | |
146 base::TimeDelta TestURLFetcher::GetBackoffDelay() const { | |
147 return fake_backoff_delay_; | |
148 } | |
149 | |
150 void TestURLFetcher::SetAutomaticallyRetryOnNetworkChanges(int max_retries) { | |
151 } | |
152 | |
153 void TestURLFetcher::SaveResponseToFileAtPath( | |
154 const base::FilePath& file_path, | |
155 scoped_refptr<base::SequencedTaskRunner> file_task_runner) { | |
156 SetResponseFilePath(file_path); | |
157 // Asynchronous IO is not supported, so file_task_runner is ignored. | |
158 base::ThreadRestrictions::ScopedAllowIO allow_io; | |
159 const size_t written_bytes = base::WriteFile( | |
160 file_path, fake_response_string_.c_str(), fake_response_string_.size()); | |
161 DCHECK_EQ(written_bytes, fake_response_string_.size()); | |
162 } | |
163 | |
164 void TestURLFetcher::SaveResponseToTemporaryFile( | |
165 scoped_refptr<base::SequencedTaskRunner> file_task_runner) { | |
166 } | |
167 | |
168 void TestURLFetcher::SaveResponseWithWriter( | |
169 scoped_ptr<URLFetcherResponseWriter> response_writer) { | |
170 // In class URLFetcherCore this method is called by all three: | |
171 // GetResponseAsString() / SaveResponseToFileAtPath() / | |
172 // SaveResponseToTemporaryFile(). But here (in TestURLFetcher), this method | |
173 // is never used by any of these three methods. So, file writing is expected | |
174 // to be done in SaveResponseToFileAtPath(), and this method supports only | |
175 // URLFetcherStringWriter (for testing of this method only). | |
176 if (fake_response_destination_ == STRING) { | |
177 response_writer_ = response_writer.Pass(); | |
178 int response = response_writer_->Initialize(CompletionCallback()); | |
179 // The TestURLFetcher doesn't handle asynchronous writes. | |
180 DCHECK_EQ(OK, response); | |
181 | |
182 scoped_refptr<IOBuffer> buffer(new StringIOBuffer(fake_response_string_)); | |
183 response = response_writer_->Write(buffer.get(), | |
184 fake_response_string_.size(), | |
185 CompletionCallback()); | |
186 DCHECK_EQ(static_cast<int>(fake_response_string_.size()), response); | |
187 response = response_writer_->Finish(CompletionCallback()); | |
188 DCHECK_EQ(OK, response); | |
189 } else if (fake_response_destination_ == TEMP_FILE) { | |
190 // SaveResponseToFileAtPath() should be called instead of this method to | |
191 // save file. Asynchronous file writing using URLFetcherFileWriter is not | |
192 // supported. | |
193 NOTIMPLEMENTED(); | |
194 } else { | |
195 NOTREACHED(); | |
196 } | |
197 } | |
198 | |
199 HttpResponseHeaders* TestURLFetcher::GetResponseHeaders() const { | |
200 return fake_response_headers_.get(); | |
201 } | |
202 | |
203 HostPortPair TestURLFetcher::GetSocketAddress() const { | |
204 NOTIMPLEMENTED(); | |
205 return HostPortPair(); | |
206 } | |
207 | |
208 bool TestURLFetcher::WasFetchedViaProxy() const { | |
209 return fake_was_fetched_via_proxy_; | |
210 } | |
211 | |
212 void TestURLFetcher::Start() { | |
213 // Overriden to do nothing. It is assumed the caller will notify the delegate. | |
214 if (delegate_for_tests_) | |
215 delegate_for_tests_->OnRequestStart(id_); | |
216 } | |
217 | |
218 const GURL& TestURLFetcher::GetOriginalURL() const { | |
219 return original_url_; | |
220 } | |
221 | |
222 const GURL& TestURLFetcher::GetURL() const { | |
223 return fake_url_; | |
224 } | |
225 | |
226 const URLRequestStatus& TestURLFetcher::GetStatus() const { | |
227 return fake_status_; | |
228 } | |
229 | |
230 int TestURLFetcher::GetResponseCode() const { | |
231 return fake_response_code_; | |
232 } | |
233 | |
234 const ResponseCookies& TestURLFetcher::GetCookies() const { | |
235 return fake_cookies_; | |
236 } | |
237 | |
238 void TestURLFetcher::ReceivedContentWasMalformed() { | |
239 } | |
240 | |
241 bool TestURLFetcher::GetResponseAsString( | |
242 std::string* out_response_string) const { | |
243 if (fake_response_destination_ != STRING) | |
244 return false; | |
245 | |
246 *out_response_string = fake_response_string_; | |
247 return true; | |
248 } | |
249 | |
250 bool TestURLFetcher::GetResponseAsFilePath( | |
251 bool take_ownership, base::FilePath* out_response_path) const { | |
252 if (fake_response_destination_ != TEMP_FILE) | |
253 return false; | |
254 | |
255 *out_response_path = fake_response_file_path_; | |
256 return true; | |
257 } | |
258 | |
259 void TestURLFetcher::GetExtraRequestHeaders( | |
260 HttpRequestHeaders* headers) const { | |
261 *headers = fake_extra_request_headers_; | |
262 } | |
263 | |
264 void TestURLFetcher::set_status(const URLRequestStatus& status) { | |
265 fake_status_ = status; | |
266 } | |
267 | |
268 void TestURLFetcher::set_was_fetched_via_proxy(bool flag) { | |
269 fake_was_fetched_via_proxy_ = flag; | |
270 } | |
271 | |
272 void TestURLFetcher::set_response_headers( | |
273 scoped_refptr<HttpResponseHeaders> headers) { | |
274 fake_response_headers_ = headers; | |
275 } | |
276 | |
277 void TestURLFetcher::set_backoff_delay(base::TimeDelta backoff_delay) { | |
278 fake_backoff_delay_ = backoff_delay; | |
279 } | |
280 | |
281 void TestURLFetcher::SetDelegateForTests(DelegateForTests* delegate_for_tests) { | |
282 delegate_for_tests_ = delegate_for_tests; | |
283 } | |
284 | |
285 void TestURLFetcher::SetResponseString(const std::string& response) { | |
286 fake_response_destination_ = STRING; | |
287 fake_response_string_ = response; | |
288 } | |
289 | |
290 void TestURLFetcher::SetResponseFilePath(const base::FilePath& path) { | |
291 fake_response_destination_ = TEMP_FILE; | |
292 fake_response_file_path_ = path; | |
293 } | |
294 | |
295 TestURLFetcherFactory::TestURLFetcherFactory() | |
296 : ScopedURLFetcherFactory(this), | |
297 delegate_for_tests_(NULL), | |
298 remove_fetcher_on_delete_(false) { | |
299 } | |
300 | |
301 TestURLFetcherFactory::~TestURLFetcherFactory() {} | |
302 | |
303 URLFetcher* TestURLFetcherFactory::CreateURLFetcher( | |
304 int id, | |
305 const GURL& url, | |
306 URLFetcher::RequestType request_type, | |
307 URLFetcherDelegate* d) { | |
308 TestURLFetcher* fetcher = new TestURLFetcher(id, url, d); | |
309 if (remove_fetcher_on_delete_) | |
310 fetcher->set_owner(this); | |
311 fetcher->SetDelegateForTests(delegate_for_tests_); | |
312 fetchers_[id] = fetcher; | |
313 return fetcher; | |
314 } | |
315 | |
316 TestURLFetcher* TestURLFetcherFactory::GetFetcherByID(int id) const { | |
317 Fetchers::const_iterator i = fetchers_.find(id); | |
318 return i == fetchers_.end() ? NULL : i->second; | |
319 } | |
320 | |
321 void TestURLFetcherFactory::RemoveFetcherFromMap(int id) { | |
322 Fetchers::iterator i = fetchers_.find(id); | |
323 DCHECK(i != fetchers_.end()); | |
324 fetchers_.erase(i); | |
325 } | |
326 | |
327 void TestURLFetcherFactory::SetDelegateForTests( | |
328 TestURLFetcherDelegateForTests* delegate_for_tests) { | |
329 delegate_for_tests_ = delegate_for_tests; | |
330 } | |
331 | |
332 FakeURLFetcher::FakeURLFetcher(const GURL& url, | |
333 URLFetcherDelegate* d, | |
334 const std::string& response_data, | |
335 HttpStatusCode response_code, | |
336 URLRequestStatus::Status status) | |
337 : TestURLFetcher(0, url, d), | |
338 weak_factory_(this) { | |
339 Error error = OK; | |
340 switch(status) { | |
341 case URLRequestStatus::SUCCESS: | |
342 // |error| is initialized to OK. | |
343 break; | |
344 case URLRequestStatus::IO_PENDING: | |
345 error = ERR_IO_PENDING; | |
346 break; | |
347 case URLRequestStatus::CANCELED: | |
348 error = ERR_ABORTED; | |
349 break; | |
350 case URLRequestStatus::FAILED: | |
351 error = ERR_FAILED; | |
352 break; | |
353 } | |
354 set_status(URLRequestStatus(status, error)); | |
355 set_response_code(response_code); | |
356 SetResponseString(response_data); | |
357 } | |
358 | |
359 FakeURLFetcher::~FakeURLFetcher() {} | |
360 | |
361 void FakeURLFetcher::Start() { | |
362 base::MessageLoop::current()->PostTask( | |
363 FROM_HERE, | |
364 base::Bind(&FakeURLFetcher::RunDelegate, weak_factory_.GetWeakPtr())); | |
365 } | |
366 | |
367 void FakeURLFetcher::RunDelegate() { | |
368 delegate()->OnURLFetchComplete(this); | |
369 } | |
370 | |
371 const GURL& FakeURLFetcher::GetURL() const { | |
372 return TestURLFetcher::GetOriginalURL(); | |
373 } | |
374 | |
375 FakeURLFetcherFactory::FakeURLFetcherFactory( | |
376 URLFetcherFactory* default_factory) | |
377 : ScopedURLFetcherFactory(this), | |
378 creator_(base::Bind(&DefaultFakeURLFetcherCreator)), | |
379 default_factory_(default_factory) { | |
380 } | |
381 | |
382 FakeURLFetcherFactory::FakeURLFetcherFactory( | |
383 URLFetcherFactory* default_factory, | |
384 const FakeURLFetcherCreator& creator) | |
385 : ScopedURLFetcherFactory(this), | |
386 creator_(creator), | |
387 default_factory_(default_factory) { | |
388 } | |
389 | |
390 scoped_ptr<FakeURLFetcher> FakeURLFetcherFactory::DefaultFakeURLFetcherCreator( | |
391 const GURL& url, | |
392 URLFetcherDelegate* delegate, | |
393 const std::string& response_data, | |
394 HttpStatusCode response_code, | |
395 URLRequestStatus::Status status) { | |
396 return scoped_ptr<FakeURLFetcher>( | |
397 new FakeURLFetcher(url, delegate, response_data, response_code, status)); | |
398 } | |
399 | |
400 FakeURLFetcherFactory::~FakeURLFetcherFactory() {} | |
401 | |
402 URLFetcher* FakeURLFetcherFactory::CreateURLFetcher( | |
403 int id, | |
404 const GURL& url, | |
405 URLFetcher::RequestType request_type, | |
406 URLFetcherDelegate* d) { | |
407 FakeResponseMap::const_iterator it = fake_responses_.find(url); | |
408 if (it == fake_responses_.end()) { | |
409 if (default_factory_ == NULL) { | |
410 // If we don't have a baked response for that URL we return NULL. | |
411 DLOG(ERROR) << "No baked response for URL: " << url.spec(); | |
412 return NULL; | |
413 } else { | |
414 return default_factory_->CreateURLFetcher(id, url, request_type, d); | |
415 } | |
416 } | |
417 | |
418 scoped_ptr<FakeURLFetcher> fake_fetcher = | |
419 creator_.Run(url, d, it->second.response_data, | |
420 it->second.response_code, it->second.status); | |
421 // TODO: Make URLFetcherFactory::CreateURLFetcher return a scoped_ptr | |
422 return fake_fetcher.release(); | |
423 } | |
424 | |
425 void FakeURLFetcherFactory::SetFakeResponse( | |
426 const GURL& url, | |
427 const std::string& response_data, | |
428 HttpStatusCode response_code, | |
429 URLRequestStatus::Status status) { | |
430 // Overwrite existing URL if it already exists. | |
431 FakeURLResponse response; | |
432 response.response_data = response_data; | |
433 response.response_code = response_code; | |
434 response.status = status; | |
435 fake_responses_[url] = response; | |
436 } | |
437 | |
438 void FakeURLFetcherFactory::ClearFakeResponses() { | |
439 fake_responses_.clear(); | |
440 } | |
441 | |
442 URLFetcherImplFactory::URLFetcherImplFactory() {} | |
443 | |
444 URLFetcherImplFactory::~URLFetcherImplFactory() {} | |
445 | |
446 URLFetcher* URLFetcherImplFactory::CreateURLFetcher( | |
447 int id, | |
448 const GURL& url, | |
449 URLFetcher::RequestType request_type, | |
450 URLFetcherDelegate* d) { | |
451 return new URLFetcherImpl(url, request_type, d); | |
452 } | |
453 | |
454 } // namespace net | |
OLD | NEW |