// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/url_request/url_fetcher_impl.h"

#include <algorithm>
#include <string>

#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/macros.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/stringprintf.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h"
#include "build/build_config.h"
#include "crypto/nss_util.h"
#include "net/base/elements_upload_data_stream.h"
#include "net/base/network_change_notifier.h"
#include "net/base/upload_bytes_element_reader.h"
#include "net/base/upload_element_reader.h"
#include "net/base/upload_file_element_reader.h"
#include "net/dns/mock_host_resolver.h"
#include "net/http/http_response_headers.h"
#include "net/test/spawned_test_server/spawned_test_server.h"
#include "net/url_request/url_fetcher_delegate.h"
#include "net/url_request/url_request_context_getter.h"
#include "net/url_request/url_request_test_util.h"
#include "net/url_request/url_request_throttler_manager.h"
#include "testing/gtest/include/gtest/gtest.h"

#if defined(USE_NSS_CERTS) || defined(OS_IOS)
#include "net/cert_net/nss_ocsp.h"
#endif

namespace net {

using base::Time;
using base::TimeDelta;

// TODO(eroman): Add a regression test for http://crbug.com/40505.

namespace {

// TODO(akalin): Move all the test data to somewhere under net/.
const base::FilePath::CharType kDocRoot[] =
    FILE_PATH_LITERAL("net/data/url_fetcher_impl_unittest");
const char kTestServerFilePrefix[] = "files/";

// Test server path and response body for the default URL used by many of the
// tests.
const char kDefaultResponsePath[] = "defaultresponse";
const char kDefaultResponseBody[] =
    "Default response given for path: /defaultresponse";

// Request body for streams created by CreateUploadStream.
const char kCreateUploadStreamBody[] = "rosebud";

base::FilePath GetUploadFileTestPath() {
  base::FilePath path;
  PathService::Get(base::DIR_SOURCE_ROOT, &path);
  return path.Append(
      FILE_PATH_LITERAL("net/data/url_request_unittest/BullRunSpeech.txt"));
}

// Simple URLRequestDelegate that waits for the specified fetcher to complete.
// Can only be used once.
class WaitingURLFetcherDelegate : public URLFetcherDelegate {
 public:
  WaitingURLFetcherDelegate() : did_complete_(false) {}

  void CreateFetcher(
      const GURL& url,
      URLFetcher::RequestType request_type,
      scoped_refptr<net::URLRequestContextGetter> context_getter) {
    fetcher_.reset(new URLFetcherImpl(url, request_type, this));
    fetcher_->SetRequestContext(context_getter.get());
  }

  URLFetcher* fetcher() const { return fetcher_.get(); }

  // Wait until the request has completed or been canceled.
  void StartFetcherAndWait() {
    fetcher_->Start();
    WaitForComplete();
  }

  // Wait until the request has completed or been canceled. Does not start the
  // request.
  void WaitForComplete() { run_loop_.Run(); }

  // Cancels the fetch by deleting the fetcher.
  void CancelFetch() {
    EXPECT_TRUE(fetcher_);
    fetcher_.reset();
    run_loop_.Quit();
  }

  // URLFetcherDelegate:
  void OnURLFetchComplete(const URLFetcher* source) override {
    EXPECT_FALSE(did_complete_);
    EXPECT_TRUE(fetcher_);
    EXPECT_EQ(fetcher_.get(), source);
    did_complete_ = true;
    run_loop_.Quit();
  }

  void OnURLFetchDownloadProgress(const URLFetcher* source,
                                  int64 current,
                                  int64 total) override {
    // Note that the current progress may be greater than the previous progress,
    // in the case of retrying the request.
    EXPECT_FALSE(did_complete_);
    EXPECT_TRUE(fetcher_);
    EXPECT_EQ(source, fetcher_.get());

    EXPECT_LE(0, current);
    // If file size is not known, |total| is -1.
    if (total >= 0)
      EXPECT_LE(current, total);
  }

  void OnURLFetchUploadProgress(const URLFetcher* source,
                                int64 current,
                                int64 total) override {
    // Note that the current progress may be greater than the previous progress,
    // in the case of retrying the request.
    EXPECT_FALSE(did_complete_);
    EXPECT_TRUE(fetcher_);
    EXPECT_EQ(source, fetcher_.get());

    EXPECT_LE(0, current);
    // If file size is not known, |total| is -1.
    if (total >= 0)
      EXPECT_LE(current, total);
  }

  bool did_complete() const { return did_complete_; }

 private:
  bool did_complete_;

  scoped_ptr<URLFetcherImpl> fetcher_;
  base::RunLoop run_loop_;

  DISALLOW_COPY_AND_ASSIGN(WaitingURLFetcherDelegate);
};

// A TestURLRequestContext with a ThrottleManager and a MockHostResolver.
class FetcherTestURLRequestContext : public TestURLRequestContext {
 public:
  // All requests for |hanging_domain| will hang on host resolution until the
  // mock_resolver()->ResolveAllPending() is called.
  explicit FetcherTestURLRequestContext(const std::string& hanging_domain)
      : TestURLRequestContext(true), mock_resolver_(new MockHostResolver()) {
    mock_resolver_->set_ondemand_mode(true);
    mock_resolver_->rules()->AddRule(hanging_domain, "127.0.0.1");
    // Pass ownership to ContextStorage to ensure correct destruction order.
    context_storage_.set_host_resolver(
        scoped_ptr<HostResolver>(mock_resolver_));
    context_storage_.set_throttler_manager(new URLRequestThrottlerManager());
    Init();
  }

  MockHostResolver* mock_resolver() { return mock_resolver_; }

 private:
  MockHostResolver* mock_resolver_;

  DISALLOW_COPY_AND_ASSIGN(FetcherTestURLRequestContext);
};

class FetcherTestURLRequestContextGetter : public URLRequestContextGetter {
 public:
  FetcherTestURLRequestContextGetter(
      scoped_refptr<base::SingleThreadTaskRunner> network_task_runner,
      const std::string& hanging_domain)
      : network_task_runner_(network_task_runner),
        hanging_domain_(hanging_domain),
        shutting_down_(false) {}

  // Sets callback to be invoked when the getter is destroyed.
  void set_on_destruction_callback(
      const base::Closure& on_destruction_callback) {
    on_destruction_callback_ = on_destruction_callback;
  }

  // URLRequestContextGetter:
  FetcherTestURLRequestContext* GetURLRequestContext() override {
    // Calling this on the wrong thread may be either a bug in the test or a bug
    // in production code.
    EXPECT_TRUE(network_task_runner_->BelongsToCurrentThread());

    if (shutting_down_)
      return nullptr;

    if (!context_)
      context_.reset(new FetcherTestURLRequestContext(hanging_domain_));
    return context_.get();
  }

  scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner()
      const override {
    return network_task_runner_;
  }

