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