Home | History | Annotate | Download | only in url_request
      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/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 
     26 ScopedURLFetcherFactory::ScopedURLFetcherFactory(
     27     URLFetcherFactory* factory) {
     28   DCHECK(!URLFetcherImpl::factory());
     29   URLFetcherImpl::set_factory(factory);
     30 }
     31 
     32 ScopedURLFetcherFactory::~ScopedURLFetcherFactory() {
     33   DCHECK(URLFetcherImpl::factory());
     34   URLFetcherImpl::set_factory(NULL);
     35 }
     36 
     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 
     53 TestURLFetcher::~TestURLFetcher() {
     54   if (delegate_for_tests_)
     55     delegate_for_tests_->OnRequestEnd(id_);
     56   if (owner_)
     57     owner_->RemoveFetcherFromMap(id_);
     58 }
     59 
     60 void TestURLFetcher::SetUploadData(const std::string& upload_content_type,
     61                                    const std::string& upload_content) {
     62   upload_data_ = upload_content;
     63 }
     64 
     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 
     74 void TestURLFetcher::SetChunkedUpload(const std::string& upload_content_type) {
     75 }
     76 
     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 
     86 void TestURLFetcher::SetLoadFlags(int load_flags) {
     87   fake_load_flags_= load_flags;
     88 }
     89 
     90 int TestURLFetcher::GetLoadFlags() const {
     91   return fake_load_flags_;
     92 }
     93 
     94 void TestURLFetcher::SetReferrer(const std::string& referrer) {
     95 }
     96 
     97 void TestURLFetcher::SetReferrerPolicy(
     98     URLRequest::ReferrerPolicy referrer_policy) {
     99 }
    100 
    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 
    107 void TestURLFetcher::AddExtraRequestHeader(const std::string& header_line) {
    108   fake_extra_request_headers_.AddHeaderFromString(header_line);
    109 }
    110 
    111 void TestURLFetcher::SetRequestContext(
    112     URLRequestContextGetter* request_context_getter) {
    113 }
    114 
    115 void TestURLFetcher::SetFirstPartyForCookies(
    116     const GURL& first_party_for_cookies) {
    117 }
    118 
    119 void TestURLFetcher::SetURLRequestUserData(
    120     const void* key,
    121     const CreateDataCallback& create_data_callback) {
    122 }
    123 
    124 void TestURLFetcher::SetStopOnRedirect(bool stop_on_redirect) {
    125 }
    126 
    127 void TestURLFetcher::SetAutomaticallyRetryOn5xx(bool retry) {
    128 }
    129 
    130 void TestURLFetcher::SetMaxRetriesOn5xx(int max_retries) {
    131   fake_max_retries_ = max_retries;
    132 }
    133 
    134 int TestURLFetcher::GetMaxRetriesOn5xx() const {
    135   return fake_max_retries_;
    136 }
    137 
    138 base::TimeDelta TestURLFetcher::GetBackoffDelay() const {
    139   return fake_backoff_delay_;
    140 }
    141 
    142 void TestURLFetcher::SetAutomaticallyRetryOnNetworkChanges(int max_retries) {
    143 }
    144 
    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 
    156 void TestURLFetcher::SaveResponseToTemporaryFile(
    157     scoped_refptr<base::SequencedTaskRunner> file_task_runner) {
    158 }
    159 
    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 
    191 HttpResponseHeaders* TestURLFetcher::GetResponseHeaders() const {
    192   return fake_response_headers_.get();
    193 }
    194 
    195 HostPortPair TestURLFetcher::GetSocketAddress() const {
    196   NOTIMPLEMENTED();
    197   return HostPortPair();
    198 }
    199 
    200 bool TestURLFetcher::WasFetchedViaProxy() const {
    201   return fake_was_fetched_via_proxy_;
    202 }
    203 
    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 
    210 const GURL& TestURLFetcher::GetOriginalURL() const {
    211   return original_url_;
    212 }
    213 
    214 const GURL& TestURLFetcher::GetURL() const {
    215   return fake_url_;
    216 }
    217 
    218 const URLRequestStatus& TestURLFetcher::GetStatus() const {
    219   return fake_status_;
    220 }
    221 
    222 int TestURLFetcher::GetResponseCode() const {
    223   return fake_response_code_;
    224 }
    225 
    226 const ResponseCookies& TestURLFetcher::GetCookies() const {
    227   return fake_cookies_;
    228 }
    229 
    230 void TestURLFetcher::ReceivedContentWasMalformed() {
    231 }
    232 
    233 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 
    242 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 
    251 void TestURLFetcher::GetExtraRequestHeaders(
    252     HttpRequestHeaders* headers) const {
    253   *headers = fake_extra_request_headers_;
    254 }
    255 
    256 void TestURLFetcher::set_status(const URLRequestStatus& status) {
    257   fake_status_ = status;
    258 }
    259 
    260 void TestURLFetcher::set_was_fetched_via_proxy(bool flag) {
    261   fake_was_fetched_via_proxy_ = flag;
    262 }
    263 
    264 void TestURLFetcher::set_response_headers(
    265     scoped_refptr<HttpResponseHeaders> headers) {
    266   fake_response_headers_ = headers;
    267 }
    268 
    269 void TestURLFetcher::set_backoff_delay(base::TimeDelta backoff_delay) {
    270   fake_backoff_delay_ = backoff_delay;
    271 }
    272 
    273 void TestURLFetcher::SetDelegateForTests(DelegateForTests* delegate_for_tests) {
    274   delegate_for_tests_ = delegate_for_tests;
    275 }
    276 
    277 void TestURLFetcher::SetResponseString(const std::string& response) {
    278   fake_response_destination_ = STRING;
    279   fake_response_string_ = response;
    280 }
    281 
    282 void TestURLFetcher::SetResponseFilePath(const base::FilePath& path) {
    283   fake_response_destination_ = TEMP_FILE;
    284   fake_response_file_path_ = path;
    285 }
    286 
    287 TestURLFetcherFactory::TestURLFetcherFactory()
    288     : ScopedURLFetcherFactory(this),
    289       delegate_for_tests_(NULL),
    290       remove_fetcher_on_delete_(false) {
    291 }
    292 
    293 TestURLFetcherFactory::~TestURLFetcherFactory() {}
    294 
    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 
    308 TestURLFetcher* TestURLFetcherFactory::GetFetcherByID(int id) const {
    309   Fetchers::const_iterator i = fetchers_.find(id);
    310   return i == fetchers_.end() ? NULL : i->second;
    311 }
    312 
    313 void TestURLFetcherFactory::RemoveFetcherFromMap(int id) {
    314   Fetchers::iterator i = fetchers_.find(id);
    315   DCHECK(i != fetchers_.end());
    316   fetchers_.erase(i);
    317 }
    318 
    319 void TestURLFetcherFactory::SetDelegateForTests(
    320     TestURLFetcherDelegateForTests* delegate_for_tests) {
    321   delegate_for_tests_ = delegate_for_tests;
    322 }
    323 
    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 
    351 FakeURLFetcher::~FakeURLFetcher() {}
    352 
    353 void FakeURLFetcher::Start() {
    354   base::MessageLoop::current()->PostTask(
    355       FROM_HERE,
    356       base::Bind(&FakeURLFetcher::RunDelegate, weak_factory_.GetWeakPtr()));
    357 }
    358 
    359 void FakeURLFetcher::RunDelegate() {
    360   delegate()->OnURLFetchComplete(this);
    361 }
    362 
    363 const GURL& FakeURLFetcher::GetURL() const {
    364   return TestURLFetcher::GetOriginalURL();
    365 }
    366 
    367 FakeURLFetcherFactory::FakeURLFetcherFactory(
    368     URLFetcherFactory* default_factory)
    369     : ScopedURLFetcherFactory(this),
    370       creator_(base::Bind(&DefaultFakeURLFetcherCreator)),
    371       default_factory_(default_factory) {
    372 }
    373 
    374 FakeURLFetcherFactory::FakeURLFetcherFactory(
    375     URLFetcherFactory* default_factory,
    376     const FakeURLFetcherCreator& creator)
    377     : ScopedURLFetcherFactory(this),
    378       creator_(creator),
    379       default_factory_(default_factory) {
    380 }
    381 
    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 
    392 FakeURLFetcherFactory::~FakeURLFetcherFactory() {}
    393 
    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 
    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 
    430 void FakeURLFetcherFactory::ClearFakeResponses() {
    431   fake_responses_.clear();
    432 }
    433 
    434 URLFetcherImplFactory::URLFetcherImplFactory() {}
    435 
    436 URLFetcherImplFactory::~URLFetcherImplFactory() {}
    437 
    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