  // Adds a throttler entry with the specified parameters.  Does this
  // synchronously if the context lives on the current thread, or posts a task
  // to the relevant thread otherwise.
  //
  // If |reserve_sending_time_for_next_request|, will start backoff early, as
  // if there has already been a request for |url|.
  void AddThrottlerEntry(const GURL& url,
                         const std::string& url_id,
                         int sliding_window_period_ms,
                         int max_send_threshold,
                         int initial_backoff_ms,
                         double multiply_factor,
                         double jitter_factor,
                         int maximum_backoff_ms,
                         bool reserve_sending_time_for_next_request) {
    if (!network_task_runner_->RunsTasksOnCurrentThread()) {
      network_task_runner_->PostTask(
          FROM_HERE,
          base::Bind(&FetcherTestURLRequestContextGetter::AddThrottlerEntry,
                     this, url, url_id, sliding_window_period_ms,
                     max_send_threshold, initial_backoff_ms, multiply_factor,
                     jitter_factor, maximum_backoff_ms,
                     reserve_sending_time_for_next_request));
      return;
    }
    scoped_refptr<URLRequestThrottlerEntry> entry(new URLRequestThrottlerEntry(
        GetURLRequestContext()->throttler_manager(), url_id,
        sliding_window_period_ms, max_send_threshold, initial_backoff_ms,
        multiply_factor, jitter_factor, maximum_backoff_ms));

    GetURLRequestContext()->throttler_manager()->OverrideEntryForTests(
        url, entry.get());

    if (reserve_sending_time_for_next_request)
      entry->ReserveSendingTimeForNextRequest(base::TimeTicks());
  }

  // Tells the getter to act as if the URLRequestContext is about to be shut
  // down.
  void Shutdown() {
    if (!network_task_runner_->RunsTasksOnCurrentThread()) {
      network_task_runner_->PostTask(
          FROM_HERE,
          base::Bind(&FetcherTestURLRequestContextGetter::Shutdown, this));
      return;
    }

    shutting_down_ = true;
    NotifyContextShuttingDown();
    // Should now be safe to destroy the context.  Context will check it has no
    // pending requests.
    context_.reset();
  }

  // Convenience method to access the context as a FetcherTestURLRequestContext
  // without going through GetURLRequestContext.
  FetcherTestURLRequestContext* context() {
    DCHECK(network_task_runner_->BelongsToCurrentThread());
    return context_.get();
  }

 protected:
  ~FetcherTestURLRequestContextGetter() override {
    // |context_| may only be deleted on the network thread. Fortunately,
    // the parent class already ensures it's deleted on the network thread.
    DCHECK(network_task_runner_->BelongsToCurrentThread());
    if (!on_destruction_callback_.is_null())
      on_destruction_callback_.Run();
  }

  scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_;
  const std::string hanging_domain_;

  scoped_ptr<FetcherTestURLRequestContext> context_;
  bool shutting_down_;

  base::Closure on_destruction_callback_;

  DISALLOW_COPY_AND_ASSIGN(FetcherTestURLRequestContextGetter);
};

}  // namespace

class URLFetcherTest : public testing::Test {
 public:
  URLFetcherTest() : num_upload_streams_created_(0) {}

  static int GetNumFetcherCores() {
    return URLFetcherImpl::GetNumFetcherCores();
  }

  // Creates a URLRequestContextGetter with a URLRequestContext that lives on
  // the current thread.
  scoped_refptr<FetcherTestURLRequestContextGetter>
  CreateSameThreadContextGetter() {
    return scoped_refptr<FetcherTestURLRequestContextGetter>(
        new FetcherTestURLRequestContextGetter(
            base::MessageLoopProxy::current(), hanging_url().host()));
  }

  // Creates a URLRequestContextGetter with a URLRequestContext that lives on
  // a separate network thread.
  scoped_refptr<FetcherTestURLRequestContextGetter>
  CreateCrossThreadContextGetter() {
    if (!network_thread_) {
      network_thread_.reset(new base::Thread("network thread"));
      base::Thread::Options network_thread_options;
      network_thread_options.message_loop_type = base::MessageLoop::TYPE_IO;
      bool result = network_thread_->StartWithOptions(network_thread_options);
      CHECK(result);
    }

    return scoped_refptr<FetcherTestURLRequestContextGetter>(
        new FetcherTestURLRequestContextGetter(network_thread_->task_runner(),
                                               hanging_url().host()));
  }

  // Callback passed to URLFetcher to create upload stream by some tests.
  scoped_ptr<UploadDataStream> CreateUploadStream() {
    ++num_upload_streams_created_;
    std::vector<char> buffer(
        kCreateUploadStreamBody,
        kCreateUploadStreamBody + strlen(kCreateUploadStreamBody));
    return ElementsUploadDataStream::CreateWithReader(
        scoped_ptr<UploadElementReader>(
            new UploadOwnedBytesElementReader(&buffer)),
        0);
  }

  // Number of streams created by CreateUploadStream.
  size_t num_upload_streams_created() const {
    return num_upload_streams_created_;
  }

  // Downloads |file_to_fetch| and checks the contents when done.  If
  // |save_to_temporary_file| is true, saves it to a temporary file, and
  // |requested_out_path| is ignored. Otherwise, saves it to
  // |requested_out_path|. Takes ownership of the file if |take_ownership| is
  // true. Deletes file when done.
  void SaveFileTest(const char* file_to_fetch,
                    bool save_to_temporary_file,
                    const base::FilePath& requested_out_path,
                    bool take_ownership) {
    scoped_ptr<WaitingURLFetcherDelegate> delegate(
        new WaitingURLFetcherDelegate());
    delegate->CreateFetcher(
        test_server_->GetURL(std::string(kTestServerFilePrefix) +
                             file_to_fetch),
        URLFetcher::GET, CreateSameThreadContextGetter());
    if (save_to_temporary_file) {
      delegate->fetcher()->SaveResponseToTemporaryFile(
          scoped_refptr<base::MessageLoopProxy>(
              base::MessageLoopProxy::current()));
    } else {
      delegate->fetcher()->SaveResponseToFileAtPath(
          requested_out_path, scoped_refptr<base::MessageLoopProxy>(
                                  base::MessageLoopProxy::current()));
    }
    delegate->StartFetcherAndWait();

    EXPECT_TRUE(delegate->fetcher()->GetStatus().is_success());
    EXPECT_EQ(200, delegate->fetcher()->GetResponseCode());

    base::FilePath out_path;
    EXPECT_TRUE(
        delegate->fetcher()->GetResponseAsFilePath(take_ownership, &out_path));
    if (!save_to_temporary_file) {
      EXPECT_EQ(requested_out_path, out_path);
    }

    EXPECT_TRUE(base::ContentsEqual(
        test_server_->GetDocumentRoot().AppendASCII(file_to_fetch), out_path));

    // Delete the delegate and run the message loop to give the fetcher's
    // destructor a chance to delete the file.
    delegate.reset();
    base::RunLoop().RunUntilIdle();

    // File should only exist if |take_ownership| was true.
    EXPECT_EQ(take_ownership, base::PathExists(out_path));

    // Cleanup.
    if (base::PathExists(out_path))
      base::DeleteFile(out_path, false);
  }

  // Returns a URL that hangs on DNS resolution when using a context created by
  // the test fixture.
  const GURL& hanging_url() const { return hanging_url_; }

  // testing::Test:
  void SetUp() override {
    SetUpServer();
    ASSERT_TRUE(test_server_->Start());

    // URL that will hang when lookups reach the host resolver.
    hanging_url_ = GURL(base::StringPrintf(
        "http://example.com:%d/%s", test_server_->host_port_pair().port(),
        kDefaultResponsePath));
    ASSERT_TRUE(hanging_url_.is_valid());

#if defined(USE_NSS_CERTS) || defined(OS_IOS)
    crypto::EnsureNSSInit();
    EnsureNSSHttpIOInit();
#endif
  }

