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