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/url_fetcher_impl.h"
      6 
      7 #include <algorithm>
      8 #include <string>
      9 
     10 #include "base/bind.h"
     11 #include "base/file_util.h"
     12 #include "base/files/scoped_temp_dir.h"
     13 #include "base/message_loop/message_loop_proxy.h"
     14 #include "base/strings/stringprintf.h"
     15 #include "base/synchronization/waitable_event.h"
     16 #include "base/threading/thread.h"
     17 #include "build/build_config.h"
     18 #include "crypto/nss_util.h"
     19 #include "net/base/network_change_notifier.h"
     20 #include "net/dns/mock_host_resolver.h"
     21 #include "net/http/http_response_headers.h"
     22 #include "net/test/spawned_test_server/spawned_test_server.h"
     23 #include "net/url_request/url_fetcher_delegate.h"
     24 #include "net/url_request/url_request_context_getter.h"
     25 #include "net/url_request/url_request_test_util.h"
     26 #include "net/url_request/url_request_throttler_manager.h"
     27 #include "testing/gtest/include/gtest/gtest.h"
     28 
     29 #if defined(USE_NSS) || defined(OS_IOS)
     30 #include "net/ocsp/nss_ocsp.h"
     31 #endif
     32 
     33 namespace net {
     34 
     35 using base::Time;
     36 using base::TimeDelta;
     37 
     38 // TODO(eroman): Add a regression test for http://crbug.com/40505.
     39 
     40 namespace {
     41 
     42 // TODO(akalin): Move all the test data to somewhere under net/.
     43 const base::FilePath::CharType kDocRoot[] =
     44     FILE_PATH_LITERAL("chrome/test/data");
     45 const char kTestServerFilePrefix[] = "files/";
     46 
     47 class ThrottlingTestURLRequestContext : public TestURLRequestContext {
     48  public:
     49   ThrottlingTestURLRequestContext() : TestURLRequestContext(true) {
     50     set_throttler_manager(&throttler_manager_);
     51     Init();
     52     DCHECK(throttler_manager() != NULL);
     53   }
     54 
     55  private:
     56   URLRequestThrottlerManager throttler_manager_;
     57 };
     58 
     59 class ThrottlingTestURLRequestContextGetter
     60     : public TestURLRequestContextGetter {
     61  public:
     62   ThrottlingTestURLRequestContextGetter(
     63       base::MessageLoopProxy* io_message_loop_proxy,
     64       TestURLRequestContext* request_context)
     65       : TestURLRequestContextGetter(io_message_loop_proxy),
     66         context_(request_context) {
     67   }
     68 
     69   // TestURLRequestContextGetter:
     70   virtual TestURLRequestContext* GetURLRequestContext() OVERRIDE {
     71     return context_;
     72   }
     73 
     74  protected:
     75   virtual ~ThrottlingTestURLRequestContextGetter() {}
     76 
     77   TestURLRequestContext* const context_;
     78 };
     79 
     80 }  // namespace
     81 
     82 class URLFetcherTest : public testing::Test,
     83                        public URLFetcherDelegate {
     84  public:
     85   URLFetcherTest() : fetcher_(NULL) {}
     86 
     87   static int GetNumFetcherCores() {
     88     return URLFetcherImpl::GetNumFetcherCores();
     89   }
     90 
     91   // Creates a URLFetcher, using the program's main thread to do IO.
     92   virtual void CreateFetcher(const GURL& url);
     93 
     94   // URLFetcherDelegate:
     95   // Subclasses that override this should either call this function or
     96   // CleanupAfterFetchComplete() at the end of their processing, depending on
     97   // whether they want to check for a non-empty HTTP 200 response or not.
     98   virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE;
     99 
    100   // Deletes |fetcher| and terminates the message loop.
    101   void CleanupAfterFetchComplete();
    102 
    103   scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy() {
    104     return io_message_loop_proxy_;
    105   }
    106 
    107   TestURLRequestContext* request_context() {
    108     return context_.get();
    109   }
    110 
    111  protected:
    112   // testing::Test:
    113   virtual void SetUp() OVERRIDE {
    114     testing::Test::SetUp();
    115 
    116     context_.reset(new ThrottlingTestURLRequestContext());
    117     io_message_loop_proxy_ = base::MessageLoopProxy::current();
    118 
    119 #if defined(USE_NSS) || defined(OS_IOS)
    120     crypto::EnsureNSSInit();
    121     EnsureNSSHttpIOInit();
    122 #endif
    123   }
    124 
    125   virtual void TearDown() OVERRIDE {
    126 #if defined(USE_NSS) || defined(OS_IOS)
    127     ShutdownNSSHttpIO();
    128 #endif
    129   }
    130 
    131   // URLFetcher is designed to run on the main UI thread, but in our tests
    132   // we assume that the current thread is the IO thread where the URLFetcher
    133   // dispatches its requests to.  When we wish to simulate being used from
    134   // a UI thread, we dispatch a worker thread to do so.
    135   scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_;
    136 
    137   URLFetcherImpl* fetcher_;
    138   scoped_ptr<TestURLRequestContext> context_;
    139 };
    140 
    141 // A test fixture that uses a MockHostResolver, so that name resolutions can
    142 // be manipulated by the tests to keep connections in the resolving state.
    143 class URLFetcherMockDnsTest : public URLFetcherTest {
    144  public:
    145   // testing::Test:
    146   virtual void SetUp() OVERRIDE;
    147 
    148   // URLFetcherTest:
    149   virtual void CreateFetcher(const GURL& url) OVERRIDE;
    150 
    151   // URLFetcherDelegate:
    152   virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE;
    153 
    154  protected:
    155   GURL test_url_;
    156   scoped_ptr<SpawnedTestServer> test_server_;
    157   MockHostResolver resolver_;
    158   scoped_ptr<URLFetcher> completed_fetcher_;
    159 };
    160 
    161 void URLFetcherTest::CreateFetcher(const GURL& url) {
    162   fetcher_ = new URLFetcherImpl(url, URLFetcher::GET, this);
    163   fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter(
    164       io_message_loop_proxy().get(), request_context()));
    165   fetcher_->Start();
    166 }
    167 
    168 void URLFetcherTest::OnURLFetchComplete(const URLFetcher* source) {
    169   EXPECT_TRUE(source->GetStatus().is_success());
    170   EXPECT_EQ(200, source->GetResponseCode());  // HTTP OK
    171 
    172   std::string data;
    173   EXPECT_TRUE(source->GetResponseAsString(&data));
    174   EXPECT_FALSE(data.empty());
    175 
    176   CleanupAfterFetchComplete();
    177 }
    178 
    179 void URLFetcherTest::CleanupAfterFetchComplete() {
    180   delete fetcher_;  // Have to delete this here and not in the destructor,
    181                     // because the destructor won't necessarily run on the
    182                     // same thread that CreateFetcher() did.
    183 
    184   io_message_loop_proxy()->PostTask(FROM_HERE,
    185                                     base::MessageLoop::QuitClosure());
    186   // If the current message loop is not the IO loop, it will be shut down when
    187   // the main loop returns and this thread subsequently goes out of scope.
    188 }
    189 
    190 void URLFetcherMockDnsTest::SetUp() {
    191   URLFetcherTest::SetUp();
    192 
    193   resolver_.set_ondemand_mode(true);
    194   resolver_.rules()->AddRule("example.com", "127.0.0.1");
    195 
    196   context_.reset(new TestURLRequestContext(true));
    197   context_->set_host_resolver(&resolver_);
    198   context_->Init();
    199 
    200   test_server_.reset(new SpawnedTestServer(SpawnedTestServer::TYPE_HTTP,
    201                                            SpawnedTestServer::kLocalhost,
    202                                            base::FilePath(kDocRoot)));
    203   ASSERT_TRUE(test_server_->Start());
    204 
    205   // test_server_.GetURL() returns a URL with 127.0.0.1 (kLocalhost), that is
    206   // immediately resolved by the MockHostResolver. Use a hostname instead to
    207   // trigger an async resolve.
    208   test_url_ = GURL(
    209       base::StringPrintf("http://example.com:%d/defaultresponse",
    210       test_server_->host_port_pair().port()));
    211   ASSERT_TRUE(test_url_.is_valid());
    212 }
    213 
    214 void URLFetcherMockDnsTest::CreateFetcher(const GURL& url) {
    215   fetcher_ = new URLFetcherImpl(url, URLFetcher::GET, this);
    216   fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter(
    217       io_message_loop_proxy().get(), request_context()));
    218 }
    219 
    220 void URLFetcherMockDnsTest::OnURLFetchComplete(const URLFetcher* source) {
    221   io_message_loop_proxy()->PostTask(FROM_HERE,
    222                                     base::MessageLoop::QuitClosure());
    223   ASSERT_EQ(fetcher_, source);
    224   EXPECT_EQ(test_url_, source->GetOriginalURL());
    225   completed_fetcher_.reset(fetcher_);
    226 }
    227 
    228 namespace {
    229 
    230 // Version of URLFetcherTest that does a POST instead
    231 class URLFetcherPostTest : public URLFetcherTest {
    232  public:
    233   // URLFetcherTest:
    234   virtual void CreateFetcher(const GURL& url) OVERRIDE;
    235 
    236   // URLFetcherDelegate:
    237   virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE;
    238 };
    239 
    240 // Version of URLFetcherTest that does a POST of a file using
    241 // SetUploadDataStream
    242 class URLFetcherPostFileTest : public URLFetcherTest {
    243  public:
    244   URLFetcherPostFileTest();
    245 
    246   void SetUploadRange(uint64 range_offset, uint64 range_length) {
    247     range_offset_ = range_offset;
    248     range_length_ = range_length;
    249   }
    250 
    251   // URLFetcherTest:
    252   virtual void CreateFetcher(const GURL& url) OVERRIDE;
    253 
    254   // URLFetcherDelegate:
    255   virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE;
    256 
    257  private:
    258   base::FilePath path_;
    259   uint64 range_offset_;
    260   uint64 range_length_;
    261 };
    262 
    263 // Version of URLFetcherTest that does a POST instead with empty upload body
    264 class URLFetcherEmptyPostTest : public URLFetcherTest {
    265  public:
    266   // URLFetcherTest:
    267   virtual void CreateFetcher(const GURL& url) OVERRIDE;
    268 
    269   // URLFetcherDelegate:
    270   virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE;
    271 };
    272 
    273 // Version of URLFetcherTest that tests download progress reports.
    274 class URLFetcherDownloadProgressTest : public URLFetcherTest {
    275  public:
    276   URLFetcherDownloadProgressTest()
    277       : previous_progress_(0),
    278         expected_total_(0) {
    279   }
    280 
    281   // URLFetcherTest:
    282   virtual void CreateFetcher(const GURL& url) OVERRIDE;
    283 
    284   // URLFetcherDelegate:
    285   virtual void OnURLFetchDownloadProgress(const URLFetcher* source,
    286                                           int64 current,
    287                                           int64 total) OVERRIDE;
    288 
    289  protected:
    290   // Download progress returned by the previous callback.
    291   int64 previous_progress_;
    292   // Size of the file being downloaded, known in advance (provided by each test
    293   // case).
    294   int64 expected_total_;
    295 };
    296 
    297 // Version of URLFetcherTest that tests progress reports at cancellation.
    298 class URLFetcherDownloadProgressCancelTest : public URLFetcherTest {
    299  public:
    300   // URLFetcherTest:
    301   virtual void CreateFetcher(const GURL& url) OVERRIDE;
    302 
    303   // URLFetcherDelegate:
    304   virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE;
    305   virtual void OnURLFetchDownloadProgress(const URLFetcher* source,
    306                                           int64 current,
    307                                           int64 total) OVERRIDE;
    308  protected:
    309   bool cancelled_;
    310 };
    311 
    312 // Version of URLFetcherTest that tests upload progress reports.
    313 class URLFetcherUploadProgressTest : public URLFetcherTest {
    314  public:
    315   // URLFetcherTest:
    316   virtual void CreateFetcher(const GURL& url) OVERRIDE;
    317 
    318   // URLFetcherDelegate:
    319   virtual void OnURLFetchUploadProgress(const URLFetcher* source,
    320                                         int64 current,
    321                                         int64 total) OVERRIDE;
    322  protected:
    323   int64 previous_progress_;
    324   std::string chunk_;
    325   int64 number_of_chunks_added_;
    326 };
    327 
    328 // Version of URLFetcherTest that tests headers.
    329 class URLFetcherHeadersTest : public URLFetcherTest {
    330  public:
    331   // URLFetcherDelegate:
    332   virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE;
    333 };
    334 
    335 // Version of URLFetcherTest that tests SocketAddress.
    336 class URLFetcherSocketAddressTest : public URLFetcherTest {
    337  public:
    338   // URLFetcherDelegate:
    339   virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE;
    340  protected:
    341   std::string expected_host_;
    342   uint16 expected_port_;
    343 };
    344 
    345 // Version of URLFetcherTest that tests stopping on a redirect.
    346 class URLFetcherStopOnRedirectTest : public URLFetcherTest {
    347  public:
    348   URLFetcherStopOnRedirectTest();
    349   virtual ~URLFetcherStopOnRedirectTest();
    350 
    351   // URLFetcherTest:
    352   virtual void CreateFetcher(const GURL& url) OVERRIDE;
    353 
    354   // URLFetcherDelegate:
    355   virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE;
    356 
    357  protected:
    358   // The URL we should be redirected to.
    359   static const char* kRedirectTarget;
    360 
    361   bool callback_called_;  // Set to true in OnURLFetchComplete().
    362 };
    363 
    364 // Version of URLFetcherTest that tests overload protection.
    365 class URLFetcherProtectTest : public URLFetcherTest {
    366  public:
    367   // URLFetcherTest:
    368   virtual void CreateFetcher(const GURL& url) OVERRIDE;
    369 
    370   // URLFetcherDelegate:
    371   virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE;
    372  private:
    373   Time start_time_;
    374 };
    375 
    376 // Version of URLFetcherTest that tests overload protection, when responses
    377 // passed through.
    378 class URLFetcherProtectTestPassedThrough : public URLFetcherTest {
    379  public:
    380   // URLFetcherTest:
    381   virtual void CreateFetcher(const GURL& url) OVERRIDE;
    382 
    383   // URLFetcherDelegate:
    384   virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE;
    385  private:
    386   Time start_time_;
    387 };
    388 
    389 // Version of URLFetcherTest that tests bad HTTPS requests.
    390 class URLFetcherBadHTTPSTest : public URLFetcherTest {
    391  public:
    392   URLFetcherBadHTTPSTest();
    393 
    394   // URLFetcherDelegate:
    395   virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE;
    396 
    397  private:
    398   base::FilePath cert_dir_;
    399 };
    400 
    401 // Version of URLFetcherTest that tests request cancellation on shutdown.
    402 class URLFetcherCancelTest : public URLFetcherTest {
    403  public:
    404   // URLFetcherTest:
    405   virtual void CreateFetcher(const GURL& url) OVERRIDE;
    406 
    407   // URLFetcherDelegate:
    408   virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE;
    409 
    410   void CancelRequest();
    411 };
    412 
    413 // Version of TestURLRequestContext that posts a Quit task to the IO
    414 // thread once it is deleted.
    415 class CancelTestURLRequestContext : public ThrottlingTestURLRequestContext {
    416  public:
    417   explicit CancelTestURLRequestContext() {
    418   }
    419 
    420  private:
    421   virtual ~CancelTestURLRequestContext() {
    422     // The d'tor should execute in the IO thread. Post the quit task to the
    423     // current thread.
    424     base::MessageLoop::current()->PostTask(FROM_HERE,
    425                                            base::MessageLoop::QuitClosure());
    426   }
    427 };
    428 
    429 class CancelTestURLRequestContextGetter
    430     : public TestURLRequestContextGetter {
    431  public:
    432   CancelTestURLRequestContextGetter(
    433       base::MessageLoopProxy* io_message_loop_proxy,
    434       const GURL& throttle_for_url)
    435       : TestURLRequestContextGetter(io_message_loop_proxy),
    436         io_message_loop_proxy_(io_message_loop_proxy),
    437         context_created_(false, false),
    438         throttle_for_url_(throttle_for_url) {
    439   }
    440 
    441   // TestURLRequestContextGetter:
    442   virtual TestURLRequestContext* GetURLRequestContext() OVERRIDE {
    443     if (!context_.get()) {
    444       context_.reset(new CancelTestURLRequestContext());
    445       DCHECK(context_->throttler_manager());
    446 
    447       // Registers an entry for test url. The backoff time is calculated by:
    448       //     new_backoff = 2.0 * old_backoff + 0
    449       // The initial backoff is 2 seconds and maximum backoff is 4 seconds.
    450       // Maximum retries allowed is set to 2.
    451       scoped_refptr<URLRequestThrottlerEntry> entry(
    452           new URLRequestThrottlerEntry(context_->throttler_manager(),
    453                                        std::string(),
    454                                        200,
    455                                        3,
    456                                        2000,
    457                                        2.0,
    458                                        0.0,
    459                                        4000));
    460       context_->throttler_manager()
    461           ->OverrideEntryForTests(throttle_for_url_, entry.get());
    462 
    463       context_created_.Signal();
    464     }
    465     return context_.get();
    466   }
    467 
    468   virtual scoped_refptr<base::MessageLoopProxy> GetIOMessageLoopProxy() const {
    469     return io_message_loop_proxy_;
    470   }
    471 
    472   void WaitForContextCreation() {
    473     context_created_.Wait();
    474   }
    475 
    476  protected:
    477   virtual ~CancelTestURLRequestContextGetter() {}
    478 
    479  private:
    480   scoped_ptr<TestURLRequestContext> context_;
    481   scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_;
    482   base::WaitableEvent context_created_;
    483   GURL throttle_for_url_;
    484 };
    485 
    486 // Version of URLFetcherTest that tests retying the same request twice.
    487 class URLFetcherMultipleAttemptTest : public URLFetcherTest {
    488  public:
    489   // URLFetcherDelegate:
    490   virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE;
    491  private:
    492   std::string data_;
    493 };
    494 
    495 class URLFetcherFileTest : public URLFetcherTest {
    496  public:
    497   URLFetcherFileTest() : take_ownership_of_file_(false),
    498                          expected_file_error_(OK) {}
    499 
    500   void CreateFetcherForFile(const GURL& url, const base::FilePath& file_path);
    501   void CreateFetcherForTempFile(const GURL& url);
    502 
    503   // URLFetcherDelegate:
    504   virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE;
    505 
    506  protected:
    507   base::FilePath expected_file_;
    508   base::FilePath file_path_;
    509 
    510   // Set by the test. Used in OnURLFetchComplete() to decide if
    511   // the URLFetcher should own the temp file, so that we can test
    512   // disowning prevents the file from being deleted.
    513   bool take_ownership_of_file_;
    514 
    515   // Expected file error code for the test.  OK when expecting success.
    516   int expected_file_error_;
    517 };
    518 
    519 void URLFetcherPostTest::CreateFetcher(const GURL& url) {
    520   fetcher_ = new URLFetcherImpl(url, URLFetcher::POST, this);
    521   fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter(
    522       io_message_loop_proxy().get(), request_context()));
    523   fetcher_->SetUploadData("application/x-www-form-urlencoded", "bobsyeruncle");
    524   fetcher_->Start();
    525 }
    526 
    527 void URLFetcherPostTest::OnURLFetchComplete(const URLFetcher* source) {
    528   std::string data;
    529   EXPECT_TRUE(source->GetResponseAsString(&data));
    530   EXPECT_EQ(std::string("bobsyeruncle"), data);
    531   URLFetcherTest::OnURLFetchComplete(source);
    532 }
    533 
    534 URLFetcherPostFileTest::URLFetcherPostFileTest()
    535     : range_offset_(0),
    536       range_length_(kuint64max) {
    537   PathService::Get(base::DIR_SOURCE_ROOT, &path_);
    538   path_ = path_.Append(FILE_PATH_LITERAL("net"));
    539   path_ = path_.Append(FILE_PATH_LITERAL("data"));
    540   path_ = path_.Append(FILE_PATH_LITERAL("url_request_unittest"));
    541   path_ = path_.Append(FILE_PATH_LITERAL("BullRunSpeech.txt"));
    542 }
    543 
    544 void URLFetcherPostFileTest::CreateFetcher(const GURL& url) {
    545   fetcher_ = new URLFetcherImpl(url, URLFetcher::POST, this);
    546   fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter(
    547       io_message_loop_proxy().get(), request_context()));
    548   fetcher_->SetUploadFilePath("application/x-www-form-urlencoded",
    549                               path_,
    550                               range_offset_,
    551                               range_length_,
    552                               base::MessageLoopProxy::current());
    553   fetcher_->Start();
    554 }
    555 
    556 void URLFetcherPostFileTest::OnURLFetchComplete(const URLFetcher* source) {
    557   std::string expected;
    558   ASSERT_TRUE(base::ReadFileToString(path_, &expected));
    559   ASSERT_LE(range_offset_, expected.size());
    560   uint64 expected_size =
    561       std::min(range_length_, expected.size() - range_offset_);
    562 
    563   std::string data;
    564   EXPECT_TRUE(source->GetResponseAsString(&data));
    565   EXPECT_EQ(expected.substr(range_offset_, expected_size), data);
    566   URLFetcherTest::OnURLFetchComplete(source);
    567 }
    568 
    569 void URLFetcherEmptyPostTest::CreateFetcher(const GURL& url) {
    570   fetcher_ = new URLFetcherImpl(url, URLFetcher::POST, this);
    571   fetcher_->SetRequestContext(new TestURLRequestContextGetter(
    572       io_message_loop_proxy()));
    573   fetcher_->SetUploadData("text/plain", std::string());
    574   fetcher_->Start();
    575 }
    576 
    577 void URLFetcherEmptyPostTest::OnURLFetchComplete(const URLFetcher* source) {
    578   EXPECT_TRUE(source->GetStatus().is_success());
    579   EXPECT_EQ(200, source->GetResponseCode());  // HTTP OK
    580 
    581   std::string data;
    582   EXPECT_TRUE(source->GetResponseAsString(&data));
    583   EXPECT_TRUE(data.empty());
    584 
    585   CleanupAfterFetchComplete();
    586   // Do not call the super class method URLFetcherTest::OnURLFetchComplete,
    587   // since it expects a non-empty response.
    588 }
    589 
    590 void URLFetcherDownloadProgressTest::CreateFetcher(const GURL& url) {
    591   fetcher_ = new URLFetcherImpl(url, URLFetcher::GET, this);
    592   fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter(
    593       io_message_loop_proxy().get(), request_context()));
    594   fetcher_->Start();
    595 }
    596 
    597 void URLFetcherDownloadProgressTest::OnURLFetchDownloadProgress(
    598     const URLFetcher* source, int64 progress, int64 total) {
    599   // Increasing between 0 and total.
    600   EXPECT_LE(0, progress);
    601   EXPECT_GE(total, progress);
    602   EXPECT_LE(previous_progress_, progress);
    603   EXPECT_EQ(expected_total_, total);
    604   previous_progress_ = progress;
    605 }
    606 
    607 void URLFetcherDownloadProgressCancelTest::CreateFetcher(const GURL& url) {
    608   fetcher_ = new URLFetcherImpl(url, URLFetcher::GET, this);
    609   fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter(
    610       io_message_loop_proxy().get(), request_context()));
    611   cancelled_ = false;
    612   fetcher_->Start();
    613 }
    614 
    615 void URLFetcherDownloadProgressCancelTest::OnURLFetchDownloadProgress(
    616     const URLFetcher* source, int64 current, int64 total) {
    617   EXPECT_FALSE(cancelled_);
    618   if (!cancelled_) {
    619     cancelled_ = true;
    620     CleanupAfterFetchComplete();
    621   }
    622 }
    623 
    624 void URLFetcherDownloadProgressCancelTest::OnURLFetchComplete(
    625     const URLFetcher* source) {
    626   // Should have been cancelled.
    627   ADD_FAILURE();
    628   CleanupAfterFetchComplete();
    629 }
    630 
    631 void URLFetcherUploadProgressTest::CreateFetcher(const GURL& url) {
    632   fetcher_ = new URLFetcherImpl(url, URLFetcher::POST, this);
    633   fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter(
    634       io_message_loop_proxy().get(), request_context()));
    635   previous_progress_ = 0;
    636   // Large enough data to require more than one read from UploadDataStream.
    637   chunk_.assign(1<<16, 'a');
    638   // Use chunked upload to wait for a timer event of progress notification.
    639   fetcher_->SetChunkedUpload("application/x-www-form-urlencoded");
    640   fetcher_->Start();
    641   number_of_chunks_added_ = 1;
    642   fetcher_->AppendChunkToUpload(chunk_, false);
    643 }
    644 
    645 void URLFetcherUploadProgressTest::OnURLFetchUploadProgress(
    646     const URLFetcher* source, int64 current, int64 total) {
    647   // Increasing between 0 and total.
    648   EXPECT_LE(0, current);
    649   EXPECT_GE(static_cast<int64>(chunk_.size()) * number_of_chunks_added_,
    650             current);
    651   EXPECT_LE(previous_progress_, current);
    652   previous_progress_ = current;
    653   EXPECT_EQ(-1, total);
    654 
    655   if (number_of_chunks_added_ < 2) {
    656     number_of_chunks_added_ += 1;
    657     fetcher_->AppendChunkToUpload(chunk_, true);
    658   }
    659 }
    660 
    661 void URLFetcherHeadersTest::OnURLFetchComplete(
    662     const URLFetcher* source) {
    663   std::string header;
    664   EXPECT_TRUE(source->GetResponseHeaders()->GetNormalizedHeader("cache-control",
    665                                                                 &header));
    666   EXPECT_EQ("private", header);
    667   URLFetcherTest::OnURLFetchComplete(source);
    668 }
    669 
    670 void URLFetcherSocketAddressTest::OnURLFetchComplete(
    671     const URLFetcher* source) {
    672   EXPECT_EQ("127.0.0.1", source->GetSocketAddress().host());
    673   EXPECT_EQ(expected_port_, source->GetSocketAddress().port());
    674   URLFetcherTest::OnURLFetchComplete(source);
    675 }
    676 
    677 // static
    678 const char* URLFetcherStopOnRedirectTest::kRedirectTarget =
    679     "http://redirect.target.com";
    680 
    681 URLFetcherStopOnRedirectTest::URLFetcherStopOnRedirectTest()
    682     : callback_called_(false) {
    683 }
    684 
    685 URLFetcherStopOnRedirectTest::~URLFetcherStopOnRedirectTest() {
    686 }
    687 
    688 void URLFetcherStopOnRedirectTest::CreateFetcher(const GURL& url) {
    689   fetcher_ = new URLFetcherImpl(url, URLFetcher::GET, this);
    690   fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter(
    691       io_message_loop_proxy().get(), request_context()));
    692   fetcher_->SetStopOnRedirect(true);
    693   fetcher_->Start();
    694 }
    695 
    696 void URLFetcherStopOnRedirectTest::OnURLFetchComplete(
    697     const URLFetcher* source) {
    698   callback_called_ = true;
    699   EXPECT_EQ(GURL(kRedirectTarget), source->GetURL());
    700   EXPECT_EQ(URLRequestStatus::CANCELED, source->GetStatus().status());
    701   EXPECT_EQ(ERR_ABORTED, source->GetStatus().error());
    702   EXPECT_EQ(301, source->GetResponseCode());
    703   CleanupAfterFetchComplete();
    704 }
    705 
    706 void URLFetcherProtectTest::CreateFetcher(const GURL& url) {
    707   fetcher_ = new URLFetcherImpl(url, URLFetcher::GET, this);
    708   fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter(
    709       io_message_loop_proxy().get(), request_context()));
    710   start_time_ = Time::Now();
    711   fetcher_->SetMaxRetriesOn5xx(11);
    712   fetcher_->Start();
    713 }
    714 
    715 void URLFetcherProtectTest::OnURLFetchComplete(const URLFetcher* source) {
    716   const TimeDelta one_second = TimeDelta::FromMilliseconds(1000);
    717   if (source->GetResponseCode() >= 500) {
    718     // Now running ServerUnavailable test.
    719     // It takes more than 1 second to finish all 11 requests.
    720     EXPECT_TRUE(Time::Now() - start_time_ >= one_second);
    721     EXPECT_TRUE(source->GetStatus().is_success());
    722     std::string data;
    723     EXPECT_TRUE(source->GetResponseAsString(&data));
    724     EXPECT_FALSE(data.empty());
    725     CleanupAfterFetchComplete();
    726   } else {
    727     // Now running Overload test.
    728     static int count = 0;
    729     count++;
    730     if (count < 20) {
    731       fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter(
    732           io_message_loop_proxy().get(), request_context()));
    733       fetcher_->Start();
    734     } else {
    735       // We have already sent 20 requests continuously. And we expect that
    736       // it takes more than 1 second due to the overload protection settings.
    737       EXPECT_TRUE(Time::Now() - start_time_ >= one_second);
    738       URLFetcherTest::OnURLFetchComplete(source);
    739     }
    740   }
    741 }
    742 
    743 void URLFetcherProtectTestPassedThrough::CreateFetcher(const GURL& url) {
    744   fetcher_ = new URLFetcherImpl(url, URLFetcher::GET, this);
    745   fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter(
    746       io_message_loop_proxy().get(), request_context()));
    747   fetcher_->SetAutomaticallyRetryOn5xx(false);
    748   start_time_ = Time::Now();
    749   fetcher_->SetMaxRetriesOn5xx(11);
    750   fetcher_->Start();
    751 }
    752 
    753 void URLFetcherProtectTestPassedThrough::OnURLFetchComplete(
    754     const URLFetcher* source) {
    755   const TimeDelta one_minute = TimeDelta::FromMilliseconds(60000);
    756   if (source->GetResponseCode() >= 500) {
    757     // Now running ServerUnavailable test.
    758     // It should get here on the first attempt, so almost immediately and
    759     // *not* to attempt to execute all 11 requests (2.5 minutes).
    760     EXPECT_TRUE(Time::Now() - start_time_ < one_minute);
    761     EXPECT_TRUE(source->GetStatus().is_success());
    762     // Check that suggested back off time is bigger than 0.
    763     EXPECT_GT(fetcher_->GetBackoffDelay().InMicroseconds(), 0);
    764     std::string data;
    765     EXPECT_TRUE(source->GetResponseAsString(&data));
    766     EXPECT_FALSE(data.empty());
    767   } else {
    768     // We should not get here!
    769     ADD_FAILURE();
    770   }
    771 
    772   CleanupAfterFetchComplete();
    773 }
    774 
    775 
    776 URLFetcherBadHTTPSTest::URLFetcherBadHTTPSTest() {
    777   PathService::Get(base::DIR_SOURCE_ROOT, &cert_dir_);
    778   cert_dir_ = cert_dir_.AppendASCII("chrome");
    779   cert_dir_ = cert_dir_.AppendASCII("test");
    780   cert_dir_ = cert_dir_.AppendASCII("data");
    781   cert_dir_ = cert_dir_.AppendASCII("ssl");
    782   cert_dir_ = cert_dir_.AppendASCII("certificates");
    783 }
    784 
    785 // The "server certificate expired" error should result in automatic
    786 // cancellation of the request by
    787 // URLRequest::Delegate::OnSSLCertificateError.
    788 void URLFetcherBadHTTPSTest::OnURLFetchComplete(
    789     const URLFetcher* source) {
    790   // This part is different from URLFetcherTest::OnURLFetchComplete
    791   // because this test expects the request to be cancelled.
    792   EXPECT_EQ(URLRequestStatus::CANCELED, source->GetStatus().status());
    793   EXPECT_EQ(ERR_ABORTED, source->GetStatus().error());
    794   EXPECT_EQ(-1, source->GetResponseCode());
    795   EXPECT_TRUE(source->GetCookies().empty());
    796   std::string data;
    797   EXPECT_TRUE(source->GetResponseAsString(&data));
    798   EXPECT_TRUE(data.empty());
    799   CleanupAfterFetchComplete();
    800 }
    801 
    802 void URLFetcherCancelTest::CreateFetcher(const GURL& url) {
    803   fetcher_ = new URLFetcherImpl(url, URLFetcher::GET, this);
    804   CancelTestURLRequestContextGetter* context_getter =
    805       new CancelTestURLRequestContextGetter(io_message_loop_proxy().get(), url);
    806   fetcher_->SetRequestContext(context_getter);
    807   fetcher_->SetMaxRetriesOn5xx(2);
    808   fetcher_->Start();
    809   // We need to wait for the creation of the URLRequestContext, since we
    810   // rely on it being destroyed as a signal to end the test.
    811   context_getter->WaitForContextCreation();
    812   CancelRequest();
    813 }
    814 
    815 void URLFetcherCancelTest::OnURLFetchComplete(
    816     const URLFetcher* source) {
    817   // We should have cancelled the request before completion.
    818   ADD_FAILURE();
    819   CleanupAfterFetchComplete();
    820 }
    821 
    822 void URLFetcherCancelTest::CancelRequest() {
    823   delete fetcher_;
    824   // The URLFetcher's test context will post a Quit task once it is
    825   // deleted. So if this test simply hangs, it means cancellation
    826   // did not work.
    827 }
    828 
    829 void URLFetcherMultipleAttemptTest::OnURLFetchComplete(
    830     const URLFetcher* source) {
    831   EXPECT_TRUE(source->GetStatus().is_success());
    832   EXPECT_EQ(200, source->GetResponseCode());  // HTTP OK
    833   std::string data;
    834   EXPECT_TRUE(source->GetResponseAsString(&data));
    835   EXPECT_FALSE(data.empty());
    836   if (!data.empty() && data_.empty()) {
    837     data_ = data;
    838     fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter(
    839         io_message_loop_proxy().get(), request_context()));
    840     fetcher_->Start();
    841   } else {
    842     EXPECT_EQ(data, data_);
    843     CleanupAfterFetchComplete();
    844   }
    845 }
    846 
    847 void URLFetcherFileTest::CreateFetcherForFile(const GURL& url,
    848                                               const base::FilePath& file_path) {
    849   fetcher_ = new URLFetcherImpl(url, URLFetcher::GET, this);
    850   fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter(
    851       io_message_loop_proxy().get(), request_context()));
    852 
    853   // Use the IO message loop to do the file operations in this test.
    854   fetcher_->SaveResponseToFileAtPath(file_path, io_message_loop_proxy());
    855   fetcher_->Start();
    856 }
    857 
    858 void URLFetcherFileTest::CreateFetcherForTempFile(const GURL& url) {
    859   fetcher_ = new URLFetcherImpl(url, URLFetcher::GET, this);
    860   fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter(
    861       io_message_loop_proxy().get(), request_context()));
    862 
    863   // Use the IO message loop to do the file operations in this test.
    864   fetcher_->SaveResponseToTemporaryFile(io_message_loop_proxy());
    865   fetcher_->Start();
    866 }
    867 
    868 void URLFetcherFileTest::OnURLFetchComplete(const URLFetcher* source) {
    869   if (expected_file_error_ == OK) {
    870     EXPECT_TRUE(source->GetStatus().is_success());
    871     EXPECT_EQ(OK, source->GetStatus().error());
    872     EXPECT_EQ(200, source->GetResponseCode());
    873 
    874     EXPECT_TRUE(source->GetResponseAsFilePath(
    875         take_ownership_of_file_, &file_path_));
    876 
    877     EXPECT_TRUE(base::ContentsEqual(expected_file_, file_path_));
    878   } else {
    879     EXPECT_FALSE(source->GetStatus().is_success());
    880     EXPECT_EQ(expected_file_error_, source->GetStatus().error());
    881   }
    882   CleanupAfterFetchComplete();
    883 }
    884 
    885 TEST_F(URLFetcherTest, SameThreadsTest) {
    886   SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP,
    887                                 SpawnedTestServer::kLocalhost,
    888                                 base::FilePath(kDocRoot));
    889   ASSERT_TRUE(test_server.Start());
    890 
    891   // Create the fetcher on the main thread.  Since IO will happen on the main
    892   // thread, this will test URLFetcher's ability to do everything on one
    893   // thread.
    894   CreateFetcher(test_server.GetURL("defaultresponse"));
    895 
    896   base::MessageLoop::current()->Run();
    897 }
    898 
    899 TEST_F(URLFetcherTest, DifferentThreadsTest) {
    900   SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP,
    901                                 SpawnedTestServer::kLocalhost,
    902                                 base::FilePath(kDocRoot));
    903   ASSERT_TRUE(test_server.Start());
    904 
    905   // Create a separate thread that will create the URLFetcher.  The current
    906   // (main) thread will do the IO, and when the fetch is complete it will
    907   // terminate the main thread's message loop; then the other thread's
    908   // message loop will be shut down automatically as the thread goes out of
    909   // scope.
    910   base::Thread t("URLFetcher test thread");
    911   ASSERT_TRUE(t.Start());
    912   t.message_loop()->PostTask(
    913       FROM_HERE,
    914       base::Bind(&URLFetcherTest::CreateFetcher,
    915                  base::Unretained(this),
    916                  test_server.GetURL("defaultresponse")));
    917 
    918   base::MessageLoop::current()->Run();
    919 }
    920 
    921 void CancelAllOnIO() {
    922   EXPECT_EQ(1, URLFetcherTest::GetNumFetcherCores());
    923   URLFetcherImpl::CancelAll();
    924   EXPECT_EQ(0, URLFetcherTest::GetNumFetcherCores());
    925 }
    926 
    927 // Tests to make sure CancelAll() will successfully cancel existing URLFetchers.
    928 TEST_F(URLFetcherTest, CancelAll) {
    929   SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP,
    930                                 SpawnedTestServer::kLocalhost,
    931                                 base::FilePath(kDocRoot));
    932   ASSERT_TRUE(test_server.Start());
    933   EXPECT_EQ(0, GetNumFetcherCores());
    934 
    935   CreateFetcher(test_server.GetURL("defaultresponse"));
    936   io_message_loop_proxy()->PostTaskAndReply(
    937       FROM_HERE, base::Bind(&CancelAllOnIO), base::MessageLoop::QuitClosure());
    938   base::MessageLoop::current()->Run();
    939   EXPECT_EQ(0, GetNumFetcherCores());
    940   delete fetcher_;
    941 }
    942 
    943 TEST_F(URLFetcherMockDnsTest, DontRetryOnNetworkChangedByDefault) {
    944   EXPECT_EQ(0, GetNumFetcherCores());
    945   EXPECT_FALSE(resolver_.has_pending_requests());
    946 
    947   // This posts a task to start the fetcher.
    948   CreateFetcher(test_url_);
    949   fetcher_->Start();
    950   EXPECT_EQ(0, GetNumFetcherCores());
    951   base::MessageLoop::current()->RunUntilIdle();
    952 
    953   // The fetcher is now running, but is pending the host resolve.
    954   EXPECT_EQ(1, GetNumFetcherCores());
    955   EXPECT_TRUE(resolver_.has_pending_requests());
    956   ASSERT_FALSE(completed_fetcher_);
    957 
    958   // A network change notification aborts the connect job.
    959   NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
    960   base::MessageLoop::current()->RunUntilIdle();
    961   EXPECT_EQ(0, GetNumFetcherCores());
    962   EXPECT_FALSE(resolver_.has_pending_requests());
    963   ASSERT_TRUE(completed_fetcher_);
    964 
    965   // And the owner of the fetcher gets the ERR_NETWORK_CHANGED error.
    966   EXPECT_EQ(ERR_NETWORK_CHANGED, completed_fetcher_->GetStatus().error());
    967 }
    968 
    969 TEST_F(URLFetcherMockDnsTest, RetryOnNetworkChangedAndFail) {
    970   EXPECT_EQ(0, GetNumFetcherCores());
    971   EXPECT_FALSE(resolver_.has_pending_requests());
    972 
    973   // This posts a task to start the fetcher.
    974   CreateFetcher(test_url_);
    975   fetcher_->SetAutomaticallyRetryOnNetworkChanges(3);
    976   fetcher_->Start();
    977   EXPECT_EQ(0, GetNumFetcherCores());
    978   base::MessageLoop::current()->RunUntilIdle();
    979 
    980   // The fetcher is now running, but is pending the host resolve.
    981   EXPECT_EQ(1, GetNumFetcherCores());
    982   EXPECT_TRUE(resolver_.has_pending_requests());
    983   ASSERT_FALSE(completed_fetcher_);
    984 
    985   // Make it fail 3 times.
    986   for (int i = 0; i < 3; ++i) {
    987     // A network change notification aborts the connect job.
    988     NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
    989     base::MessageLoop::current()->RunUntilIdle();
    990 
    991     // But the fetcher retries automatically.
    992     EXPECT_EQ(1, GetNumFetcherCores());
    993     EXPECT_TRUE(resolver_.has_pending_requests());
    994     ASSERT_FALSE(completed_fetcher_);
    995   }
    996 
    997   // A 4th failure doesn't trigger another retry, and propagates the error
    998   // to the owner of the fetcher.
    999   NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
   1000   base::MessageLoop::current()->RunUntilIdle();
   1001   EXPECT_EQ(0, GetNumFetcherCores());
   1002   EXPECT_FALSE(resolver_.has_pending_requests());
   1003   ASSERT_TRUE(completed_fetcher_);
   1004 
   1005   // And the owner of the fetcher gets the ERR_NETWORK_CHANGED error.
   1006   EXPECT_EQ(ERR_NETWORK_CHANGED, completed_fetcher_->GetStatus().error());
   1007 }
   1008 
   1009 TEST_F(URLFetcherMockDnsTest, RetryOnNetworkChangedAndSucceed) {
   1010   EXPECT_EQ(0, GetNumFetcherCores());
   1011   EXPECT_FALSE(resolver_.has_pending_requests());
   1012 
   1013   // This posts a task to start the fetcher.
   1014   CreateFetcher(test_url_);
   1015   fetcher_->SetAutomaticallyRetryOnNetworkChanges(3);
   1016   fetcher_->Start();
   1017   EXPECT_EQ(0, GetNumFetcherCores());
   1018   base::MessageLoop::current()->RunUntilIdle();
   1019 
   1020   // The fetcher is now running, but is pending the host resolve.
   1021   EXPECT_EQ(1, GetNumFetcherCores());
   1022   EXPECT_TRUE(resolver_.has_pending_requests());
   1023   ASSERT_FALSE(completed_fetcher_);
   1024 
   1025   // Make it fail 3 times.
   1026   for (int i = 0; i < 3; ++i) {
   1027     // A network change notification aborts the connect job.
   1028     NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
   1029     base::MessageLoop::current()->RunUntilIdle();
   1030 
   1031     // But the fetcher retries automatically.
   1032     EXPECT_EQ(1, GetNumFetcherCores());
   1033     EXPECT_TRUE(resolver_.has_pending_requests());
   1034     ASSERT_FALSE(completed_fetcher_);
   1035   }
   1036 
   1037   // Now let it succeed by resolving the pending request.
   1038   resolver_.ResolveAllPending();
   1039   base::MessageLoop::current()->Run();
   1040 
   1041   // URLFetcherMockDnsTest::OnURLFetchComplete() will quit the loop.
   1042   EXPECT_EQ(0, GetNumFetcherCores());
   1043   EXPECT_FALSE(resolver_.has_pending_requests());
   1044   ASSERT_TRUE(completed_fetcher_);
   1045 
   1046   // This time the request succeeded.
   1047   EXPECT_EQ(OK, completed_fetcher_->GetStatus().error());
   1048   EXPECT_EQ(200, completed_fetcher_->GetResponseCode());
   1049 }
   1050 
   1051 TEST_F(URLFetcherPostTest, Basic) {
   1052   SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP,
   1053                                 SpawnedTestServer::kLocalhost,
   1054                                 base::FilePath(kDocRoot));
   1055   ASSERT_TRUE(test_server.Start());
   1056 
   1057   CreateFetcher(test_server.GetURL("echo"));
   1058   base::MessageLoop::current()->Run();
   1059 }
   1060 
   1061 TEST_F(URLFetcherPostFileTest, Basic) {
   1062   SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP,
   1063                                 SpawnedTestServer::kLocalhost,
   1064                                 base::FilePath(kDocRoot));
   1065   ASSERT_TRUE(test_server.Start());
   1066 
   1067   CreateFetcher(test_server.GetURL("echo"));
   1068   base::MessageLoop::current()->Run();
   1069 }
   1070 
   1071 TEST_F(URLFetcherPostFileTest, Range) {
   1072   SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP,
   1073                                 SpawnedTestServer::kLocalhost,
   1074                                 base::FilePath(kDocRoot));
   1075   ASSERT_TRUE(test_server.Start());
   1076 
   1077   SetUploadRange(30, 100);
   1078 
   1079   CreateFetcher(test_server.GetURL("echo"));
   1080   base::MessageLoop::current()->Run();
   1081 }
   1082 
   1083 TEST_F(URLFetcherEmptyPostTest, Basic) {
   1084   SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP,
   1085                                 SpawnedTestServer::kLocalhost,
   1086                                 base::FilePath(kDocRoot));
   1087   ASSERT_TRUE(test_server.Start());
   1088 
   1089   CreateFetcher(test_server.GetURL("echo"));
   1090   base::MessageLoop::current()->Run();
   1091 }
   1092 
   1093 TEST_F(URLFetcherUploadProgressTest, Basic) {
   1094   SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP,
   1095                                 SpawnedTestServer::kLocalhost,
   1096                                 base::FilePath(kDocRoot));
   1097   ASSERT_TRUE(test_server.Start());
   1098 
   1099   CreateFetcher(test_server.GetURL("echo"));
   1100   base::MessageLoop::current()->Run();
   1101 }
   1102 
   1103 TEST_F(URLFetcherDownloadProgressTest, Basic) {
   1104   SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP,
   1105                                 SpawnedTestServer::kLocalhost,
   1106                                 base::FilePath(kDocRoot));
   1107   ASSERT_TRUE(test_server.Start());
   1108 
   1109   // Get a file large enough to require more than one read into
   1110   // URLFetcher::Core's IOBuffer.
   1111   static const char kFileToFetch[] = "animate1.gif";
   1112   // Hardcoded file size - it cannot be easily fetched when a remote http server
   1113   // is used for testing.
   1114   static const int64 kFileSize = 19021;
   1115 
   1116   expected_total_ = kFileSize;
   1117 
   1118   CreateFetcher(test_server.GetURL(
   1119       std::string(kTestServerFilePrefix) + kFileToFetch));
   1120 
   1121   base::MessageLoop::current()->Run();
   1122 }
   1123 
   1124 TEST_F(URLFetcherDownloadProgressCancelTest, CancelWhileProgressReport) {
   1125   SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP,
   1126                                 SpawnedTestServer::kLocalhost,
   1127                                 base::FilePath(kDocRoot));
   1128   ASSERT_TRUE(test_server.Start());
   1129 
   1130   // Get a file large enough to require more than one read into
   1131   // URLFetcher::Core's IOBuffer.
   1132   static const char kFileToFetch[] = "animate1.gif";
   1133   CreateFetcher(test_server.GetURL(
   1134       std::string(kTestServerFilePrefix) + kFileToFetch));
   1135 
   1136   base::MessageLoop::current()->Run();
   1137 }
   1138 
   1139 TEST_F(URLFetcherHeadersTest, Headers) {
   1140   SpawnedTestServer test_server(
   1141       SpawnedTestServer::TYPE_HTTP,
   1142       SpawnedTestServer::kLocalhost,
   1143       base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest")));
   1144   ASSERT_TRUE(test_server.Start());
   1145 
   1146   CreateFetcher(test_server.GetURL("files/with-headers.html"));
   1147   base::MessageLoop::current()->Run();
   1148   // The actual tests are in the URLFetcherHeadersTest fixture.
   1149 }
   1150 
   1151 TEST_F(URLFetcherSocketAddressTest, SocketAddress) {
   1152   SpawnedTestServer test_server(
   1153       SpawnedTestServer::TYPE_HTTP,
   1154       SpawnedTestServer::kLocalhost,
   1155       base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest")));
   1156   ASSERT_TRUE(test_server.Start());
   1157   expected_port_ = test_server.host_port_pair().port();
   1158 
   1159   // Reusing "with-headers.html" but doesn't really matter.
   1160   CreateFetcher(test_server.GetURL("files/with-headers.html"));
   1161   base::MessageLoop::current()->Run();
   1162   // The actual tests are in the URLFetcherSocketAddressTest fixture.
   1163 }
   1164 
   1165 TEST_F(URLFetcherStopOnRedirectTest, StopOnRedirect) {
   1166   SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP,
   1167                                 SpawnedTestServer::kLocalhost,
   1168                                 base::FilePath(kDocRoot));
   1169   ASSERT_TRUE(test_server.Start());
   1170 
   1171   CreateFetcher(
   1172       test_server.GetURL(std::string("server-redirect?") + kRedirectTarget));
   1173   base::MessageLoop::current()->Run();
   1174   EXPECT_TRUE(callback_called_);
   1175 }
   1176 
   1177 TEST_F(URLFetcherProtectTest, Overload) {
   1178   SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP,
   1179                                 SpawnedTestServer::kLocalhost,
   1180                                 base::FilePath(kDocRoot));
   1181   ASSERT_TRUE(test_server.Start());
   1182 
   1183   GURL url(test_server.GetURL("defaultresponse"));
   1184 
   1185   // Registers an entry for test url. It only allows 3 requests to be sent
   1186   // in 200 milliseconds.
   1187   scoped_refptr<URLRequestThrottlerEntry> entry(
   1188       new URLRequestThrottlerEntry(request_context()->throttler_manager(),
   1189                                    std::string(),
   1190                                    200,
   1191                                    3,
   1192                                    1,
   1193                                    2.0,
   1194                                    0.0,
   1195                                    256));
   1196   request_context()->throttler_manager()
   1197       ->OverrideEntryForTests(url, entry.get());
   1198 
   1199   CreateFetcher(url);
   1200 
   1201   base::MessageLoop::current()->Run();
   1202 }
   1203 
   1204 TEST_F(URLFetcherProtectTest, ServerUnavailable) {
   1205   SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP,
   1206                                 SpawnedTestServer::kLocalhost,
   1207                                 base::FilePath(kDocRoot));
   1208   ASSERT_TRUE(test_server.Start());
   1209 
   1210   GURL url(test_server.GetURL("files/server-unavailable.html"));
   1211 
   1212   // Registers an entry for test url. The backoff time is calculated by:
   1213   //     new_backoff = 2.0 * old_backoff + 0
   1214   // and maximum backoff time is 256 milliseconds.
   1215   // Maximum retries allowed is set to 11.
   1216   scoped_refptr<URLRequestThrottlerEntry> entry(
   1217       new URLRequestThrottlerEntry(request_context()->throttler_manager(),
   1218                                    std::string(),
   1219                                    200,
   1220                                    3,
   1221                                    1,
   1222                                    2.0,
   1223                                    0.0,
   1224                                    256));
   1225   request_context()->throttler_manager()
   1226       ->OverrideEntryForTests(url, entry.get());
   1227 
   1228   CreateFetcher(url);
   1229 
   1230   base::MessageLoop::current()->Run();
   1231 }
   1232 
   1233 TEST_F(URLFetcherProtectTestPassedThrough, ServerUnavailablePropagateResponse) {
   1234   SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP,
   1235                                 SpawnedTestServer::kLocalhost,
   1236                                 base::FilePath(kDocRoot));
   1237   ASSERT_TRUE(test_server.Start());
   1238 
   1239   GURL url(test_server.GetURL("files/server-unavailable.html"));
   1240 
   1241   // Registers an entry for test url. The backoff time is calculated by:
   1242   //     new_backoff = 2.0 * old_backoff + 0
   1243   // and maximum backoff time is 150000 milliseconds.
   1244   // Maximum retries allowed is set to 11.
   1245   scoped_refptr<URLRequestThrottlerEntry> entry(
   1246       new URLRequestThrottlerEntry(request_context()->throttler_manager(),
   1247                                    std::string(),
   1248                                    200,
   1249                                    3,
   1250                                    100,
   1251                                    2.0,
   1252                                    0.0,
   1253                                    150000));
   1254   // Total time if *not* for not doing automatic backoff would be 150s.
   1255   // In reality it should be "as soon as server responds".
   1256   request_context()->throttler_manager()
   1257       ->OverrideEntryForTests(url, entry.get());
   1258 
   1259   CreateFetcher(url);
   1260 
   1261   base::MessageLoop::current()->Run();
   1262 }
   1263 
   1264 TEST_F(URLFetcherBadHTTPSTest, BadHTTPSTest) {
   1265   SpawnedTestServer::SSLOptions ssl_options(
   1266       SpawnedTestServer::SSLOptions::CERT_EXPIRED);
   1267   SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS,
   1268                                 ssl_options,
   1269                                 base::FilePath(kDocRoot));
   1270   ASSERT_TRUE(test_server.Start());
   1271 
   1272   CreateFetcher(test_server.GetURL("defaultresponse"));
   1273   base::MessageLoop::current()->Run();
   1274 }
   1275 
   1276 TEST_F(URLFetcherCancelTest, ReleasesContext) {
   1277   SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP,
   1278                                 SpawnedTestServer::kLocalhost,
   1279                                 base::FilePath(kDocRoot));
   1280   ASSERT_TRUE(test_server.Start());
   1281 
   1282   GURL url(test_server.GetURL("files/server-unavailable.html"));
   1283 
   1284   // Create a separate thread that will create the URLFetcher.  The current
   1285   // (main) thread will do the IO, and when the fetch is complete it will
   1286   // terminate the main thread's message loop; then the other thread's
   1287   // message loop will be shut down automatically as the thread goes out of
   1288   // scope.
   1289   base::Thread t("URLFetcher test thread");
   1290   ASSERT_TRUE(t.Start());
   1291   t.message_loop()->PostTask(
   1292       FROM_HERE,
   1293       base::Bind(&URLFetcherCancelTest::CreateFetcher,
   1294                  base::Unretained(this), url));
   1295 
   1296   base::MessageLoop::current()->Run();
   1297 }
   1298 
   1299 TEST_F(URLFetcherCancelTest, CancelWhileDelayedStartTaskPending) {
   1300   SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP,
   1301                                 SpawnedTestServer::kLocalhost,
   1302                                 base::FilePath(kDocRoot));
   1303   ASSERT_TRUE(test_server.Start());
   1304 
   1305   GURL url(test_server.GetURL("files/server-unavailable.html"));
   1306 
   1307   // Register an entry for test url.
   1308   // Using a sliding window of 4 seconds, and max of 1 request, under a fast
   1309   // run we expect to have a 4 second delay when posting the Start task.
   1310   scoped_refptr<URLRequestThrottlerEntry> entry(
   1311       new URLRequestThrottlerEntry(request_context()->throttler_manager(),
   1312                                    std::string(),
   1313                                    4000,
   1314                                    1,
   1315                                    2000,
   1316                                    2.0,
   1317                                    0.0,
   1318                                    4000));
   1319   request_context()->throttler_manager()
   1320       ->OverrideEntryForTests(url, entry.get());
   1321   // Fake that a request has just started.
   1322   entry->ReserveSendingTimeForNextRequest(base::TimeTicks());
   1323 
   1324   // The next request we try to send will be delayed by ~4 seconds.
   1325   // The slower the test runs, the less the delay will be (since it takes the
   1326   // time difference from now).
   1327 
   1328   base::Thread t("URLFetcher test thread");
   1329   ASSERT_TRUE(t.Start());
   1330   t.message_loop()->PostTask(
   1331       FROM_HERE,
   1332       base::Bind(&URLFetcherTest::CreateFetcher, base::Unretained(this), url));
   1333 
   1334   base::MessageLoop::current()->Run();
   1335 }
   1336 
   1337 TEST_F(URLFetcherMultipleAttemptTest, SameData) {
   1338   SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP,
   1339                                 SpawnedTestServer::kLocalhost,
   1340                                 base::FilePath(kDocRoot));
   1341   ASSERT_TRUE(test_server.Start());
   1342 
   1343   // Create the fetcher on the main thread.  Since IO will happen on the main
   1344   // thread, this will test URLFetcher's ability to do everything on one
   1345   // thread.
   1346   CreateFetcher(test_server.GetURL("defaultresponse"));
   1347 
   1348   base::MessageLoop::current()->Run();
   1349 }
   1350 
   1351 TEST_F(URLFetcherFileTest, SmallGet) {
   1352   SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP,
   1353                                 SpawnedTestServer::kLocalhost,
   1354                                 base::FilePath(kDocRoot));
   1355   ASSERT_TRUE(test_server.Start());
   1356 
   1357   base::ScopedTempDir temp_dir;
   1358   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
   1359 
   1360   // Get a small file.
   1361   static const char kFileToFetch[] = "simple.html";
   1362   expected_file_ = test_server.GetDocumentRoot().AppendASCII(kFileToFetch);
   1363   CreateFetcherForFile(
   1364       test_server.GetURL(std::string(kTestServerFilePrefix) + kFileToFetch),
   1365       temp_dir.path().AppendASCII(kFileToFetch));
   1366 
   1367   base::MessageLoop::current()->Run();  // OnURLFetchComplete() will Quit().
   1368 
   1369   ASSERT_FALSE(base::PathExists(file_path_))
   1370       << file_path_.value() << " not removed.";
   1371 }
   1372 
   1373 TEST_F(URLFetcherFileTest, LargeGet) {
   1374   SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP,
   1375                                 SpawnedTestServer::kLocalhost,
   1376                                 base::FilePath(kDocRoot));
   1377   ASSERT_TRUE(test_server.Start());
   1378 
   1379   base::ScopedTempDir temp_dir;
   1380   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
   1381 
   1382   // Get a file large enough to require more than one read into
   1383   // URLFetcher::Core's IOBuffer.
   1384   static const char kFileToFetch[] = "animate1.gif";
   1385   expected_file_ = test_server.GetDocumentRoot().AppendASCII(kFileToFetch);
   1386   CreateFetcherForFile(
   1387       test_server.GetURL(std::string(kTestServerFilePrefix) + kFileToFetch),
   1388       temp_dir.path().AppendASCII(kFileToFetch));
   1389 
   1390   base::MessageLoop::current()->Run();  // OnURLFetchComplete() will Quit().
   1391 }
   1392 
   1393 TEST_F(URLFetcherFileTest, SavedOutputFileOwnerhisp) {
   1394   // If the caller takes the ownership of the output file, the file should
   1395   // persist even after URLFetcher is gone. If not, the file must be deleted.
   1396   const bool kTake[] = {false, true};
   1397   for (size_t i = 0; i < arraysize(kTake); ++i) {
   1398     take_ownership_of_file_ = kTake[i];
   1399     SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP,
   1400                                   SpawnedTestServer::kLocalhost,
   1401                                   base::FilePath(kDocRoot));
   1402     ASSERT_TRUE(test_server.Start());
   1403 
   1404     base::ScopedTempDir temp_dir;
   1405     ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
   1406 
   1407     // Get a small file.
   1408     static const char kFileToFetch[] = "simple.html";
   1409     expected_file_ = test_server.GetDocumentRoot().AppendASCII(kFileToFetch);
   1410     CreateFetcherForFile(
   1411         test_server.GetURL(std::string(kTestServerFilePrefix) + kFileToFetch),
   1412         temp_dir.path().AppendASCII(kFileToFetch));
   1413 
   1414     base::MessageLoop::current()->Run();  // OnURLFetchComplete() will Quit().
   1415 
   1416     base::MessageLoop::current()->RunUntilIdle();
   1417     ASSERT_EQ(kTake[i], base::PathExists(file_path_)) <<
   1418         "FilePath: " << file_path_.value();
   1419   }
   1420 }
   1421 
   1422 TEST_F(URLFetcherFileTest, OverwriteExistingFile) {
   1423   SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP,
   1424                                 SpawnedTestServer::kLocalhost,
   1425                                 base::FilePath(kDocRoot));
   1426   ASSERT_TRUE(test_server.Start());
   1427 
   1428   base::ScopedTempDir temp_dir;
   1429   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
   1430 
   1431   // Create a file before trying to fetch.
   1432   static const char kFileToFetch[] = "simple.html";
   1433   std::string data(10000, '?');  // Meant to be larger than simple.html.
   1434   file_path_ = temp_dir.path().AppendASCII(kFileToFetch);
   1435   ASSERT_EQ(static_cast<int>(data.size()),
   1436             base::WriteFile(file_path_, data.data(), data.size()));
   1437   ASSERT_TRUE(base::PathExists(file_path_));
   1438   expected_file_ = test_server.GetDocumentRoot().AppendASCII(kFileToFetch);
   1439   ASSERT_FALSE(base::ContentsEqual(file_path_, expected_file_));
   1440 
   1441   // Get a small file.
   1442   CreateFetcherForFile(
   1443       test_server.GetURL(std::string(kTestServerFilePrefix) + kFileToFetch),
   1444       file_path_);
   1445 
   1446   base::MessageLoop::current()->Run();  // OnURLFetchComplete() will Quit().
   1447 }
   1448 
   1449 TEST_F(URLFetcherFileTest, TryToOverwriteDirectory) {
   1450   SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP,
   1451                                 SpawnedTestServer::kLocalhost,
   1452                                 base::FilePath(kDocRoot));
   1453   ASSERT_TRUE(test_server.Start());
   1454 
   1455   base::ScopedTempDir temp_dir;
   1456   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
   1457 
   1458   // Create a directory before trying to fetch.
   1459   static const char kFileToFetch[] = "simple.html";
   1460   file_path_ = temp_dir.path().AppendASCII(kFileToFetch);
   1461   ASSERT_TRUE(base::CreateDirectory(file_path_));
   1462   ASSERT_TRUE(base::PathExists(file_path_));
   1463 
   1464   // Get a small file.
   1465   expected_file_error_ = ERR_ACCESS_DENIED;
   1466   expected_file_ = test_server.GetDocumentRoot().AppendASCII(kFileToFetch);
   1467   CreateFetcherForFile(
   1468       test_server.GetURL(std::string(kTestServerFilePrefix) + kFileToFetch),
   1469       file_path_);
   1470 
   1471   base::MessageLoop::current()->Run();  // OnURLFetchComplete() will Quit().
   1472 
   1473   base::MessageLoop::current()->RunUntilIdle();
   1474 }
   1475 
   1476 TEST_F(URLFetcherFileTest, SmallGetToTempFile) {
   1477   SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP,
   1478                                 SpawnedTestServer::kLocalhost,
   1479                                 base::FilePath(kDocRoot));
   1480   ASSERT_TRUE(test_server.Start());
   1481 
   1482   // Get a small file.
   1483   static const char kFileToFetch[] = "simple.html";
   1484   expected_file_ = test_server.GetDocumentRoot().AppendASCII(kFileToFetch);
   1485   CreateFetcherForTempFile(
   1486       test_server.GetURL(std::string(kTestServerFilePrefix) + kFileToFetch));
   1487 
   1488   base::MessageLoop::current()->Run();  // OnURLFetchComplete() will Quit().
   1489 
   1490   ASSERT_FALSE(base::PathExists(file_path_))
   1491       << file_path_.value() << " not removed.";
   1492 }
   1493 
   1494 TEST_F(URLFetcherFileTest, LargeGetToTempFile) {
   1495   SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP,
   1496                                 SpawnedTestServer::kLocalhost,
   1497                                 base::FilePath(kDocRoot));
   1498   ASSERT_TRUE(test_server.Start());
   1499 
   1500   // Get a file large enough to require more than one read into
   1501   // URLFetcher::Core's IOBuffer.
   1502   static const char kFileToFetch[] = "animate1.gif";
   1503   expected_file_ = test_server.GetDocumentRoot().AppendASCII(kFileToFetch);
   1504   CreateFetcherForTempFile(test_server.GetURL(
   1505       std::string(kTestServerFilePrefix) + kFileToFetch));
   1506 
   1507   base::MessageLoop::current()->Run();  // OnURLFetchComplete() will Quit().
   1508 }
   1509 
   1510 TEST_F(URLFetcherFileTest, SavedOutputTempFileOwnerhisp) {
   1511   // If the caller takes the ownership of the temp file, the file should persist
   1512   // even after URLFetcher is gone. If not, the file must be deleted.
   1513   const bool kTake[] = {false, true};
   1514   for (size_t i = 0; i < arraysize(kTake); ++i) {
   1515     take_ownership_of_file_ = kTake[i];
   1516 
   1517     SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP,
   1518                                   SpawnedTestServer::kLocalhost,
   1519                                   base::FilePath(kDocRoot));
   1520     ASSERT_TRUE(test_server.Start());
   1521 
   1522     // Get a small file.
   1523     static const char kFileToFetch[] = "simple.html";
   1524     expected_file_ = test_server.GetDocumentRoot().AppendASCII(kFileToFetch);
   1525     CreateFetcherForTempFile(test_server.GetURL(
   1526         std::string(kTestServerFilePrefix) + kFileToFetch));
   1527 
   1528     base::MessageLoop::current()->Run();  // OnURLFetchComplete() will Quit().
   1529 
   1530     base::MessageLoop::current()->RunUntilIdle();
   1531     ASSERT_EQ(kTake[i], base::PathExists(file_path_)) <<
   1532         "FilePath: " << file_path_.value();
   1533   }
   1534 }
   1535 
   1536 }  // namespace
   1537 
   1538 }  // namespace net
   1539