  void TearDown() override {
#if defined(USE_NSS_CERTS) || defined(OS_IOS)
    ShutdownNSSHttpIO();
#endif
  }

  // Initializes |test_server_| without starting it.  Allows subclasses to use
  // their own server configuration.
  virtual void SetUpServer() {
    test_server_.reset(new SpawnedTestServer(SpawnedTestServer::TYPE_HTTP,
                                             SpawnedTestServer::kLocalhost,
                                             base::FilePath(kDocRoot)));
  }

  // Network thread for cross-thread tests.  Most threads just use the main
  // thread for network activity.
  scoped_ptr<base::Thread> network_thread_;

  scoped_ptr<SpawnedTestServer> test_server_;
  GURL hanging_url_;

  size_t num_upload_streams_created_;
};

namespace {

// Version of URLFetcherTest that tests bad HTTPS requests.
class URLFetcherBadHTTPSTest : public URLFetcherTest {
 public:
  URLFetcherBadHTTPSTest() {}

  // URLFetcherTest:
  void SetUpServer() override {
    SpawnedTestServer::SSLOptions ssl_options(
        SpawnedTestServer::SSLOptions::CERT_EXPIRED);
    test_server_.reset(new SpawnedTestServer(
        SpawnedTestServer::TYPE_HTTPS, ssl_options, base::FilePath(kDocRoot)));
  }
};

// Create the fetcher on the main thread.  Since network IO will happen on the
// main thread, this will test URLFetcher's ability to do everything on one
// thread.
TEST_F(URLFetcherTest, SameThreadTest) {
  WaitingURLFetcherDelegate delegate;
  delegate.CreateFetcher(test_server_->GetURL(kDefaultResponsePath),
                         URLFetcher::GET, CreateSameThreadContextGetter());
  delegate.StartFetcherAndWait();

  EXPECT_TRUE(delegate.fetcher()->GetStatus().is_success());
  EXPECT_EQ(200, delegate.fetcher()->GetResponseCode());
  std::string data;
  ASSERT_TRUE(delegate.fetcher()->GetResponseAsString(&data));
  EXPECT_EQ(kDefaultResponseBody, data);
}

// Create a separate thread that will create the URLFetcher.  A separate thread
// acts as the network thread.
TEST_F(URLFetcherTest, DifferentThreadsTest) {
  WaitingURLFetcherDelegate delegate;
  delegate.CreateFetcher(test_server_->GetURL(kDefaultResponsePath),
                         URLFetcher::GET, CreateCrossThreadContextGetter());
  delegate.StartFetcherAndWait();

  EXPECT_TRUE(delegate.fetcher()->GetStatus().is_success());
  EXPECT_EQ(200, delegate.fetcher()->GetResponseCode());
  std::string data;
  ASSERT_TRUE(delegate.fetcher()->GetResponseAsString(&data));
  EXPECT_EQ(kDefaultResponseBody, data);
}

// Tests to make sure CancelAll() will successfully cancel existing URLFetchers.
TEST_F(URLFetcherTest, CancelAll) {
  EXPECT_EQ(0, GetNumFetcherCores());

  scoped_refptr<FetcherTestURLRequestContextGetter> context_getter(
      CreateSameThreadContextGetter());
  // Force context creation.
  context_getter->GetURLRequestContext();
  MockHostResolver* mock_resolver = context_getter->context()->mock_resolver();

  WaitingURLFetcherDelegate delegate;
  delegate.CreateFetcher(hanging_url(), URLFetcher::GET, context_getter);
  delegate.fetcher()->Start();
  // Wait for the request to reach the mock resolver and hang, to ensure the
  // request has actually started.
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(mock_resolver->has_pending_requests());

  EXPECT_EQ(1, URLFetcherTest::GetNumFetcherCores());
  URLFetcherImpl::CancelAll();
  EXPECT_EQ(0, URLFetcherTest::GetNumFetcherCores());
}

TEST_F(URLFetcherTest, DontRetryOnNetworkChangedByDefault) {
  EXPECT_EQ(0, GetNumFetcherCores());

  scoped_refptr<FetcherTestURLRequestContextGetter> context_getter(
      CreateSameThreadContextGetter());
  // Force context creation.
  context_getter->GetURLRequestContext();
  MockHostResolver* mock_resolver = context_getter->context()->mock_resolver();

  WaitingURLFetcherDelegate delegate;
  delegate.CreateFetcher(hanging_url(), URLFetcher::GET, context_getter);
  EXPECT_FALSE(mock_resolver->has_pending_requests());

  // This posts a task to start the fetcher.
  delegate.fetcher()->Start();
  base::RunLoop().RunUntilIdle();

  // The fetcher is now running, but is pending the host resolve.
  EXPECT_EQ(1, GetNumFetcherCores());
  EXPECT_TRUE(mock_resolver->has_pending_requests());
  ASSERT_FALSE(delegate.did_complete());

  // A network change notification aborts the connect job.
  NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
  delegate.WaitForComplete();
  EXPECT_FALSE(mock_resolver->has_pending_requests());

  // And the owner of the fetcher gets the ERR_NETWORK_CHANGED error.
  EXPECT_EQ(hanging_url(), delegate.fetcher()->GetOriginalURL());
  ASSERT_FALSE(delegate.fetcher()->GetStatus().is_success());
  EXPECT_EQ(ERR_NETWORK_CHANGED, delegate.fetcher()->GetStatus().error());
}

TEST_F(URLFetcherTest, RetryOnNetworkChangedAndFail) {
  EXPECT_EQ(0, GetNumFetcherCores());

  scoped_refptr<FetcherTestURLRequestContextGetter> context_getter(
      CreateSameThreadContextGetter());
  // Force context creation.
  context_getter->GetURLRequestContext();
  MockHostResolver* mock_resolver = context_getter->context()->mock_resolver();

  WaitingURLFetcherDelegate delegate;
  delegate.CreateFetcher(hanging_url(), URLFetcher::GET, context_getter);
  delegate.fetcher()->SetAutomaticallyRetryOnNetworkChanges(3);
  EXPECT_FALSE(mock_resolver->has_pending_requests());

  // This posts a task to start the fetcher.
  delegate.fetcher()->Start();
  base::RunLoop().RunUntilIdle();

  // The fetcher is now running, but is pending the host resolve.
  EXPECT_EQ(1, GetNumFetcherCores());
  EXPECT_TRUE(mock_resolver->has_pending_requests());
  ASSERT_FALSE(delegate.did_complete());

  // Make it fail 3 times.
  for (int i = 0; i < 3; ++i) {
    // A network change notification aborts the connect job.
    NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
    base::RunLoop().RunUntilIdle();

    // But the fetcher retries automatically.
    EXPECT_EQ(1, GetNumFetcherCores());
    EXPECT_TRUE(mock_resolver->has_pending_requests());
    ASSERT_FALSE(delegate.did_complete());
  }

  // A 4th failure doesn't trigger another retry, and propagates the error
  // to the owner of the fetcher.
  NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
  delegate.WaitForComplete();
  EXPECT_FALSE(mock_resolver->has_pending_requests());

  // And the owner of the fetcher gets the ERR_NETWORK_CHANGED error.
  EXPECT_EQ(hanging_url(), delegate.fetcher()->GetOriginalURL());
  ASSERT_FALSE(delegate.fetcher()->GetStatus().is_success());
  EXPECT_EQ(ERR_NETWORK_CHANGED, delegate.fetcher()->GetStatus().error());
}

TEST_F(URLFetcherTest, RetryOnNetworkChangedAndSucceed) {
  EXPECT_EQ(0, GetNumFetcherCores());

  scoped_refptr<FetcherTestURLRequestContextGetter> context_getter(
      CreateSameThreadContextGetter());
  // Force context creation.
  context_getter->GetURLRequestContext();
  MockHostResolver* mock_resolver = context_getter->context()->mock_resolver();

  WaitingURLFetcherDelegate delegate;
  delegate.CreateFetcher(hanging_url(), URLFetcher::GET, context_getter);
  delegate.fetcher()->SetAutomaticallyRetryOnNetworkChanges(3);
  EXPECT_FALSE(mock_resolver->has_pending_requests());

  // This posts a task to start the fetcher.
  delegate.fetcher()->Start();
  base::RunLoop().RunUntilIdle();

  // The fetcher is now running, but is pending the host resolve.
  EXPECT_EQ(1, GetNumFetcherCores());
  EXPECT_TRUE(mock_resolver->has_pending_requests());
  ASSERT_FALSE(delegate.did_complete());

  // Make it fail 3 times.
  for (int i = 0; i < 3; ++i) {
    // A network change notification aborts the connect job.
    NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
    base::RunLoop().RunUntilIdle();

    // But the fetcher retries automatically.
    EXPECT_EQ(1, GetNumFetcherCores());
    EXPECT_TRUE(mock_resolver->has_pending_requests());
    ASSERT_FALSE(delegate.did_complete());
  }

  // Now let it succeed by resolving the pending request.
  mock_resolver->ResolveAllPending();
  delegate.WaitForComplete();
  EXPECT_FALSE(mock_resolver->has_pending_requests());

  // This time the request succeeded.
  EXPECT_EQ(hanging_url(), delegate.fetcher()->GetOriginalURL());
  EXPECT_TRUE(delegate.fetcher()->GetStatus().is_success());
  EXPECT_EQ(200, delegate.fetcher()->GetResponseCode());

  std::string data;
  ASSERT_TRUE(delegate.fetcher()->GetResponseAsString(&data));
  EXPECT_EQ(kDefaultResponseBody, data);
}

TEST_F(URLFetcherTest, PostString) {
  const char kUploadData[] = "bobsyeruncle";

  WaitingURLFetcherDelegate delegate;
  delegate.CreateFetcher(test_server_->GetURL("echo"), URLFetcher::POST,
                         CreateSameThreadContextGetter());
  delegate.fetcher()->SetUploadData("application/x-www-form-urlencoded",
                                    kUploadData);
  delegate.StartFetcherAndWait();

  EXPECT_TRUE(delegate.fetcher()->GetStatus().is_success());
  EXPECT_EQ(200, delegate.fetcher()->GetResponseCode());
  std::string data;
  ASSERT_TRUE(delegate.fetcher()->GetResponseAsString(&data));
  EXPECT_EQ(kUploadData, data);
}

TEST_F(URLFetcherTest, PostEmptyString) {
  const char kUploadData[] = "";

  WaitingURLFetcherDelegate delegate;
  delegate.CreateFetcher(test_server_->GetURL("echo"), URLFetcher::POST,
                         CreateSameThreadContextGetter());
  delegate.fetcher()->SetUploadData("application/x-www-form-urlencoded",
                                    kUploadData);
  delegate.StartFetcherAndWait();

  EXPECT_TRUE(delegate.fetcher()->GetStatus().is_success());
  EXPECT_EQ(200, delegate.fetcher()->GetResponseCode());
  std::string data;
  ASSERT_TRUE(delegate.fetcher()->GetResponseAsString(&data));
  EXPECT_EQ(kUploadData, data);
}

TEST_F(URLFetcherTest, PostEntireFile) {
  base::FilePath upload_path = GetUploadFileTestPath();

  WaitingURLFetcherDelegate delegate;
  delegate.CreateFetcher(test_server_->GetURL("echo"), URLFetcher::POST,
                         CreateSameThreadContextGetter());
  delegate.fetcher()->SetUploadFilePath("application/x-www-form-urlencoded",
                                        upload_path, 0, kuint64max,
                                        base::MessageLoopProxy::current());
  delegate.StartFetcherAndWait();

  EXPECT_TRUE(delegate.fetcher()->GetStatus().is_success());
  EXPECT_EQ(200, delegate.fetcher()->GetResponseCode());

  std::string expected;
  ASSERT_TRUE(base::ReadFileToString(upload_path, &expected));
  std::string data;
  ASSERT_TRUE(delegate.fetcher()->GetResponseAsString(&data));
  EXPECT_EQ(expected, data);
}

TEST_F(URLFetcherTest, PostFileRange) {
  const size_t kRangeStart = 30;
  const size_t kRangeLength = 100;
  base::FilePath upload_path = GetUploadFileTestPath();

  WaitingURLFetcherDelegate delegate;
  delegate.CreateFetcher(test_server_->GetURL("echo"), URLFetcher::POST,
                         CreateSameThreadContextGetter());
  delegate.fetcher()->SetUploadFilePath("application/x-www-form-urlencoded",
                                        upload_path, kRangeStart, kRangeLength,
                                        base::MessageLoopProxy::current());
  delegate.StartFetcherAndWait();

  EXPECT_TRUE(delegate.fetcher()->GetStatus().is_success());
  EXPECT_EQ(200, delegate.fetcher()->GetResponseCode());

  std::string expected;
  ASSERT_TRUE(base::ReadFileToString(upload_path, &expected));
  std::string data;
  ASSERT_TRUE(delegate.fetcher()->GetResponseAsString(&data));
  EXPECT_EQ(expected.substr(kRangeStart, kRangeLength), data);
}

TEST_F(URLFetcherTest, PostWithUploadStreamFactory) {
  WaitingURLFetcherDelegate delegate;
  delegate.CreateFetcher(test_server_->GetURL("echo"), URLFetcher::POST,
                         CreateSameThreadContextGetter());
  delegate.fetcher()->SetUploadStreamFactory(
      "text/plain",
      base::Bind(&URLFetcherTest::CreateUploadStream, base::Unretained(this)));
  delegate.StartFetcherAndWait();

  EXPECT_TRUE(delegate.fetcher()->GetStatus().is_success());
  EXPECT_EQ(200, delegate.fetcher()->GetResponseCode());
  std::string data;
  ASSERT_TRUE(delegate.fetcher()->GetResponseAsString(&data));
  EXPECT_EQ(kCreateUploadStreamBody, data);
  EXPECT_EQ(1u, num_upload_streams_created());
}

TEST_F(URLFetcherTest, PostWithUploadStreamFactoryAndRetries) {
  WaitingURLFetcherDelegate delegate;
  delegate.CreateFetcher(test_server_->GetURL("echo?status=500"),
                         URLFetcher::POST, CreateSameThreadContextGetter());
  delegate.fetcher()->SetAutomaticallyRetryOn5xx(true);
  delegate.fetcher()->SetMaxRetriesOn5xx(1);
  delegate.fetcher()->SetUploadStreamFactory(
      "text/plain",
      base::Bind(&URLFetcherTest::CreateUploadStream, base::Unretained(this)));
  delegate.StartFetcherAndWait();

  EXPECT_TRUE(delegate.fetcher()->GetStatus().is_success());
  EXPECT_EQ(500, delegate.fetcher()->GetResponseCode());
  std::string data;
  ASSERT_TRUE(delegate.fetcher()->GetResponseAsString(&data));
  EXPECT_EQ(kCreateUploadStreamBody, data);
  EXPECT_EQ(2u, num_upload_streams_created());
}

// Checks that upload progress increases over time, never exceeds what's already
// been sent, and adds a chunk whenever all previously appended chunks have
// been uploaded.
class CheckUploadProgressDelegate : public WaitingURLFetcherDelegate {
 public:
  CheckUploadProgressDelegate()
      : chunk_(1 << 16, 'a'), num_chunks_appended_(0), last_seen_progress_(0) {}
  ~CheckUploadProgressDelegate() override {}

  void OnURLFetchUploadProgress(const URLFetcher* source,
                                int64 current,
                                int64 total) override {
    // Run default checks.
    WaitingURLFetcherDelegate::OnURLFetchUploadProgress(source, current, total);

    EXPECT_LE(last_seen_progress_, current);
    EXPECT_LE(current, bytes_appended());
    last_seen_progress_ = current;
    MaybeAppendChunk();
  }

  // Append the next chunk if all previously appended chunks have been sent.
  void MaybeAppendChunk() {
    const int kNumChunks = 5;
    if (last_seen_progress_ == bytes_appended() &&
        num_chunks_appended_ < kNumChunks) {
      ++num_chunks_appended_;
      fetcher()->AppendChunkToUpload(chunk_,
                                     num_chunks_appended_ == kNumChunks);
    }
  }

 private:
  int64 bytes_appended() const { return num_chunks_appended_ * chunk_.size(); }

  const std::string chunk_;

  int64 num_chunks_appended_;
  int64 last_seen_progress_;

  DISALLOW_COPY_AND_ASSIGN(CheckUploadProgressDelegate);
};

TEST_F(URLFetcherTest, UploadProgress) {
  CheckUploadProgressDelegate delegate;
  delegate.CreateFetcher(test_server_->GetURL("echo"), URLFetcher::POST,
                         CreateSameThreadContextGetter());
  // Use a chunked upload so that the upload can be paused after uploading data.
  // Since upload progress uses a timer, the delegate may not receive any
  // notification otherwise.
  delegate.fetcher()->SetChunkedUpload("application/x-www-form-urlencoded");

  delegate.fetcher()->Start();
  // Append the first chunk.  Others will be appended automatically in response
  // to OnURLFetchUploadProgress events.
  delegate.MaybeAppendChunk();
  delegate.WaitForComplete();

  // Make sure there are no pending events that cause problems when run.
  base::RunLoop().RunUntilIdle();

  EXPECT_TRUE(delegate.fetcher()->GetStatus().is_success());
  EXPECT_EQ(200, delegate.fetcher()->GetResponseCode());
  EXPECT_TRUE(delegate.did_complete());
}

// Checks that download progress never decreases, never exceeds file size, and
// that file size is correctly reported.
class CheckDownloadProgressDelegate : public WaitingURLFetcherDelegate {
 public:
  CheckDownloadProgressDelegate(int64 file_size)
      : file_size_(file_size), last_seen_progress_(0) {}
  ~CheckDownloadProgressDelegate() override {}

  void OnURLFetchDownloadProgress(const URLFetcher* source,
                                  int64 current,
                                  int64 total) override {
    // Run default checks.
    WaitingURLFetcherDelegate::OnURLFetchDownloadProgress(source, current,
                                                          total);

    EXPECT_LE(last_seen_progress_, current);
    EXPECT_EQ(file_size_, total);
    last_seen_progress_ = current;
  }

 private:
  int64 file_size_;
  int64 last_seen_progress_;

  DISALLOW_COPY_AND_ASSIGN(CheckDownloadProgressDelegate);
};

TEST_F(URLFetcherTest, DownloadProgress) {
  // Get a file large enough to require more than one read into
  // URLFetcher::Core's IOBuffer.
  const char kFileToFetch[] = "animate1.gif";

  std::string file_contents;
  ASSERT_TRUE(base::ReadFileToString(
      test_server_->GetDocumentRoot().AppendASCII(kFileToFetch),
      &file_contents));

  CheckDownloadProgressDelegate delegate(file_contents.size());
  delegate.CreateFetcher(
      test_server_->GetURL(std::string(kTestServerFilePrefix) + kFileToFetch),
      URLFetcher::GET, CreateSameThreadContextGetter());
  delegate.StartFetcherAndWait();

  EXPECT_TRUE(delegate.fetcher()->GetStatus().is_success());
  EXPECT_EQ(200, delegate.fetcher()->GetResponseCode());
  std::string data;
  ASSERT_TRUE(delegate.fetcher()->GetResponseAsString(&data));
  EXPECT_EQ(file_contents, data);
}

class CancelOnUploadProgressDelegate : public WaitingURLFetcherDelegate {
 public:
  CancelOnUploadProgressDelegate() {}
  ~CancelOnUploadProgressDelegate() override {}

  void OnURLFetchUploadProgress(const URLFetcher* source,
                                int64 current,
                                int64 total) override {
    CancelFetch();
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(CancelOnUploadProgressDelegate);
};

// Check that a fetch can be safely cancelled/deleted during an upload progress
// callback.
TEST_F(URLFetcherTest, CancelInUploadProgressCallback) {
  CancelOnUploadProgressDelegate delegate;
  delegate.CreateFetcher(test_server_->GetURL("echo"), URLFetcher::POST,
                         CreateSameThreadContextGetter());
  delegate.fetcher()->SetChunkedUpload("application/x-www-form-urlencoded");
  delegate.fetcher()->Start();
  // Use a chunked upload so that the upload can be paused after uploading data.
  // Since uploads progress uses a timer, may not receive any notification,
  // otherwise.
  std::string upload_data(1 << 16, 'a');
  delegate.fetcher()->AppendChunkToUpload(upload_data, false);
  delegate.WaitForComplete();

  // Make sure there are no pending events that cause problems when run.
  base::RunLoop().RunUntilIdle();

  EXPECT_FALSE(delegate.did_complete());
  EXPECT_FALSE(delegate.fetcher());
}

class CancelOnDownloadProgressDelegate : public WaitingURLFetcherDelegate {
 public:
  CancelOnDownloadProgressDelegate() {}
  ~CancelOnDownloadProgressDelegate() override {}

  void OnURLFetchDownloadProgress(const URLFetcher* source,
                                  int64 current,
                                  int64 total) override {
    CancelFetch();
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(CancelOnDownloadProgressDelegate);
};

// Check that a fetch can be safely cancelled/deleted during a download progress
// callback.
TEST_F(URLFetcherTest, CancelInDownloadProgressCallback) {
  // Get a file large enough to require more than one read into
  // URLFetcher::Core's IOBuffer.
  static const char kFileToFetch[] = "animate1.gif";
  CancelOnDownloadProgressDelegate delegate;
  delegate.CreateFetcher(
      test_server_->GetURL(std::string(kTestServerFilePrefix) + kFileToFetch),
      URLFetcher::GET, CreateSameThreadContextGetter());
  delegate.StartFetcherAndWait();

  // Make sure there are no pending events that cause problems when run.
  base::RunLoop().RunUntilIdle();

  EXPECT_FALSE(delegate.did_complete());
  EXPECT_FALSE(delegate.fetcher());
}

TEST_F(URLFetcherTest, Headers) {
  WaitingURLFetcherDelegate delegate;
  delegate.CreateFetcher(
      test_server_->GetURL("set-header?cache-control: private"),
      URLFetcher::GET, CreateSameThreadContextGetter());
  delegate.StartFetcherAndWait();

  EXPECT_TRUE(delegate.fetcher()->GetStatus().is_success());
  EXPECT_EQ(200, delegate.fetcher()->GetResponseCode());
  std::string header;
  ASSERT_TRUE(delegate.fetcher()->GetResponseHeaders()->GetNormalizedHeader(
      "cache-control", &header));
  EXPECT_EQ("private", header);
}

TEST_F(URLFetcherTest, SocketAddress) {
  WaitingURLFetcherDelegate delegate;
  delegate.CreateFetcher(test_server_->GetURL(kDefaultResponsePath),
                         URLFetcher::GET, CreateSameThreadContextGetter());
  delegate.StartFetcherAndWait();

  EXPECT_TRUE(delegate.fetcher()->GetStatus().is_success());
  EXPECT_EQ(200, delegate.fetcher()->GetResponseCode());
  EXPECT_EQ(test_server_->host_port_pair().port(),
            delegate.fetcher()->GetSocketAddress().port());
  EXPECT_EQ(test_server_->host_port_pair().host(),
            delegate.fetcher()->GetSocketAddress().host());
}

TEST_F(URLFetcherTest, StopOnRedirect) {
  const char kRedirectTarget[] = "http://redirect.target.com";

  WaitingURLFetcherDelegate delegate;
  delegate.CreateFetcher(
      test_server_->GetURL(std::string("server-redirect?") + kRedirectTarget),
      URLFetcher::GET, CreateSameThreadContextGetter());
  delegate.fetcher()->SetStopOnRedirect(true);
  delegate.StartFetcherAndWait();

  EXPECT_EQ(GURL(kRedirectTarget), delegate.fetcher()->GetURL());
  EXPECT_EQ(URLRequestStatus::CANCELED,
            delegate.fetcher()->GetStatus().status());
  EXPECT_EQ(ERR_ABORTED, delegate.fetcher()->GetStatus().error());
  EXPECT_EQ(301, delegate.fetcher()->GetResponseCode());
}

TEST_F(URLFetcherTest, ThrottleOnRepeatedFetches) {
  base::Time start_time = Time::Now();
  GURL url(test_server_->GetURL(kDefaultResponsePath));

  scoped_refptr<FetcherTestURLRequestContextGetter> context_getter(
      CreateSameThreadContextGetter());

  // Registers an entry for test url. It only allows 3 requests to be sent
  // in 200 milliseconds.
  context_getter->AddThrottlerEntry(
      url, std::string() /* url_id */, 200 /* sliding_window_period_ms */,
      3 /* max_send_threshold */, 1 /* initial_backoff_ms */,
      2.0 /* multiply_factor */, 0.0 /* jitter_factor */,
      256 /* maximum_backoff_ms */,
      false /* reserve_sending_time_for_next_request*/);

  for (int i = 0; i < 20; ++i) {
    WaitingURLFetcherDelegate delegate;
    delegate.CreateFetcher(url, URLFetcher::GET, context_getter);
    delegate.StartFetcherAndWait();

    EXPECT_TRUE(delegate.fetcher()->GetStatus().is_success());
    EXPECT_EQ(200, delegate.fetcher()->GetResponseCode());
  }

  // 20 requests were sent. Due to throttling, they should have collectively
  // taken over 1 second.
  EXPECT_GE(Time::Now() - start_time, base::TimeDelta::FromSeconds(1));
}

TEST_F(URLFetcherTest, ThrottleOn5xxRetries) {
  base::Time start_time = Time::Now();
  GURL url(test_server_->GetURL("files/server-unavailable.html"));

  scoped_refptr<FetcherTestURLRequestContextGetter> context_getter(
      CreateSameThreadContextGetter());

  // Registers an entry for test url. The backoff time is calculated by:
  //     new_backoff = 2.0 * old_backoff + 0
  // and maximum backoff time is 256 milliseconds.
  // Maximum retries allowed is set to 11.
  context_getter->AddThrottlerEntry(
      url, std::string() /* url_id */, 200 /* sliding_window_period_ms */,
      3 /* max_send_threshold */, 1 /* initial_backoff_ms */,
      2.0 /* multiply_factor */, 0.0 /* jitter_factor */,
      256 /* maximum_backoff_ms */,
      false /* reserve_sending_time_for_next_request*/);

  WaitingURLFetcherDelegate delegate;
  delegate.CreateFetcher(url, URLFetcher::GET, context_getter);
  delegate.fetcher()->SetAutomaticallyRetryOn5xx(true);
  delegate.fetcher()->SetMaxRetriesOn5xx(11);
  delegate.StartFetcherAndWait();

  EXPECT_TRUE(delegate.fetcher()->GetStatus().is_success());
  EXPECT_EQ(503, delegate.fetcher()->GetResponseCode());
  std::string data;
  ASSERT_TRUE(delegate.fetcher()->GetResponseAsString(&data));
  EXPECT_FALSE(data.empty());

  // The request should have been retried 11 times (12 times including the first
  // attempt).  Due to throttling, they should have collectively taken over 1
  // second.
  EXPECT_GE(Time::Now() - start_time, base::TimeDelta::FromSeconds(1));
}

// Tests overload protection, when responses passed through.
TEST_F(URLFetcherTest, ProtectTestPassedThrough) {
  base::Time start_time = Time::Now();
  GURL url(test_server_->GetURL("files/server-unavailable.html"));

  scoped_refptr<FetcherTestURLRequestContextGetter> context_getter(
      CreateSameThreadContextGetter());

  // Registers an entry for test url. The backoff time is calculated by:
  //     new_backoff = 2.0 * old_backoff + 0
  // and maximum backoff time is 150000 milliseconds.
  // Maximum retries allowed is set to 11.
  // Total time if *not* for not doing automatic backoff would be 150s.
  // In reality it should be "as soon as server responds".
  context_getter->AddThrottlerEntry(
      url, std::string() /* url_id */, 200 /* sliding_window_period_ms */,
      3 /* max_send_threshold */, 10000 /* initial_backoff_ms */,
      2.0 /* multiply_factor */, 0.0 /* jitter_factor */,
      150000 /* maximum_backoff_ms */,
      false /* reserve_sending_time_for_next_request*/);

  WaitingURLFetcherDelegate delegate;
  delegate.CreateFetcher(url, URLFetcher::GET, context_getter);
  delegate.fetcher()->SetAutomaticallyRetryOn5xx(false);
  delegate.fetcher()->SetMaxRetriesOn5xx(11);
  delegate.StartFetcherAndWait();

  EXPECT_TRUE(delegate.fetcher()->GetStatus().is_success());
  EXPECT_EQ(503, delegate.fetcher()->GetResponseCode());
  std::string data;
  ASSERT_TRUE(delegate.fetcher()->GetResponseAsString(&data));
  EXPECT_FALSE(data.empty());
  EXPECT_GT(delegate.fetcher()->GetBackoffDelay().InMicroseconds(), 0);

  // The request should not have been retried at all.  If it had attempted all
  // 11 retries, that should have taken 2.5 minutes.
  EXPECT_TRUE(Time::Now() - start_time < TimeDelta::FromMinutes(1));
}

// Used to check if a callback has been invoked.
void SetBoolToTrue(bool* ptr) {
  *ptr = true;
}

// Make sure that the URLFetcher cancels the URLRequest and releases its context
// getter pointer synchronously when the fetcher and request context live on
// the same thread.
TEST_F(URLFetcherTest, CancelSameThread) {
  WaitingURLFetcherDelegate delegate;
  scoped_refptr<FetcherTestURLRequestContextGetter> context_getter(
      CreateSameThreadContextGetter());
  bool getter_was_destroyed = false;
  context_getter->set_on_destruction_callback(
      base::Bind(&SetBoolToTrue, &getter_was_destroyed));
  delegate.CreateFetcher(hanging_url(), URLFetcher::GET, context_getter);

  // The getter won't be destroyed if the test holds on to a reference to it.
  context_getter = nullptr;

  delegate.fetcher()->Start();
  // Give the fetcher a chance to start the request.
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1, URLFetcherTest::GetNumFetcherCores());

  // On same-thread cancel, the request should be canceled and getter destroyed
  // synchronously, for safe shutdown.
  delegate.CancelFetch();
  EXPECT_EQ(0, URLFetcherTest::GetNumFetcherCores());
  EXPECT_TRUE(getter_was_destroyed);
}

// Make sure that the URLFetcher releases its context getter pointer on
// cancellation, cross-thread case.
TEST_F(URLFetcherTest, CancelDifferentThreads) {
  base::RunLoop run_loop_;

  WaitingURLFetcherDelegate delegate;
  scoped_refptr<FetcherTestURLRequestContextGetter> context_getter(
      CreateCrossThreadContextGetter());
  context_getter->set_on_destruction_callback(base::Bind(
      base::IgnoreResult(&base::MessageLoopProxy::PostTask),
      base::MessageLoopProxy::current(), FROM_HERE, run_loop_.QuitClosure()));
  delegate.CreateFetcher(hanging_url(), URLFetcher::GET, context_getter);

  // The getter won't be destroyed if the test holds on to a reference to it.
  context_getter = nullptr;

  delegate.fetcher()->Start();
  delegate.CancelFetch();
  run_loop_.Run();

  EXPECT_FALSE(delegate.did_complete());
}

TEST_F(URLFetcherTest, CancelWhileDelayedByThrottleDifferentThreads) {
  GURL url = test_server_->GetURL(kDefaultResponsePath);
  base::RunLoop run_loop_;

  WaitingURLFetcherDelegate delegate;
  scoped_refptr<FetcherTestURLRequestContextGetter> context_getter(
      CreateCrossThreadContextGetter());
  context_getter->set_on_destruction_callback(base::Bind(
      base::IgnoreResult(&base::MessageLoopProxy::PostTask),
      base::MessageLoopProxy::current(), FROM_HERE, run_loop_.QuitClosure()));
  delegate.CreateFetcher(url, URLFetcher::GET, context_getter);

  // Register an entry for test url using a sliding window of 400 seconds, and
  // max of 1 request.  Also simulate a request having just started, so the
  // next request will be affected by backoff of ~400 seconds.
  context_getter->AddThrottlerEntry(
      url, std::string() /* url_id */, 400000 /* sliding_window_period_ms */,
      1 /* max_send_threshold */, 200000 /* initial_backoff_ms */,
      2.0 /* multiply_factor */, 0.0 /* jitter_factor */,
      400000 /* maximum_backoff_ms */,
      true /* reserve_sending_time_for_next_request*/);

  // The getter won't be destroyed if the test holds on to a reference to it.
  context_getter = nullptr;

  delegate.fetcher()->Start();
  delegate.CancelFetch();
  run_loop_.Run();

  EXPECT_FALSE(delegate.did_complete());
}

// A URLFetcherDelegate that expects to receive a response body of "request1"
// and then reuses the fetcher for the same URL, setting the "test" request
// header to "request2".
class ReuseFetcherDelegate : public WaitingURLFetcherDelegate {
 public:
  // |second_request_context_getter| is the context getter used for the second
  // request. Can't reuse the old one because fetchers release it on completion.
  ReuseFetcherDelegate(
      scoped_refptr<URLRequestContextGetter> second_request_context_getter)
      : first_request_complete_(false),
        second_request_context_getter_(second_request_context_getter) {}

  ~ReuseFetcherDelegate() override {}

  void OnURLFetchComplete(const URLFetcher* source) override {
    EXPECT_EQ(fetcher(), source);
    if (!first_request_complete_) {
      first_request_complete_ = true;
      EXPECT_TRUE(fetcher()->GetStatus().is_success());
      EXPECT_EQ(200, fetcher()->GetResponseCode());
      std::string data;
      ASSERT_TRUE(fetcher()->GetResponseAsString(&data));
      EXPECT_EQ("request1", data);

      fetcher()->SetRequestContext(second_request_context_getter_.get());
      fetcher()->SetExtraRequestHeaders("test: request2");
      fetcher()->Start();
      return;
    }
    WaitingURLFetcherDelegate::OnURLFetchComplete(source);
  }

 private:
  bool first_request_complete_;
  scoped_refptr<URLRequestContextGetter> second_request_context_getter_;

  DISALLOW_COPY_AND_ASSIGN(ReuseFetcherDelegate);
};

TEST_F(URLFetcherTest, ReuseFetcherForSameURL) {
  // TODO(mmenke):  It's really weird that this is supported, particularly
  // some fields can be modified between requests, but some (Like upload body)
  // cannot be. Can we get rid of support for this?
  scoped_refptr<URLRequestContextGetter> context_getter(
      CreateSameThreadContextGetter());
  ReuseFetcherDelegate delegate(context_getter);
  delegate.CreateFetcher(test_server_->GetURL("echoheader?test"),
                         URLFetcher::GET, context_getter);
  delegate.fetcher()->SetExtraRequestHeaders("test: request1");
  delegate.StartFetcherAndWait();

  EXPECT_TRUE(delegate.fetcher()->GetStatus().is_success());
  EXPECT_EQ(200, delegate.fetcher()->GetResponseCode());
  std::string data;
  ASSERT_TRUE(delegate.fetcher()->GetResponseAsString(&data));
  EXPECT_EQ("request2", data);
}

TEST_F(URLFetcherTest, ShutdownSameThread) {
  scoped_refptr<FetcherTestURLRequestContextGetter> context_getter(
      CreateSameThreadContextGetter());

  // Create a fetcher and wait for it to create a request.
  WaitingURLFetcherDelegate delegate1;
  delegate1.CreateFetcher(hanging_url(), URLFetcher::GET, context_getter);
  delegate1.fetcher()->Start();
  // Need to spin the loop to ensure the URLRequest is created and started.
  base::RunLoop().RunUntilIdle();

  // Create and start another fetcher, but don't wait for it to start. The task
  // to start the request should be in the message loop.
  WaitingURLFetcherDelegate delegate2;
  delegate2.CreateFetcher(hanging_url(), URLFetcher::GET, context_getter);
  delegate2.fetcher()->Start();

  // Check that shutting down the getter cancels the request synchronously,
  // allowing the context to be destroyed.
  context_getter->Shutdown();

  // Wait for the first fetcher, make sure it failed.
  delegate1.WaitForComplete();
  EXPECT_FALSE(delegate1.fetcher()->GetStatus().is_success());
  EXPECT_EQ(ERR_CONTEXT_SHUT_DOWN, delegate1.fetcher()->GetStatus().error());

  // Wait for the second fetcher, make sure it failed.
  delegate2.WaitForComplete();
  EXPECT_FALSE(delegate2.fetcher()->GetStatus().is_success());
  EXPECT_EQ(ERR_CONTEXT_SHUT_DOWN, delegate2.fetcher()->GetStatus().error());

  // New fetchers should automatically fail without making new requests. This
  // should follow the same path as the second fetcher, but best to be safe.
  WaitingURLFetcherDelegate delegate3;
  delegate3.CreateFetcher(hanging_url(), URLFetcher::GET, context_getter);
  delegate3.fetcher()->Start();
  delegate3.WaitForComplete();
  EXPECT_FALSE(delegate3.fetcher()->GetStatus().is_success());
  EXPECT_EQ(ERR_CONTEXT_SHUT_DOWN, delegate3.fetcher()->GetStatus().error());
}

TEST_F(URLFetcherTest, ShutdownCrossThread) {
  scoped_refptr<FetcherTestURLRequestContextGetter> context_getter(
      CreateCrossThreadContextGetter());

  WaitingURLFetcherDelegate delegate1;
  delegate1.CreateFetcher(hanging_url(), URLFetcher::GET, context_getter);
  delegate1.fetcher()->Start();
  // Check that shutting the context getter lets the context be destroyed safely
  // and cancels the request.
  context_getter->Shutdown();
  delegate1.WaitForComplete();
  EXPECT_FALSE(delegate1.fetcher()->GetStatus().is_success());
  EXPECT_EQ(ERR_CONTEXT_SHUT_DOWN, delegate1.fetcher()->GetStatus().error());

  // New requests should automatically fail without making new requests.
  WaitingURLFetcherDelegate delegate2;
  delegate2.CreateFetcher(hanging_url(), URLFetcher::GET, context_getter);
  delegate2.StartFetcherAndWait();
  EXPECT_FALSE(delegate2.fetcher()->GetStatus().is_success());
  EXPECT_EQ(ERR_CONTEXT_SHUT_DOWN, delegate2.fetcher()->GetStatus().error());
}

// Get a small file.
TEST_F(URLFetcherTest, FileTestSmallGet) {
  const char kFileToFetch[] = "simple.html";

  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  base::FilePath out_path = temp_dir.path().AppendASCII(kFileToFetch);
  SaveFileTest(kFileToFetch, false, out_path, false);
}

// Get a file large enough to require more than one read into URLFetcher::Core's
// IOBuffer.
TEST_F(URLFetcherTest, FileTestLargeGet) {
  const char kFileToFetch[] = "animate1.gif";

  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  base::FilePath out_path = temp_dir.path().AppendASCII(kFileToFetch);
  SaveFileTest(kFileToFetch, false, out_path, false);
}

// If the caller takes the ownership of the output file, the file should persist
// even after URLFetcher is gone.
TEST_F(URLFetcherTest, FileTestTakeOwnership) {
  const char kFileToFetch[] = "simple.html";

  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  base::FilePath out_path = temp_dir.path().AppendASCII(kFileToFetch);
  SaveFileTest(kFileToFetch, false, out_path, true);
}

// Test that an existing file can be overwritten be a fetcher.
TEST_F(URLFetcherTest, FileTestOverwriteExisting) {
  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());

  // Create a file before trying to fetch.
  const char kFileToFetch[] = "simple.html";
  std::string data(10000, '?');  // Meant to be larger than simple.html.
  base::FilePath out_path = temp_dir.path().AppendASCII(kFileToFetch);
  ASSERT_EQ(static_cast<int>(data.size()),
            base::WriteFile(out_path, data.data(), data.size()));
  ASSERT_TRUE(base::PathExists(out_path));

  SaveFileTest(kFileToFetch, false, out_path, true);
}

// Test trying to overwrite a directory with a file when using a fetcher fails.
TEST_F(URLFetcherTest, FileTestTryToOverwriteDirectory) {
  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());

  // Create a directory before trying to fetch.
  static const char kFileToFetch[] = "simple.html";
  base::FilePath out_path = temp_dir.path().AppendASCII(kFileToFetch);
  ASSERT_TRUE(base::CreateDirectory(out_path));
  ASSERT_TRUE(base::PathExists(out_path));

  WaitingURLFetcherDelegate delegate;
  delegate.CreateFetcher(
      test_server_->GetURL(std::string(kTestServerFilePrefix) + kFileToFetch),
      URLFetcher::GET, CreateSameThreadContextGetter());
  delegate.fetcher()->SaveResponseToFileAtPath(
      out_path,
      scoped_refptr<base::MessageLoopProxy>(base::MessageLoopProxy::current()));
  delegate.StartFetcherAndWait();

  EXPECT_FALSE(delegate.fetcher()->GetStatus().is_success());
  EXPECT_EQ(ERR_ACCESS_DENIED, delegate.fetcher()->GetStatus().error());
}

// Get a small file and save it to a temp file.
TEST_F(URLFetcherTest, TempFileTestSmallGet) {
  SaveFileTest("simple.html", true, base::FilePath(), false);
}

// Get a file large enough to require more than one read into URLFetcher::Core's
// IOBuffer and save it to a temp file.
TEST_F(URLFetcherTest, TempFileTestLargeGet) {
  SaveFileTest("animate1.gif", true, base::FilePath(), false);
}

// If the caller takes the ownership of the temp file, check that the file
// persists even after URLFetcher is gone.
TEST_F(URLFetcherTest, TempFileTestTakeOwnership) {
  SaveFileTest("simple.html", true, base::FilePath(), true);
}

TEST_F(URLFetcherBadHTTPSTest, BadHTTPS) {
  WaitingURLFetcherDelegate delegate;
  delegate.CreateFetcher(test_server_->GetURL(kDefaultResponsePath),
                         URLFetcher::GET, CreateSameThreadContextGetter());
  delegate.StartFetcherAndWait();

  EXPECT_EQ(URLRequestStatus::CANCELED,
            delegate.fetcher()->GetStatus().status());
  EXPECT_EQ(ERR_ABORTED, delegate.fetcher()->GetStatus().error());
  EXPECT_EQ(-1, delegate.fetcher()->GetResponseCode());
  EXPECT_TRUE(delegate.fetcher()->GetCookies().empty());
  std::string data;
  EXPECT_TRUE(delegate.fetcher()->GetResponseAsString(&data));
  EXPECT_TRUE(data.empty());
}

}  // namespace

}  // namespace net
