// 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 "build/build_config.h"

#if defined(OS_WIN)
#include <windows.h>
#include <shlobj.h>
#endif

#include <stdint.h>

#include <algorithm>

#include "base/basictypes.h"
#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/format_macros.h"
#include "base/json/json_reader.h"
#include "base/location.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/power_monitor/power_monitor.h"
#include "base/power_monitor/power_monitor_source.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/histogram_tester.h"
#include "base/thread_task_runner_handle.h"
#include "base/values.h"
#include "net/base/chunked_upload_data_stream.h"
#include "net/base/elements_upload_data_stream.h"
#include "net/base/external_estimate_provider.h"
#include "net/base/load_flags.h"
#include "net/base/load_timing_info.h"
#include "net/base/load_timing_info_test_util.h"
#include "net/base/net_errors.h"
#include "net/base/net_module.h"
#include "net/base/net_util.h"
#include "net/base/network_quality_estimator.h"
#include "net/base/request_priority.h"
#include "net/base/test_data_directory.h"
#include "net/base/upload_bytes_element_reader.h"
#include "net/base/upload_data_stream.h"
#include "net/base/upload_file_element_reader.h"
#include "net/cert/ev_root_ca_metadata.h"
#include "net/cert/mock_cert_verifier.h"
#include "net/cert/test_root_certs.h"
#include "net/cert_net/nss_ocsp.h"
#include "net/cookies/cookie_monster.h"
#include "net/cookies/cookie_store_test_helpers.h"
#include "net/disk_cache/disk_cache.h"
#include "net/dns/mock_host_resolver.h"
#include "net/http/http_byte_range.h"
#include "net/http/http_cache.h"
#include "net/http/http_network_layer.h"
#include "net/http/http_network_session.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_util.h"
#include "net/log/net_log.h"
#include "net/log/test_net_log.h"
#include "net/log/test_net_log_entry.h"
#include "net/log/test_net_log_util.h"
#include "net/proxy/proxy_service.h"
#include "net/socket/ssl_client_socket.h"
#include "net/ssl/ssl_cipher_suite_names.h"
#include "net/ssl/ssl_connection_status_flags.h"
#include "net/test/cert_test_util.h"
#include "net/test/spawned_test_server/spawned_test_server.h"
#include "net/test/url_request/url_request_failed_job.h"
#include "net/url_request/data_protocol_handler.h"
#include "net/url_request/static_http_user_agent_settings.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_filter.h"
#include "net/url_request/url_request_http_job.h"
#include "net/url_request/url_request_intercepting_job_factory.h"
#include "net/url_request/url_request_interceptor.h"
#include "net/url_request/url_request_job_factory_impl.h"
#include "net/url_request/url_request_redirect_job.h"
#include "net/url_request/url_request_test_job.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"

#if !defined(DISABLE_FILE_SUPPORT)
#include "net/base/filename_util.h"
#include "net/url_request/file_protocol_handler.h"
#include "net/url_request/url_request_file_dir_job.h"
#endif

#if !defined(DISABLE_FTP_SUPPORT) && !defined(OS_ANDROID)
#include "net/ftp/ftp_network_layer.h"
#include "net/url_request/ftp_protocol_handler.h"
#endif

#if defined(OS_WIN)
#include "base/win/scoped_com_initializer.h"
#include "base/win/scoped_comptr.h"
#include "base/win/windows_version.h"
#endif

using base::ASCIIToUTF16;
using base::Time;
using std::string;

namespace net {

namespace {

const base::string16 kChrome(ASCIIToUTF16("chrome"));
const base::string16 kSecret(ASCIIToUTF16("secret"));
const base::string16 kUser(ASCIIToUTF16("user"));

const base::FilePath::CharType kTestFilePath[] =
    FILE_PATH_LITERAL("net/data/url_request_unittest");

#if !defined(DISABLE_FTP_SUPPORT) && !defined(OS_ANDROID)
// Test file used in most FTP tests.
const char kFtpTestFile[] = "BullRunSpeech.txt";
#endif

// Tests load timing information in the case a fresh connection was used, with
// no proxy.
void TestLoadTimingNotReused(const LoadTimingInfo& load_timing_info,
                             int connect_timing_flags) {
  EXPECT_FALSE(load_timing_info.socket_reused);
  EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);

  EXPECT_FALSE(load_timing_info.request_start_time.is_null());
  EXPECT_FALSE(load_timing_info.request_start.is_null());

  EXPECT_LE(load_timing_info.request_start,
            load_timing_info.connect_timing.connect_start);
  ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
                              connect_timing_flags);
  EXPECT_LE(load_timing_info.connect_timing.connect_end,
            load_timing_info.send_start);
  EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
  EXPECT_LE(load_timing_info.send_end, load_timing_info.receive_headers_end);

  EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
  EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
}

// Same as above, but with proxy times.
void TestLoadTimingNotReusedWithProxy(
    const LoadTimingInfo& load_timing_info,
    int connect_timing_flags) {
  EXPECT_FALSE(load_timing_info.socket_reused);
  EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);

  EXPECT_FALSE(load_timing_info.request_start_time.is_null());
  EXPECT_FALSE(load_timing_info.request_start.is_null());

  EXPECT_LE(load_timing_info.request_start,
            load_timing_info.proxy_resolve_start);
  EXPECT_LE(load_timing_info.proxy_resolve_start,
            load_timing_info.proxy_resolve_end);
  EXPECT_LE(load_timing_info.proxy_resolve_end,
            load_timing_info.connect_timing.connect_start);
  ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
                              connect_timing_flags);
  EXPECT_LE(load_timing_info.connect_timing.connect_end,
            load_timing_info.send_start);
  EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
  EXPECT_LE(load_timing_info.send_end, load_timing_info.receive_headers_end);
}

// Same as above, but with a reused socket and proxy times.
void TestLoadTimingReusedWithProxy(
    const LoadTimingInfo& load_timing_info) {
  EXPECT_TRUE(load_timing_info.socket_reused);
  EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);

  EXPECT_FALSE(load_timing_info.request_start_time.is_null());
  EXPECT_FALSE(load_timing_info.request_start.is_null());

  ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);

  EXPECT_LE(load_timing_info.request_start,
            load_timing_info.proxy_resolve_start);
  EXPECT_LE(load_timing_info.proxy_resolve_start,
            load_timing_info.proxy_resolve_end);
  EXPECT_LE(load_timing_info.proxy_resolve_end,
            load_timing_info.send_start);
  EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
  EXPECT_LE(load_timing_info.send_end, load_timing_info.receive_headers_end);
}

#if !defined(DISABLE_FILE_SUPPORT)
// Tests load timing information in the case of a cache hit, when no cache
// validation request was sent over the wire.
base::StringPiece TestNetResourceProvider(int key) {
  return "header";
}

void FillBuffer(char* buffer, size_t len) {
  static bool called = false;
  if (!called) {
    called = true;
    int seed = static_cast<int>(Time::Now().ToInternalValue());
    srand(seed);
  }

  for (size_t i = 0; i < len; i++) {
    buffer[i] = static_cast<char>(rand());
    if (!buffer[i])
      buffer[i] = 'g';
  }
}
#endif

#if !defined(OS_IOS)
void TestLoadTimingCacheHitNoNetwork(
    const LoadTimingInfo& load_timing_info) {
  EXPECT_FALSE(load_timing_info.socket_reused);
  EXPECT_EQ(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);

  EXPECT_FALSE(load_timing_info.request_start_time.is_null());
  EXPECT_FALSE(load_timing_info.request_start.is_null());

  ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
  EXPECT_LE(load_timing_info.request_start, load_timing_info.send_start);
  EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
  EXPECT_LE(load_timing_info.send_end, load_timing_info.receive_headers_end);

  EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
  EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
}

#if !defined(DISABLE_FTP_SUPPORT) && !defined(OS_ANDROID)
// Tests load timing in the case that there is no HTTP response.  This can be
// used to test in the case of errors or non-HTTP requests.
void TestLoadTimingNoHttpResponse(
    const LoadTimingInfo& load_timing_info) {
  EXPECT_FALSE(load_timing_info.socket_reused);
  EXPECT_EQ(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);

  // Only the request times should be non-null.
  EXPECT_FALSE(load_timing_info.request_start_time.is_null());
  EXPECT_FALSE(load_timing_info.request_start.is_null());

  ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);

  EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
  EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
  EXPECT_TRUE(load_timing_info.send_start.is_null());
  EXPECT_TRUE(load_timing_info.send_end.is_null());
  EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
}
#endif

// Test power monitor source that can simulate entering suspend mode. Can't use
// the one in base/ because it insists on bringing its own MessageLoop.
class TestPowerMonitorSource : public base::PowerMonitorSource {
 public:
  TestPowerMonitorSource() {}
  ~TestPowerMonitorSource() override {}

  void Suspend() { ProcessPowerEvent(SUSPEND_EVENT); }

  void Resume() { ProcessPowerEvent(RESUME_EVENT); }

  bool IsOnBatteryPowerImpl() override { return false; }

 private:
  DISALLOW_COPY_AND_ASSIGN(TestPowerMonitorSource);
};

// Do a case-insensitive search through |haystack| for |needle|.
bool ContainsString(const std::string& haystack, const char* needle) {
  std::string::const_iterator it = std::search(
      haystack.begin(), haystack.end(), needle, needle + strlen(needle),
      base::CaseInsensitiveCompareASCII<char>());
  return it != haystack.end();
}

scoped_ptr<UploadDataStream> CreateSimpleUploadData(const char* data) {
  scoped_ptr<UploadElementReader> reader(
      new UploadBytesElementReader(data, strlen(data)));
  return ElementsUploadDataStream::CreateWithReader(reader.Pass(), 0);
}

// Verify that the SSLInfo of a successful SSL connection has valid values.
void CheckSSLInfo(const SSLInfo& ssl_info) {
  // -1 means unknown.  0 means no encryption.
  EXPECT_GT(ssl_info.security_bits, 0);

  // The cipher suite TLS_NULL_WITH_NULL_NULL (0) must not be negotiated.
  uint16 cipher_suite = SSLConnectionStatusToCipherSuite(
      ssl_info.connection_status);
  EXPECT_NE(0U, cipher_suite);
}

void CheckFullRequestHeaders(const HttpRequestHeaders& headers,
                             const GURL& host_url) {
  std::string sent_value;

  EXPECT_TRUE(headers.GetHeader("Host", &sent_value));
  EXPECT_EQ(GetHostAndOptionalPort(host_url), sent_value);

  EXPECT_TRUE(headers.GetHeader("Connection", &sent_value));
  EXPECT_EQ("keep-alive", sent_value);
}

bool FingerprintsEqual(const HashValueVector& a, const HashValueVector& b) {
  size_t size = a.size();

  if (size != b.size())
    return false;

  for (size_t i = 0; i < size; ++i) {
    if (!a[i].Equals(b[i]))
      return false;
  }

  return true;
}
#endif  // !defined(OS_IOS)

// A network delegate that allows the user to choose a subset of request stages
// to block in. When blocking, the delegate can do one of the following:
//  * synchronously return a pre-specified error code, or
//  * asynchronously return that value via an automatically called callback,
//    or
//  * block and wait for the user to do a callback.
// Additionally, the user may also specify a redirect URL -- then each request
// with the current URL different from the redirect target will be redirected
// to that target, in the on-before-URL-request stage, independent of whether
// the delegate blocks in ON_BEFORE_URL_REQUEST or not.
class BlockingNetworkDelegate : public TestNetworkDelegate {
 public:
  // Stages in which the delegate can block.
  enum Stage {
    NOT_BLOCKED = 0,
    ON_BEFORE_URL_REQUEST = 1 << 0,
    ON_BEFORE_SEND_HEADERS = 1 << 1,
    ON_HEADERS_RECEIVED = 1 << 2,
    ON_AUTH_REQUIRED = 1 << 3
  };

  // Behavior during blocked stages.  During other stages, just
  // returns OK or NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION.
  enum BlockMode {
    SYNCHRONOUS,    // No callback, returns specified return values.
    AUTO_CALLBACK,  // |this| posts a task to run the callback using the
                    // specified return codes.
    USER_CALLBACK,  // User takes care of doing a callback.  |retval_| and
                    // |auth_retval_| are ignored. In every blocking stage the
                    // message loop is quit.
  };

  // Creates a delegate which does not block at all.
  explicit BlockingNetworkDelegate(BlockMode block_mode);

  // For users to trigger a callback returning |response|.
  // Side-effects: resets |stage_blocked_for_callback_| and stored callbacks.
  // Only call if |block_mode_| == USER_CALLBACK.
  void DoCallback(int response);
  void DoAuthCallback(NetworkDelegate::AuthRequiredResponse response);

  // Setters.
  void set_retval(int retval) {
    ASSERT_NE(USER_CALLBACK, block_mode_);
    ASSERT_NE(ERR_IO_PENDING, retval);
    ASSERT_NE(OK, retval);
    retval_ = retval;
  }

  // If |auth_retval| == AUTH_REQUIRED_RESPONSE_SET_AUTH, then
  // |auth_credentials_| will be passed with the response.
  void set_auth_retval(AuthRequiredResponse auth_retval) {
    ASSERT_NE(USER_CALLBACK, block_mode_);
    ASSERT_NE(AUTH_REQUIRED_RESPONSE_IO_PENDING, auth_retval);
    auth_retval_ = auth_retval;
  }
  void set_auth_credentials(const AuthCredentials& auth_credentials) {
    auth_credentials_ = auth_credentials;
  }

  void set_redirect_url(const GURL& url) {
    redirect_url_ = url;
  }

  void set_block_on(int block_on) {
    block_on_ = block_on;
  }

  // Allows the user to check in which state did we block.
  Stage stage_blocked_for_callback() const {
    EXPECT_EQ(USER_CALLBACK, block_mode_);
    return stage_blocked_for_callback_;
  }

 private:
  void RunCallback(int response, const CompletionCallback& callback);
  void RunAuthCallback(AuthRequiredResponse response,
                       const AuthCallback& callback);

  // TestNetworkDelegate implementation.
  int OnBeforeURLRequest(URLRequest* request,
                         const CompletionCallback& callback,
                         GURL* new_url) override;

  int OnBeforeSendHeaders(URLRequest* request,
                          const CompletionCallback& callback,
                          HttpRequestHeaders* headers) override;

  int OnHeadersReceived(
      URLRequest* request,
      const CompletionCallback& callback,
      const HttpResponseHeaders* original_response_headers,
      scoped_refptr<HttpResponseHeaders>* override_response_headers,
      GURL* allowed_unsafe_redirect_url) override;

  NetworkDelegate::AuthRequiredResponse OnAuthRequired(
      URLRequest* request,
      const AuthChallengeInfo& auth_info,
      const AuthCallback& callback,
      AuthCredentials* credentials) override;

  // Resets the callbacks and |stage_blocked_for_callback_|.
  void Reset();

  // Checks whether we should block in |stage|. If yes, returns an error code
  // and optionally sets up callback based on |block_mode_|. If no, returns OK.
  int MaybeBlockStage(Stage stage, const CompletionCallback& callback);

  // Configuration parameters, can be adjusted by public methods:
  const BlockMode block_mode_;

  // Values returned on blocking stages when mode is SYNCHRONOUS or
  // AUTO_CALLBACK. For USER_CALLBACK these are set automatically to IO_PENDING.
  int retval_;  // To be returned in non-auth stages.
  AuthRequiredResponse auth_retval_;

  GURL redirect_url_;  // Used if non-empty during OnBeforeURLRequest.
  int block_on_;  // Bit mask: in which stages to block.

  // |auth_credentials_| will be copied to |*target_auth_credential_| on
  // callback.
  AuthCredentials auth_credentials_;
  AuthCredentials* target_auth_credentials_;

  // Internal variables, not set by not the user:
  // Last blocked stage waiting for user callback (unused if |block_mode_| !=
  // USER_CALLBACK).
  Stage stage_blocked_for_callback_;

  // Callback objects stored during blocking stages.
  CompletionCallback callback_;
  AuthCallback auth_callback_;

  base::WeakPtrFactory<BlockingNetworkDelegate> weak_factory_;

  DISALLOW_COPY_AND_ASSIGN(BlockingNetworkDelegate);
};

BlockingNetworkDelegate::BlockingNetworkDelegate(BlockMode block_mode)
    : block_mode_(block_mode),
      retval_(OK),
      auth_retval_(AUTH_REQUIRED_RESPONSE_NO_ACTION),
      block_on_(0),
      target_auth_credentials_(NULL),
      stage_blocked_for_callback_(NOT_BLOCKED),
      weak_factory_(this) {
}

void BlockingNetworkDelegate::DoCallback(int response) {
  ASSERT_EQ(USER_CALLBACK, block_mode_);
  ASSERT_NE(NOT_BLOCKED, stage_blocked_for_callback_);
  ASSERT_NE(ON_AUTH_REQUIRED, stage_blocked_for_callback_);
  CompletionCallback callback = callback_;
  Reset();
  RunCallback(response, callback);
}

void BlockingNetworkDelegate::DoAuthCallback(
    NetworkDelegate::AuthRequiredResponse response) {
  ASSERT_EQ(USER_CALLBACK, block_mode_);
  ASSERT_EQ(ON_AUTH_REQUIRED, stage_blocked_for_callback_);
  AuthCallback auth_callback = auth_callback_;
  Reset();
  RunAuthCallback(response, auth_callback);
}

void BlockingNetworkDelegate::RunCallback(int response,
                                          const CompletionCallback& callback) {
  callback.Run(response);
}

void BlockingNetworkDelegate::RunAuthCallback(AuthRequiredResponse response,
                                              const AuthCallback& callback) {
  if (auth_retval_ == AUTH_REQUIRED_RESPONSE_SET_AUTH) {
    ASSERT_TRUE(target_auth_credentials_ != NULL);
    *target_auth_credentials_ = auth_credentials_;
  }
  callback.Run(response);
}

int BlockingNetworkDelegate::OnBeforeURLRequest(
    URLRequest* request,
    const CompletionCallback& callback,
    GURL* new_url) {
  if (redirect_url_ == request->url())
    return OK;  // We've already seen this request and redirected elsewhere.

  TestNetworkDelegate::OnBeforeURLRequest(request, callback, new_url);

  if (!redirect_url_.is_empty())
    *new_url = redirect_url_;

  return MaybeBlockStage(ON_BEFORE_URL_REQUEST, callback);
}

int BlockingNetworkDelegate::OnBeforeSendHeaders(
    URLRequest* request,
    const CompletionCallback& callback,
    HttpRequestHeaders* headers) {
  TestNetworkDelegate::OnBeforeSendHeaders(request, callback, headers);

  return MaybeBlockStage(ON_BEFORE_SEND_HEADERS, callback);
}

int BlockingNetworkDelegate::OnHeadersReceived(
    URLRequest* request,
    const CompletionCallback& callback,
    const HttpResponseHeaders* original_response_headers,
    scoped_refptr<HttpResponseHeaders>* override_response_headers,
    GURL* allowed_unsafe_redirect_url) {
  TestNetworkDelegate::OnHeadersReceived(request,
                                         callback,
                                         original_response_headers,
                                         override_response_headers,
                                         allowed_unsafe_redirect_url);

  return MaybeBlockStage(ON_HEADERS_RECEIVED, callback);
}

NetworkDelegate::AuthRequiredResponse BlockingNetworkDelegate::OnAuthRequired(
    URLRequest* request,
    const AuthChallengeInfo& auth_info,
    const AuthCallback& callback,
    AuthCredentials* credentials) {
  TestNetworkDelegate::OnAuthRequired(request, auth_info, callback,
                                      credentials);
  // Check that the user has provided callback for the previous blocked stage.
  EXPECT_EQ(NOT_BLOCKED, stage_blocked_for_callback_);

  if ((block_on_ & ON_AUTH_REQUIRED) == 0) {
    return AUTH_REQUIRED_RESPONSE_NO_ACTION;
  }

  target_auth_credentials_ = credentials;

  switch (block_mode_) {
    case SYNCHRONOUS:
      if (auth_retval_ == AUTH_REQUIRED_RESPONSE_SET_AUTH)
        *target_auth_credentials_ = auth_credentials_;
      return auth_retval_;

    case AUTO_CALLBACK:
      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE,
          base::Bind(&BlockingNetworkDelegate::RunAuthCallback,
                     weak_factory_.GetWeakPtr(), auth_retval_, callback));
      return AUTH_REQUIRED_RESPONSE_IO_PENDING;

    case USER_CALLBACK:
      auth_callback_ = callback;
      stage_blocked_for_callback_ = ON_AUTH_REQUIRED;
      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::MessageLoop::QuitClosure());
      return AUTH_REQUIRED_RESPONSE_IO_PENDING;
  }
  NOTREACHED();
  return AUTH_REQUIRED_RESPONSE_NO_ACTION;  // Dummy value.
}

void BlockingNetworkDelegate::Reset() {
  EXPECT_NE(NOT_BLOCKED, stage_blocked_for_callback_);
  stage_blocked_for_callback_ = NOT_BLOCKED;
  callback_.Reset();
  auth_callback_.Reset();
}

int BlockingNetworkDelegate::MaybeBlockStage(
    BlockingNetworkDelegate::Stage stage,
    const CompletionCallback& callback) {
  // Check that the user has provided callback for the previous blocked stage.
  EXPECT_EQ(NOT_BLOCKED, stage_blocked_for_callback_);

  if ((block_on_ & stage) == 0) {
    return OK;
  }

  switch (block_mode_) {
    case SYNCHRONOUS:
      EXPECT_NE(OK, retval_);
      return retval_;

    case AUTO_CALLBACK:
      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::Bind(&BlockingNetworkDelegate::RunCallback,
                                weak_factory_.GetWeakPtr(), retval_, callback));
      return ERR_IO_PENDING;

    case USER_CALLBACK:
      callback_ = callback;
      stage_blocked_for_callback_ = stage;
      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::MessageLoop::QuitClosure());
      return ERR_IO_PENDING;
  }
  NOTREACHED();
  return 0;
}

class TestURLRequestContextWithProxy : public TestURLRequestContext {
 public:
  // Does not own |delegate|.
  TestURLRequestContextWithProxy(const std::string& proxy,
                                 NetworkDelegate* delegate)
      : TestURLRequestContext(true) {
    context_storage_.set_proxy_service(ProxyService::CreateFixed(proxy));
    set_network_delegate(delegate);
    Init();
  }
  ~TestURLRequestContextWithProxy() override {}
};

// A mock ReportSender that just remembers the latest report
// URI and report to be sent.
class MockCertificateReportSender
    : public TransportSecurityState::ReportSender {
 public:
  MockCertificateReportSender() {}
  ~MockCertificateReportSender() override {}

  void Send(const GURL& report_uri, const std::string& report) override {
    latest_report_uri_ = report_uri;
    latest_report_ = report;
  }

  const GURL& latest_report_uri() { return latest_report_uri_; }
  const std::string& latest_report() { return latest_report_; }

 private:
  GURL latest_report_uri_;
  std::string latest_report_;
};

}  // namespace

// Inherit PlatformTest since we require the autorelease pool on Mac OS X.
class URLRequestTest : public PlatformTest {
 public:
  URLRequestTest() : default_context_(true) {
    default_context_.set_network_delegate(&default_network_delegate_);
    default_context_.set_net_log(&net_log_);
    job_factory_impl_ = new URLRequestJobFactoryImpl();
    job_factory_.reset(job_factory_impl_);
  }

  ~URLRequestTest() override {
    // URLRequestJobs may post clean-up tasks on destruction.
    base::RunLoop().RunUntilIdle();
  }

  void SetUp() override {
    SetUpFactory();
    default_context_.set_job_factory(job_factory_.get());
    default_context_.Init();
    PlatformTest::SetUp();
  }

  virtual void SetUpFactory() {
    job_factory_impl_->SetProtocolHandler(
        "data", make_scoped_ptr(new DataProtocolHandler));
#if !defined(DISABLE_FILE_SUPPORT)
    job_factory_impl_->SetProtocolHandler(
        "file", make_scoped_ptr(new FileProtocolHandler(
                    base::ThreadTaskRunnerHandle::Get())));
#endif
  }

  TestNetworkDelegate* default_network_delegate() {
    return &default_network_delegate_;
  }

  const TestURLRequestContext& default_context() const {
    return default_context_;
  }


  // Adds the TestJobInterceptor to the default context.
  TestJobInterceptor* AddTestInterceptor() {
    TestJobInterceptor* protocol_handler_ = new TestJobInterceptor();
    job_factory_impl_->SetProtocolHandler("http", nullptr);
    job_factory_impl_->SetProtocolHandler("http",
                                          make_scoped_ptr(protocol_handler_));
    return protocol_handler_;
  }

 protected:
  TestNetLog net_log_;
  TestNetworkDelegate default_network_delegate_;  // Must outlive URLRequest.
  URLRequestJobFactoryImpl* job_factory_impl_;
  scoped_ptr<URLRequestJobFactory> job_factory_;
  TestURLRequestContext default_context_;
};

TEST_F(URLRequestTest, AboutBlankTest) {
  TestDelegate d;
  {
    scoped_ptr<URLRequest> r(default_context_.CreateRequest(
        GURL("about:blank"), DEFAULT_PRIORITY, &d));

    r->Start();
    EXPECT_TRUE(r->is_pending());

    base::RunLoop().Run();

    EXPECT_TRUE(!r->is_pending());
    EXPECT_FALSE(d.received_data_before_response());
    EXPECT_EQ(d.bytes_received(), 0);
    EXPECT_EQ("", r->GetSocketAddress().host());
    EXPECT_EQ(0, r->GetSocketAddress().port());

    HttpRequestHeaders headers;
    EXPECT_FALSE(r->GetFullRequestHeaders(&headers));
  }
}

TEST_F(URLRequestTest, DataURLImageTest) {
  TestDelegate d;
  {
    // Use our nice little Chrome logo.
    scoped_ptr<URLRequest> r(default_context_.CreateRequest(
        GURL(
            "data:image/png;base64,"
            "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAADVklEQVQ4jX2TfUwUB"
            "BjG3w1y+HGcd9dxhXR8T4awOccJGgOSWclHImznLkTlSw0DDQXkrmgYgbUYnlQTqQ"
            "xIEVxitD5UMCATRA1CEEg+Qjw3bWDxIauJv/5oumqs39/P827vnucRmYN0gyF01GI"
            "5MpCVdW0gO7tvNC+vqSEtbZefk5NuLv1jdJ46p/zw0HeH4+PHr3h7c1mjoV2t5rKz"
            "Mx1+fg9bAgK6zHq9cU5z+LpA3xOtx34+vTeT21onRuzssC3zxbbSwC13d/pFuC7Ck"
            "IMDxQpF7r/MWq12UctI1dWWm99ypqSYmRUBdKem8MkrO/kgaTt1O7YzlpzE5GIVd0"
            "WYUqt57yWf2McHTObYPbVD+ZwbtlLTVMZ3BW+TnLyXLaWtmEq6WJVbT3HBh3Svj2H"
            "QQcm43XwmtoYM6vVKleh0uoWvnzW3v3MpidruPTQPf0bia7sJOtBM0ufTWNvus/nk"
            "DFHF9ZS+uYVjRUasMeHUmyLYtcklTvzWGFZnNOXczThvpKIzjcahSqIzkvDLayDq6"
            "D3eOjtBbNUEIZYyqsvj4V4wY92eNJ4IoyhTbxXX1T5xsV9tm9r4TQwHLiZw/pdDZJ"
            "ea8TKmsmR/K0uLh/GwnCHghTja6lPhphezPfO5/5MrVvMzNaI3+ERHfrFzPKQukrQ"
            "GI4d/3EFD/3E2mVNYvi4at7CXWREaxZGD+3hg28zD3gVMd6q5c8GdosynKmSeRuGz"
            "pjyl1/9UDGtPR5HeaKT8Wjo17WXk579BXVUhN64ehF9fhRtq/uxxZKzNiZFGD0wRC"
            "3NFROZ5mwIPL/96K/rKMMLrIzF9uhHr+/sYH7DAbwlgC4J+R2Z7FUx1qLnV7MGF40"
            "smVSoJ/jvHRfYhQeUJd/SnYtGWhPHR0Sz+GE2F2yth0B36Vcz2KpnufBJbsysjjW4"
            "kblBUiIjiURUWqJY65zxbnTy57GQyH58zgy0QBtTQv5gH15XMdKkYu+TGaJMnlm2O"
            "34uI4b9tflqp1+QEFGzoW/ulmcofcpkZCYJhDfSpme7QcrHa+Xfji8paEQkTkSfmm"
            "oRWRNZr/F1KfVMjW+IKEnv2FwZfKdzt0BQR6lClcZR0EfEXEfv/G6W9iLiIyCoReV"
            "5EnhORIBHx+ufPj/gLB/zGI/G4Bk0AAAAASUVORK5CYII="),
        DEFAULT_PRIORITY, &d));

    r->Start();
    EXPECT_TRUE(r->is_pending());

    base::RunLoop().Run();

    EXPECT_TRUE(!r->is_pending());
    EXPECT_FALSE(d.received_data_before_response());
    EXPECT_EQ(d.bytes_received(), 911);
    EXPECT_EQ("", r->GetSocketAddress().host());
    EXPECT_EQ(0, r->GetSocketAddress().port());

    HttpRequestHeaders headers;
    EXPECT_FALSE(r->GetFullRequestHeaders(&headers));
  }
}

#if !defined(DISABLE_FILE_SUPPORT)
TEST_F(URLRequestTest, FileTest) {
  base::FilePath app_path;
  PathService::Get(base::FILE_EXE, &app_path);
  GURL app_url = FilePathToFileURL(app_path);

  TestDelegate d;
  {
    scoped_ptr<URLRequest> r(
        default_context_.CreateRequest(app_url, DEFAULT_PRIORITY, &d));

    r->Start();
    EXPECT_TRUE(r->is_pending());

    base::RunLoop().Run();

    int64 file_size = -1;
    EXPECT_TRUE(base::GetFileSize(app_path, &file_size));

    EXPECT_TRUE(!r->is_pending());
    EXPECT_EQ(1, d.response_started_count());
    EXPECT_FALSE(d.received_data_before_response());
    EXPECT_EQ(d.bytes_received(), static_cast<int>(file_size));
    EXPECT_EQ("", r->GetSocketAddress().host());
    EXPECT_EQ(0, r->GetSocketAddress().port());

    HttpRequestHeaders headers;
    EXPECT_FALSE(r->GetFullRequestHeaders(&headers));
  }
}

TEST_F(URLRequestTest, FileTestCancel) {
  base::FilePath app_path;
  PathService::Get(base::FILE_EXE, &app_path);
  GURL app_url = FilePathToFileURL(app_path);

  TestDelegate d;
  {
    scoped_ptr<URLRequest> r(
        default_context_.CreateRequest(app_url, DEFAULT_PRIORITY, &d));

    r->Start();
    EXPECT_TRUE(r->is_pending());
    r->Cancel();
  }
  // Async cancellation should be safe even when URLRequest has been already
  // destroyed.
  base::RunLoop().RunUntilIdle();
}

TEST_F(URLRequestTest, FileTestFullSpecifiedRange) {
  const size_t buffer_size = 4000;
  scoped_ptr<char[]> buffer(new char[buffer_size]);
  FillBuffer(buffer.get(), buffer_size);

  base::FilePath temp_path;
  EXPECT_TRUE(base::CreateTemporaryFile(&temp_path));
  GURL temp_url = FilePathToFileURL(temp_path);
  EXPECT_TRUE(base::WriteFile(temp_path, buffer.get(), buffer_size));

  int64 file_size;
  EXPECT_TRUE(base::GetFileSize(temp_path, &file_size));

  const size_t first_byte_position = 500;
  const size_t last_byte_position = buffer_size - first_byte_position;
  const size_t content_length = last_byte_position - first_byte_position + 1;
  std::string partial_buffer_string(buffer.get() + first_byte_position,
                                    buffer.get() + last_byte_position + 1);

  TestDelegate d;
  {
    scoped_ptr<URLRequest> r(
        default_context_.CreateRequest(temp_url, DEFAULT_PRIORITY, &d));

    HttpRequestHeaders headers;
    headers.SetHeader(
        HttpRequestHeaders::kRange,
        HttpByteRange::Bounded(
            first_byte_position, last_byte_position).GetHeaderValue());
    r->SetExtraRequestHeaders(headers);
    r->Start();
    EXPECT_TRUE(r->is_pending());

    base::RunLoop().Run();
    EXPECT_TRUE(!r->is_pending());
    EXPECT_EQ(1, d.response_started_count());
    EXPECT_FALSE(d.received_data_before_response());
    EXPECT_EQ(static_cast<int>(content_length), d.bytes_received());
    // Don't use EXPECT_EQ, it will print out a lot of garbage if check failed.
    EXPECT_TRUE(partial_buffer_string == d.data_received());
  }

  EXPECT_TRUE(base::DeleteFile(temp_path, false));
}

TEST_F(URLRequestTest, FileTestHalfSpecifiedRange) {
  const size_t buffer_size = 4000;
  scoped_ptr<char[]> buffer(new char[buffer_size]);
  FillBuffer(buffer.get(), buffer_size);

  base::FilePath temp_path;
  EXPECT_TRUE(base::CreateTemporaryFile(&temp_path));
  GURL temp_url = FilePathToFileURL(temp_path);
  EXPECT_TRUE(base::WriteFile(temp_path, buffer.get(), buffer_size));

  int64 file_size;
  EXPECT_TRUE(base::GetFileSize(temp_path, &file_size));

  const size_t first_byte_position = 500;
  const size_t last_byte_position = buffer_size - 1;
  const size_t content_length = last_byte_position - first_byte_position + 1;
  std::string partial_buffer_string(buffer.get() + first_byte_position,
                                    buffer.get() + last_byte_position + 1);

  TestDelegate d;
  {
    scoped_ptr<URLRequest> r(
        default_context_.CreateRequest(temp_url, DEFAULT_PRIORITY, &d));

    HttpRequestHeaders headers;
    headers.SetHeader(HttpRequestHeaders::kRange,
                      HttpByteRange::RightUnbounded(
                          first_byte_position).GetHeaderValue());
    r->SetExtraRequestHeaders(headers);
    r->Start();
    EXPECT_TRUE(r->is_pending());

    base::RunLoop().Run();
    EXPECT_TRUE(!r->is_pending());
    EXPECT_EQ(1, d.response_started_count());
    EXPECT_FALSE(d.received_data_before_response());
    EXPECT_EQ(static_cast<int>(content_length), d.bytes_received());
    // Don't use EXPECT_EQ, it will print out a lot of garbage if check failed.
    EXPECT_TRUE(partial_buffer_string == d.data_received());
  }

  EXPECT_TRUE(base::DeleteFile(temp_path, false));
}

TEST_F(URLRequestTest, FileTestMultipleRanges) {
  const size_t buffer_size = 400000;
  scoped_ptr<char[]> buffer(new char[buffer_size]);
  FillBuffer(buffer.get(), buffer_size);

  base::FilePath temp_path;
  EXPECT_TRUE(base::CreateTemporaryFile(&temp_path));
  GURL temp_url = FilePathToFileURL(temp_path);
  EXPECT_TRUE(base::WriteFile(temp_path, buffer.get(), buffer_size));

  int64 file_size;
  EXPECT_TRUE(base::GetFileSize(temp_path, &file_size));

  TestDelegate d;
  {
    scoped_ptr<URLRequest> r(
        default_context_.CreateRequest(temp_url, DEFAULT_PRIORITY, &d));

    HttpRequestHeaders headers;
    headers.SetHeader(HttpRequestHeaders::kRange, "bytes=0-0,10-200,200-300");
    r->SetExtraRequestHeaders(headers);
    r->Start();
    EXPECT_TRUE(r->is_pending());

    base::RunLoop().Run();
    EXPECT_TRUE(d.request_failed());
  }

  EXPECT_TRUE(base::DeleteFile(temp_path, false));
}

TEST_F(URLRequestTest, AllowFileURLs) {
  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  base::FilePath test_file;
  ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir.path(), &test_file));
  std::string test_data("monkey");
  base::WriteFile(test_file, test_data.data(), test_data.size());
  GURL test_file_url = FilePathToFileURL(test_file);

  {
    TestDelegate d;
    TestNetworkDelegate network_delegate;
    network_delegate.set_can_access_files(true);
    default_context_.set_network_delegate(&network_delegate);
    scoped_ptr<URLRequest> r(
        default_context_.CreateRequest(test_file_url, DEFAULT_PRIORITY, &d));
    r->Start();
    base::RunLoop().Run();
    EXPECT_FALSE(d.request_failed());
    EXPECT_EQ(test_data, d.data_received());
  }

  {
    TestDelegate d;
    TestNetworkDelegate network_delegate;
    network_delegate.set_can_access_files(false);
    default_context_.set_network_delegate(&network_delegate);
    scoped_ptr<URLRequest> r(
        default_context_.CreateRequest(test_file_url, DEFAULT_PRIORITY, &d));
    r->Start();
    base::RunLoop().Run();
    EXPECT_TRUE(d.request_failed());
    EXPECT_EQ("", d.data_received());
  }
}


TEST_F(URLRequestTest, FileDirCancelTest) {
  // Put in mock resource provider.
  NetModule::SetResourceProvider(TestNetResourceProvider);

  TestDelegate d;
  {
    base::FilePath file_path;
    PathService::Get(base::DIR_SOURCE_ROOT, &file_path);
    file_path = file_path.Append(FILE_PATH_LITERAL("net"));
    file_path = file_path.Append(FILE_PATH_LITERAL("data"));

    scoped_ptr<URLRequest> req(default_context_.CreateRequest(
        FilePathToFileURL(file_path), DEFAULT_PRIORITY, &d));
    req->Start();
    EXPECT_TRUE(req->is_pending());

    d.set_cancel_in_received_data_pending(true);

    base::RunLoop().Run();
  }

  // Take out mock resource provider.
  NetModule::SetResourceProvider(NULL);
}

TEST_F(URLRequestTest, FileDirOutputSanity) {
  // Verify the general sanity of the the output of the file:
  // directory lister by checking for the output of a known existing
  // file.
  const char sentinel_name[] = "filedir-sentinel";

  base::FilePath path;
  PathService::Get(base::DIR_SOURCE_ROOT, &path);
  path = path.Append(kTestFilePath);

  TestDelegate d;
  scoped_ptr<URLRequest> req(default_context_.CreateRequest(
      FilePathToFileURL(path), DEFAULT_PRIORITY, &d));
  req->Start();
  base::RunLoop().Run();

  // Generate entry for the sentinel file.
  base::FilePath sentinel_path = path.AppendASCII(sentinel_name);
  base::File::Info info;
  EXPECT_TRUE(base::GetFileInfo(sentinel_path, &info));
  EXPECT_GT(info.size, 0);
  std::string sentinel_output = GetDirectoryListingEntry(
      base::string16(sentinel_name, sentinel_name + strlen(sentinel_name)),
      std::string(sentinel_name),
      false /* is_dir */,
      info.size,
      info.last_modified);

  ASSERT_LT(0, d.bytes_received());
  ASSERT_FALSE(d.request_failed());
  ASSERT_TRUE(req->status().is_success());
  // Check for the entry generated for the "sentinel" file.
  const std::string& data = d.data_received();
  ASSERT_NE(data.find(sentinel_output), std::string::npos);
}

TEST_F(URLRequestTest, FileDirRedirectNoCrash) {
  // There is an implicit redirect when loading a file path that matches a
  // directory and does not end with a slash.  Ensure that following such
  // redirects does not crash.  See http://crbug.com/18686.

  base::FilePath path;
  PathService::Get(base::DIR_SOURCE_ROOT, &path);
  path = path.Append(kTestFilePath);

  TestDelegate d;
  scoped_ptr<URLRequest> req(default_context_.CreateRequest(
      FilePathToFileURL(path), DEFAULT_PRIORITY, &d));
  req->Start();
  base::RunLoop().Run();

  ASSERT_EQ(1, d.received_redirect_count());
  ASSERT_LT(0, d.bytes_received());
  ASSERT_FALSE(d.request_failed());
  ASSERT_TRUE(req->status().is_success());
}

#if defined(OS_WIN)
// Don't accept the url "file:///" on windows. See http://crbug.com/1474.
TEST_F(URLRequestTest, FileDirRedirectSingleSlash) {
  TestDelegate d;
  scoped_ptr<URLRequest> req(
      default_context_.CreateRequest(GURL("file:///"), DEFAULT_PRIORITY, &d));
  req->Start();
  base::RunLoop().Run();

  ASSERT_EQ(1, d.received_redirect_count());
  ASSERT_FALSE(req->status().is_success());
}
#endif  // defined(OS_WIN)

#endif  // !defined(DISABLE_FILE_SUPPORT)

TEST_F(URLRequestTest, InvalidUrlTest) {
  TestDelegate d;
  {
    scoped_ptr<URLRequest> r(default_context_.CreateRequest(
        GURL("invalid url"), DEFAULT_PRIORITY, &d));

    r->Start();
    EXPECT_TRUE(r->is_pending());

    base::RunLoop().Run();
    EXPECT_TRUE(d.request_failed());
  }
}

TEST_F(URLRequestTest, InvalidReferrerTest) {
  TestURLRequestContext context;
  TestNetworkDelegate network_delegate;
  network_delegate.set_cancel_request_with_policy_violating_referrer(true);
  context.set_network_delegate(&network_delegate);
  TestDelegate d;
  scoped_ptr<URLRequest> req(
      context.CreateRequest(GURL("http://localhost/"), DEFAULT_PRIORITY, &d));
  req->SetReferrer("https://somewhere.com/");

  req->Start();
  base::RunLoop().Run();
  EXPECT_TRUE(d.request_failed());
}

#if defined(OS_WIN)
TEST_F(URLRequestTest, ResolveShortcutTest) {
  base::FilePath app_path;
  PathService::Get(base::DIR_SOURCE_ROOT, &app_path);
  app_path = app_path.Append(kTestFilePath);
  app_path = app_path.AppendASCII("with-headers.html");

  std::wstring lnk_path = app_path.value() + L".lnk";

  base::win::ScopedCOMInitializer com_initializer;

  // Temporarily create a shortcut for test
  {
    base::win::ScopedComPtr<IShellLink> shell;
    ASSERT_TRUE(SUCCEEDED(shell.CreateInstance(CLSID_ShellLink, NULL,
                                               CLSCTX_INPROC_SERVER)));
    base::win::ScopedComPtr<IPersistFile> persist;
    ASSERT_TRUE(SUCCEEDED(shell.QueryInterface(persist.Receive())));
    EXPECT_TRUE(SUCCEEDED(shell->SetPath(app_path.value().c_str())));
    EXPECT_TRUE(SUCCEEDED(shell->SetDescription(L"ResolveShortcutTest")));
    EXPECT_TRUE(SUCCEEDED(persist->Save(lnk_path.c_str(), TRUE)));
  }

  TestDelegate d;
  {
    scoped_ptr<URLRequest> r(default_context_.CreateRequest(
        FilePathToFileURL(base::FilePath(lnk_path)), DEFAULT_PRIORITY, &d));

    r->Start();
    EXPECT_TRUE(r->is_pending());

    base::RunLoop().Run();

    WIN32_FILE_ATTRIBUTE_DATA data;
    GetFileAttributesEx(app_path.value().c_str(),
                        GetFileExInfoStandard, &data);
    HANDLE file = CreateFile(app_path.value().c_str(), GENERIC_READ,
                             FILE_SHARE_READ, NULL, OPEN_EXISTING,
                             FILE_ATTRIBUTE_NORMAL, NULL);
    EXPECT_NE(INVALID_HANDLE_VALUE, file);
    scoped_ptr<char[]> buffer(new char[data.nFileSizeLow]);
    DWORD read_size;
    BOOL result;
    result = ReadFile(file, buffer.get(), data.nFileSizeLow,
                      &read_size, NULL);
    std::string content(buffer.get(), read_size);
    CloseHandle(file);

    EXPECT_TRUE(!r->is_pending());
    EXPECT_EQ(1, d.received_redirect_count());
    EXPECT_EQ(content, d.data_received());
  }

  // Clean the shortcut
  DeleteFile(lnk_path.c_str());
}
#endif  // defined(OS_WIN)

// Custom URLRequestJobs for use with interceptor tests
class RestartTestJob : public URLRequestTestJob {
 public:
  RestartTestJob(URLRequest* request, NetworkDelegate* network_delegate)
    : URLRequestTestJob(request, network_delegate, true) {}
 protected:
  void StartAsync() override { this->NotifyRestartRequired(); }
 private:
  ~RestartTestJob() override {}
};

class CancelTestJob : public URLRequestTestJob {
 public:
  explicit CancelTestJob(URLRequest* request, NetworkDelegate* network_delegate)
    : URLRequestTestJob(request, network_delegate, true) {}
 protected:
  void StartAsync() override { request_->Cancel(); }
 private:
  ~CancelTestJob() override {}
};

class CancelThenRestartTestJob : public URLRequestTestJob {
 public:
  explicit CancelThenRestartTestJob(URLRequest* request,
                                    NetworkDelegate* network_delegate)
      : URLRequestTestJob(request, network_delegate, true) {
  }
 protected:
  void StartAsync() override {
    request_->Cancel();
    this->NotifyRestartRequired();
  }
 private:
  ~CancelThenRestartTestJob() override {}
};

// An Interceptor for use with interceptor tests.
class MockURLRequestInterceptor : public URLRequestInterceptor {
 public:
  // Static getters for canned response header and data strings.
  static std::string ok_data() {
    return URLRequestTestJob::test_data_1();
  }

  static std::string ok_headers() {
    return URLRequestTestJob::test_headers();
  }

  static std::string redirect_data() {
    return std::string();
  }

  static std::string redirect_headers() {
    return URLRequestTestJob::test_redirect_headers();
  }

  static std::string error_data() {
    return std::string("ohhh nooooo mr. bill!");
  }

  static std::string error_headers() {
    return URLRequestTestJob::test_error_headers();
  }

  MockURLRequestInterceptor()
      : intercept_main_request_(false), restart_main_request_(false),
        cancel_main_request_(false), cancel_then_restart_main_request_(false),
        simulate_main_network_error_(false),
        intercept_redirect_(false), cancel_redirect_request_(false),
        intercept_final_response_(false), cancel_final_request_(false),
        use_url_request_http_job_(false),
        did_intercept_main_(false), did_restart_main_(false),
        did_cancel_main_(false), did_cancel_then_restart_main_(false),
        did_simulate_error_main_(false),
        did_intercept_redirect_(false), did_cancel_redirect_(false),
        did_intercept_final_(false), did_cancel_final_(false) {
  }

  ~MockURLRequestInterceptor() override {
  }

  // URLRequestInterceptor implementation:
  URLRequestJob* MaybeInterceptRequest(
      URLRequest* request,
      NetworkDelegate* network_delegate) const override {
    if (restart_main_request_) {
      restart_main_request_ = false;
      did_restart_main_ = true;
      return new RestartTestJob(request, network_delegate);
    }
    if (cancel_main_request_) {
      cancel_main_request_ = false;
      did_cancel_main_ = true;
      return new CancelTestJob(request, network_delegate);
    }
    if (cancel_then_restart_main_request_) {
      cancel_then_restart_main_request_ = false;
      did_cancel_then_restart_main_ = true;
      return new CancelThenRestartTestJob(request, network_delegate);
    }
    if (simulate_main_network_error_) {
      simulate_main_network_error_ = false;
      did_simulate_error_main_ = true;
      if (use_url_request_http_job_) {
        return URLRequestHttpJob::Factory(request, network_delegate, "http");
      }
      // This job will result in error since the requested URL is not one of the
      // URLs supported by these tests.
      return new URLRequestTestJob(request, network_delegate, true);
    }
    if (!intercept_main_request_)
      return nullptr;
    intercept_main_request_ = false;
    did_intercept_main_ = true;
    URLRequestTestJob* job =  new URLRequestTestJob(request,
                                                    network_delegate,
                                                    main_headers_,
                                                    main_data_,
                                                    true);
    job->set_load_timing_info(main_request_load_timing_info_);
    return job;
  }

  URLRequestJob* MaybeInterceptRedirect(URLRequest* request,
                                        NetworkDelegate* network_delegate,
                                        const GURL& location) const override {
    if (cancel_redirect_request_) {
      cancel_redirect_request_ = false;
      did_cancel_redirect_ = true;
      return new CancelTestJob(request, network_delegate);
    }
    if (!intercept_redirect_)
      return nullptr;
    intercept_redirect_ = false;
    did_intercept_redirect_ = true;
    if (use_url_request_http_job_) {
      return URLRequestHttpJob::Factory(request, network_delegate, "http");
    }
    return new URLRequestTestJob(request,
                                 network_delegate,
                                 redirect_headers_,
                                 redirect_data_,
                                 true);
  }

  URLRequestJob* MaybeInterceptResponse(
      URLRequest* request,
      NetworkDelegate* network_delegate) const override {
    if (cancel_final_request_) {
      cancel_final_request_ = false;
      did_cancel_final_ = true;
      return new CancelTestJob(request, network_delegate);
    }
    if (!intercept_final_response_)
      return nullptr;
    intercept_final_response_ = false;
    did_intercept_final_ = true;
    if (use_url_request_http_job_) {
      return URLRequestHttpJob::Factory(request, network_delegate, "http");
    }
    return new URLRequestTestJob(request,
                                 network_delegate,
                                 final_headers_,
                                 final_data_,
                                 true);
  }

  void set_intercept_main_request(bool intercept_main_request) {
    intercept_main_request_ = intercept_main_request;
  }

  void set_main_headers(const std::string& main_headers) {
    main_headers_ = main_headers;
  }

  void set_main_data(const std::string& main_data) {
    main_data_ = main_data;
  }

  void set_main_request_load_timing_info(
      const LoadTimingInfo& main_request_load_timing_info) {
    main_request_load_timing_info_ = main_request_load_timing_info;
  }

  void set_restart_main_request(bool restart_main_request) {
    restart_main_request_ = restart_main_request;
  }

  void set_cancel_main_request(bool cancel_main_request) {
    cancel_main_request_ = cancel_main_request;
  }

  void set_cancel_then_restart_main_request(
      bool cancel_then_restart_main_request) {
    cancel_then_restart_main_request_ = cancel_then_restart_main_request;
  }

  void set_simulate_main_network_error(bool simulate_main_network_error) {
    simulate_main_network_error_ = simulate_main_network_error;
  }

  void set_intercept_redirect(bool intercept_redirect) {
    intercept_redirect_ = intercept_redirect;
  }

  void set_redirect_headers(const std::string& redirect_headers) {
    redirect_headers_ = redirect_headers;
  }

  void set_redirect_data(const std::string& redirect_data) {
    redirect_data_ = redirect_data;
  }

  void set_cancel_redirect_request(bool cancel_redirect_request) {
    cancel_redirect_request_ = cancel_redirect_request;
  }

  void set_intercept_final_response(bool intercept_final_response) {
    intercept_final_response_ = intercept_final_response;
  }

  void set_final_headers(const std::string& final_headers) {
    final_headers_ = final_headers;
  }

  void set_final_data(const std::string& final_data) {
    final_data_ = final_data;
  }

  void set_cancel_final_request(bool cancel_final_request) {
    cancel_final_request_ = cancel_final_request;
  }

  void set_use_url_request_http_job(bool use_url_request_http_job) {
    use_url_request_http_job_ = use_url_request_http_job;
  }

  bool did_intercept_main() const {
    return did_intercept_main_;
  }

  bool did_restart_main() const {
    return did_restart_main_;
  }

  bool did_cancel_main() const {
    return did_cancel_main_;
  }

  bool did_cancel_then_restart_main() const {
    return did_cancel_then_restart_main_;
  }

  bool did_simulate_error_main() const {
    return did_simulate_error_main_;
  }

  bool did_intercept_redirect() const {
    return did_intercept_redirect_;
  }

  bool did_cancel_redirect() const {
    return did_cancel_redirect_;
  }

  bool did_intercept_final() const {
    return did_intercept_final_;
  }

  bool did_cancel_final() const {
    return did_cancel_final_;
  }

 private:
  // Indicate whether to intercept the main request, and if so specify the
  // response to return and the LoadTimingInfo to use.
  mutable bool intercept_main_request_;
  mutable std::string main_headers_;
  mutable std::string main_data_;
  mutable LoadTimingInfo main_request_load_timing_info_;

  // These indicate actions that can be taken within MaybeInterceptRequest.
  mutable bool restart_main_request_;
  mutable bool cancel_main_request_;
  mutable bool cancel_then_restart_main_request_;
  mutable bool simulate_main_network_error_;

  // Indicate whether to intercept redirects, and if so specify the response to
  // return.
  mutable bool intercept_redirect_;
  mutable std::string redirect_headers_;
  mutable std::string redirect_data_;

  // Cancel the request within MaybeInterceptRedirect.
  mutable bool cancel_redirect_request_;

  // Indicate whether to intercept the final response, and if so specify the
  // response to return.
  mutable bool intercept_final_response_;
  mutable std::string final_headers_;
  mutable std::string final_data_;

  // Cancel the final request within MaybeInterceptResponse.
  mutable bool cancel_final_request_;

  // Instruct the interceptor to use a real URLRequestHTTPJob.
  mutable bool use_url_request_http_job_;

  // These indicate if the interceptor did something or not.
  mutable bool did_intercept_main_;
  mutable bool did_restart_main_;
  mutable bool did_cancel_main_;
  mutable bool did_cancel_then_restart_main_;
  mutable bool did_simulate_error_main_;
  mutable bool did_intercept_redirect_;
  mutable bool did_cancel_redirect_;
  mutable bool did_intercept_final_;
  mutable bool did_cancel_final_;
};

// Inherit PlatformTest since we require the autorelease pool on Mac OS X.
class URLRequestInterceptorTest : public URLRequestTest {
 public:
  URLRequestInterceptorTest() : URLRequestTest(), interceptor_(NULL) {
  }

  ~URLRequestInterceptorTest() override {
    // URLRequestJobs may post clean-up tasks on destruction.
    base::RunLoop().RunUntilIdle();
  }

  void SetUpFactory() override {
    interceptor_ = new MockURLRequestInterceptor();
    job_factory_.reset(new URLRequestInterceptingJobFactory(
        job_factory_.Pass(), make_scoped_ptr(interceptor_)));
  }

  MockURLRequestInterceptor* interceptor() const {
    return interceptor_;
  }

 private:
  MockURLRequestInterceptor* interceptor_;
};

TEST_F(URLRequestInterceptorTest, Intercept) {
  // Intercept the main request and respond with a simple response.
  interceptor()->set_intercept_main_request(true);
  interceptor()->set_main_headers(MockURLRequestInterceptor::ok_headers());
  interceptor()->set_main_data(MockURLRequestInterceptor::ok_data());
  TestDelegate d;
  scoped_ptr<URLRequest> req(default_context().CreateRequest(
      GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d));
  base::SupportsUserData::Data* user_data0 = new base::SupportsUserData::Data();
  base::SupportsUserData::Data* user_data1 = new base::SupportsUserData::Data();
  base::SupportsUserData::Data* user_data2 = new base::SupportsUserData::Data();
  req->SetUserData(nullptr, user_data0);
  req->SetUserData(&user_data1, user_data1);
  req->SetUserData(&user_data2, user_data2);
  req->set_method("GET");
  req->Start();
  base::RunLoop().Run();

  // Make sure we can retrieve our specific user data.
  EXPECT_EQ(user_data0, req->GetUserData(nullptr));
  EXPECT_EQ(user_data1, req->GetUserData(&user_data1));
  EXPECT_EQ(user_data2, req->GetUserData(&user_data2));

  // Check that we got one good response.
  EXPECT_TRUE(req->status().is_success());
  EXPECT_EQ(200, req->response_headers()->response_code());
  EXPECT_EQ(MockURLRequestInterceptor::ok_data(), d.data_received());
  EXPECT_EQ(1, d.response_started_count());
  EXPECT_EQ(0, d.received_redirect_count());
}

TEST_F(URLRequestInterceptorTest, InterceptRedirect) {
  // Intercept the main request and respond with a redirect.
  interceptor()->set_intercept_main_request(true);
  interceptor()->set_main_headers(
      MockURLRequestInterceptor::redirect_headers());
  interceptor()->set_main_data(MockURLRequestInterceptor::redirect_data());

  // Intercept that redirect and respond with a final OK response.
  interceptor()->set_intercept_redirect(true);
  interceptor()->set_redirect_headers(MockURLRequestInterceptor::ok_headers());
  interceptor()->set_redirect_data(MockURLRequestInterceptor::ok_data());

  TestDelegate d;
  scoped_ptr<URLRequest> req(default_context().CreateRequest(
      GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d));
  req->set_method("GET");
  req->Start();
  base::RunLoop().Run();

  // Check that the interceptor got called as expected.
  EXPECT_TRUE(interceptor()->did_intercept_main());
  EXPECT_TRUE(interceptor()->did_intercept_redirect());

  // Check that we got one good response.
  EXPECT_TRUE(req->status().is_success());
  if (req->status().is_success())
    EXPECT_EQ(200, req->response_headers()->response_code());

  EXPECT_EQ(MockURLRequestInterceptor::ok_data(), d.data_received());
  EXPECT_EQ(1, d.response_started_count());
  EXPECT_EQ(0, d.received_redirect_count());
}

TEST_F(URLRequestInterceptorTest, InterceptServerError) {
  // Intercept the main request to generate a server error response.
  interceptor()->set_intercept_main_request(true);
  interceptor()->set_main_headers(MockURLRequestInterceptor::error_headers());
  interceptor()->set_main_data(MockURLRequestInterceptor::error_data());

  // Intercept that error and respond with an OK response.
  interceptor()->set_intercept_final_response(true);
  interceptor()->set_final_headers(MockURLRequestInterceptor::ok_headers());
  interceptor()->set_final_data(MockURLRequestInterceptor::ok_data());

  TestDelegate d;
  scoped_ptr<URLRequest> req(default_context().CreateRequest(
      GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d));
  req->set_method("GET");
  req->Start();
  base::RunLoop().Run();

  // Check that the interceptor got called as expected.
  EXPECT_TRUE(interceptor()->did_intercept_main());
  EXPECT_TRUE(interceptor()->did_intercept_final());

  // Check that we got one good response.
  EXPECT_TRUE(req->status().is_success());
  EXPECT_EQ(200, req->response_headers()->response_code());
  EXPECT_EQ(MockURLRequestInterceptor::ok_data(), d.data_received());
  EXPECT_EQ(1, d.response_started_count());
  EXPECT_EQ(0, d.received_redirect_count());
}

TEST_F(URLRequestInterceptorTest, InterceptNetworkError) {
  // Intercept the main request to simulate a network error.
  interceptor()->set_simulate_main_network_error(true);

  // Intercept that error and respond with an OK response.
  interceptor()->set_intercept_final_response(true);
  interceptor()->set_final_headers(MockURLRequestInterceptor::ok_headers());
  interceptor()->set_final_data(MockURLRequestInterceptor::ok_data());

  TestDelegate d;
  scoped_ptr<URLRequest> req(default_context().CreateRequest(
      GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d));
  req->set_method("GET");
  req->Start();
  base::RunLoop().Run();

  // Check that the interceptor got called as expected.
  EXPECT_TRUE(interceptor()->did_simulate_error_main());
  EXPECT_TRUE(interceptor()->did_intercept_final());

  // Check that we received one good response.
  EXPECT_TRUE(req->status().is_success());
  EXPECT_EQ(200, req->response_headers()->response_code());
  EXPECT_EQ(MockURLRequestInterceptor::ok_data(), d.data_received());
  EXPECT_EQ(1, d.response_started_count());
  EXPECT_EQ(0, d.received_redirect_count());
}

TEST_F(URLRequestInterceptorTest, InterceptRestartRequired) {
  // Restart the main request.
  interceptor()->set_restart_main_request(true);

  // then intercept the new main request and respond with an OK response
  interceptor()->set_intercept_main_request(true);
  interceptor()->set_main_headers(MockURLRequestInterceptor::ok_headers());
  interceptor()->set_main_data(MockURLRequestInterceptor::ok_data());

  TestDelegate d;
  scoped_ptr<URLRequest> req(default_context().CreateRequest(
      GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d));
  req->set_method("GET");
  req->Start();
  base::RunLoop().Run();

  // Check that the interceptor got called as expected.
  EXPECT_TRUE(interceptor()->did_restart_main());
  EXPECT_TRUE(interceptor()->did_intercept_main());

  // Check that we received one good response.
  EXPECT_TRUE(req->status().is_success());
  if (req->status().is_success())
    EXPECT_EQ(200, req->response_headers()->response_code());

  EXPECT_EQ(MockURLRequestInterceptor::ok_data(), d.data_received());
  EXPECT_EQ(1, d.response_started_count());
  EXPECT_EQ(0, d.received_redirect_count());
}

TEST_F(URLRequestInterceptorTest, InterceptRespectsCancelMain) {
  // Intercept the main request and cancel from within the restarted job.
  interceptor()->set_cancel_main_request(true);

  // Set up to intercept the final response and override it with an OK response.
  interceptor()->set_intercept_final_response(true);
  interceptor()->set_final_headers(MockURLRequestInterceptor::ok_headers());
  interceptor()->set_final_data(MockURLRequestInterceptor::ok_data());

  TestDelegate d;
  scoped_ptr<URLRequest> req(default_context().CreateRequest(
      GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d));
  req->set_method("GET");
  req->Start();
  base::RunLoop().Run();

  // Check that the interceptor got called as expected.
  EXPECT_TRUE(interceptor()->did_cancel_main());
  EXPECT_FALSE(interceptor()->did_intercept_final());

  // Check that we see a canceled request.
  EXPECT_FALSE(req->status().is_success());
  EXPECT_EQ(URLRequestStatus::CANCELED, req->status().status());
}

TEST_F(URLRequestInterceptorTest, InterceptRespectsCancelRedirect) {
  // Intercept the main request and respond with a redirect.
  interceptor()->set_intercept_main_request(true);
  interceptor()->set_main_headers(
      MockURLRequestInterceptor::redirect_headers());
  interceptor()->set_main_data(MockURLRequestInterceptor::redirect_data());

  // Intercept the redirect and cancel from within that job.
  interceptor()->set_cancel_redirect_request(true);

  // Set up to intercept the final response and override it with an OK response.
  interceptor()->set_intercept_final_response(true);
  interceptor()->set_final_headers(MockURLRequestInterceptor::ok_headers());
  interceptor()->set_final_data(MockURLRequestInterceptor::ok_data());

  TestDelegate d;
  scoped_ptr<URLRequest> req(default_context().CreateRequest(
      GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d));
  req->set_method("GET");
  req->Start();
  base::RunLoop().Run();

  // Check that the interceptor got called as expected.
  EXPECT_TRUE(interceptor()->did_intercept_main());
  EXPECT_TRUE(interceptor()->did_cancel_redirect());
  EXPECT_FALSE(interceptor()->did_intercept_final());

  // Check that we see a canceled request.
  EXPECT_FALSE(req->status().is_success());
  EXPECT_EQ(URLRequestStatus::CANCELED, req->status().status());
}

TEST_F(URLRequestInterceptorTest, InterceptRespectsCancelFinal) {
  // Intercept the main request to simulate a network error.
  interceptor()->set_simulate_main_network_error(true);

  // Set up to intercept final the response and cancel from within that job.
  interceptor()->set_cancel_final_request(true);

  TestDelegate d;
  scoped_ptr<URLRequest> req(default_context().CreateRequest(
      GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d));
  req->set_method("GET");
  req->Start();
  base::RunLoop().Run();

  // Check that the interceptor got called as expected.
  EXPECT_TRUE(interceptor()->did_simulate_error_main());
  EXPECT_TRUE(interceptor()->did_cancel_final());

  // Check that we see a canceled request.
  EXPECT_FALSE(req->status().is_success());
  EXPECT_EQ(URLRequestStatus::CANCELED, req->status().status());
}

TEST_F(URLRequestInterceptorTest, InterceptRespectsCancelInRestart) {
  // Intercept the main request and cancel then restart from within that job.
  interceptor()->set_cancel_then_restart_main_request(true);

  // Set up to intercept the final response and override it with an OK response.
  interceptor()->set_intercept_final_response(true);
  interceptor()->set_final_headers(MockURLRequestInterceptor::ok_headers());
  interceptor()->set_final_data(MockURLRequestInterceptor::ok_data());

  TestDelegate d;
  scoped_ptr<URLRequest> req(default_context().CreateRequest(
      GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d));
  req->set_method("GET");
  req->Start();
  base::RunLoop().Run();

  // Check that the interceptor got called as expected.
  EXPECT_TRUE(interceptor()->did_cancel_then_restart_main());
  EXPECT_FALSE(interceptor()->did_intercept_final());

  // Check that we see a canceled request.
  EXPECT_FALSE(req->status().is_success());
  EXPECT_EQ(URLRequestStatus::CANCELED, req->status().status());
}

// "Normal" LoadTimingInfo as returned by a job.  Everything is in order, not
// reused.  |connect_time_flags| is used to indicate if there should be dns
// or SSL times, and |used_proxy| is used for proxy times.
LoadTimingInfo NormalLoadTimingInfo(base::TimeTicks now,
                                    int connect_time_flags,
                                    bool used_proxy) {
  LoadTimingInfo load_timing;
  load_timing.socket_log_id = 1;

  if (used_proxy) {
    load_timing.proxy_resolve_start = now + base::TimeDelta::FromDays(1);
    load_timing.proxy_resolve_end = now + base::TimeDelta::FromDays(2);
  }

  LoadTimingInfo::ConnectTiming& connect_timing = load_timing.connect_timing;
  if (connect_time_flags & CONNECT_TIMING_HAS_DNS_TIMES) {
    connect_timing.dns_start = now + base::TimeDelta::FromDays(3);
    connect_timing.dns_end = now + base::TimeDelta::FromDays(4);
  }
  connect_timing.connect_start = now + base::TimeDelta::FromDays(5);
  if (connect_time_flags & CONNECT_TIMING_HAS_SSL_TIMES) {
    connect_timing.ssl_start = now + base::TimeDelta::FromDays(6);
    connect_timing.ssl_end = now + base::TimeDelta::FromDays(7);
  }
  connect_timing.connect_end = now + base::TimeDelta::FromDays(8);

  load_timing.send_start = now + base::TimeDelta::FromDays(9);
  load_timing.send_end = now + base::TimeDelta::FromDays(10);
  load_timing.receive_headers_end = now + base::TimeDelta::FromDays(11);
  return load_timing;
}

// Same as above, but in the case of a reused socket.
LoadTimingInfo NormalLoadTimingInfoReused(base::TimeTicks now,
                                          bool used_proxy) {
  LoadTimingInfo load_timing;
  load_timing.socket_log_id = 1;
  load_timing.socket_reused = true;

  if (used_proxy) {
    load_timing.proxy_resolve_start = now + base::TimeDelta::FromDays(1);
    load_timing.proxy_resolve_end = now + base::TimeDelta::FromDays(2);
  }

  load_timing.send_start = now + base::TimeDelta::FromDays(9);
  load_timing.send_end = now + base::TimeDelta::FromDays(10);
  load_timing.receive_headers_end = now + base::TimeDelta::FromDays(11);
  return load_timing;
}

LoadTimingInfo RunURLRequestInterceptorLoadTimingTest(
    const LoadTimingInfo& job_load_timing,
    const URLRequestContext& context,
    MockURLRequestInterceptor* interceptor) {
  interceptor->set_intercept_main_request(true);
  interceptor->set_main_request_load_timing_info(job_load_timing);
  TestDelegate d;
  scoped_ptr<URLRequest> req(context.CreateRequest(
      GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d));
  req->Start();
  base::RunLoop().Run();

  LoadTimingInfo resulting_load_timing;
  req->GetLoadTimingInfo(&resulting_load_timing);

  // None of these should be modified by the URLRequest.
  EXPECT_EQ(job_load_timing.socket_reused, resulting_load_timing.socket_reused);
  EXPECT_EQ(job_load_timing.socket_log_id, resulting_load_timing.socket_log_id);
  EXPECT_EQ(job_load_timing.send_start, resulting_load_timing.send_start);
  EXPECT_EQ(job_load_timing.send_end, resulting_load_timing.send_end);
  EXPECT_EQ(job_load_timing.receive_headers_end,
            resulting_load_timing.receive_headers_end);

  return resulting_load_timing;
}

// Basic test that the intercept + load timing tests work.
TEST_F(URLRequestInterceptorTest, InterceptLoadTiming) {
  base::TimeTicks now = base::TimeTicks::Now();
  LoadTimingInfo job_load_timing =
      NormalLoadTimingInfo(now, CONNECT_TIMING_HAS_DNS_TIMES, false);

  LoadTimingInfo load_timing_result =
      RunURLRequestInterceptorLoadTimingTest(
          job_load_timing, default_context(), interceptor());

  // Nothing should have been changed by the URLRequest.
  EXPECT_EQ(job_load_timing.proxy_resolve_start,
            load_timing_result.proxy_resolve_start);
  EXPECT_EQ(job_load_timing.proxy_resolve_end,
            load_timing_result.proxy_resolve_end);
  EXPECT_EQ(job_load_timing.connect_timing.dns_start,
            load_timing_result.connect_timing.dns_start);
  EXPECT_EQ(job_load_timing.connect_timing.dns_end,
            load_timing_result.connect_timing.dns_end);
  EXPECT_EQ(job_load_timing.connect_timing.connect_start,
            load_timing_result.connect_timing.connect_start);
  EXPECT_EQ(job_load_timing.connect_timing.connect_end,
            load_timing_result.connect_timing.connect_end);
  EXPECT_EQ(job_load_timing.connect_timing.ssl_start,
            load_timing_result.connect_timing.ssl_start);
  EXPECT_EQ(job_load_timing.connect_timing.ssl_end,
            load_timing_result.connect_timing.ssl_end);

  // Redundant sanity check.
  TestLoadTimingNotReused(load_timing_result, CONNECT_TIMING_HAS_DNS_TIMES);
}

// Another basic test, with proxy and SSL times, but no DNS times.
TEST_F(URLRequestInterceptorTest, InterceptLoadTimingProxy) {
  base::TimeTicks now = base::TimeTicks::Now();
  LoadTimingInfo job_load_timing =
      NormalLoadTimingInfo(now, CONNECT_TIMING_HAS_SSL_TIMES, true);

  LoadTimingInfo load_timing_result =
      RunURLRequestInterceptorLoadTimingTest(
          job_load_timing, default_context(), interceptor());

  // Nothing should have been changed by the URLRequest.
  EXPECT_EQ(job_load_timing.proxy_resolve_start,
            load_timing_result.proxy_resolve_start);
  EXPECT_EQ(job_load_timing.proxy_resolve_end,
            load_timing_result.proxy_resolve_end);
  EXPECT_EQ(job_load_timing.connect_timing.dns_start,
            load_timing_result.connect_timing.dns_start);
  EXPECT_EQ(job_load_timing.connect_timing.dns_end,
            load_timing_result.connect_timing.dns_end);
  EXPECT_EQ(job_load_timing.connect_timing.connect_start,
            load_timing_result.connect_timing.connect_start);
  EXPECT_EQ(job_load_timing.connect_timing.connect_end,
            load_timing_result.connect_timing.connect_end);
  EXPECT_EQ(job_load_timing.connect_timing.ssl_start,
            load_timing_result.connect_timing.ssl_start);
  EXPECT_EQ(job_load_timing.connect_timing.ssl_end,
            load_timing_result.connect_timing.ssl_end);

  // Redundant sanity check.
  TestLoadTimingNotReusedWithProxy(load_timing_result,
                                   CONNECT_TIMING_HAS_SSL_TIMES);
}

// Make sure that URLRequest correctly adjusts proxy times when they're before
// |request_start|, due to already having a connected socket.  This happens in
// the case of reusing a SPDY session.  The connected socket is not considered
// reused in this test (May be a preconnect).
//
// To mix things up from the test above, assumes DNS times but no SSL times.
TEST_F(URLRequestInterceptorTest, InterceptLoadTimingEarlyProxyResolution) {
  base::TimeTicks now = base::TimeTicks::Now();
  LoadTimingInfo job_load_timing =
      NormalLoadTimingInfo(now, CONNECT_TIMING_HAS_DNS_TIMES, true);
  job_load_timing.proxy_resolve_start = now - base::TimeDelta::FromDays(6);
  job_load_timing.proxy_resolve_end = now - base::TimeDelta::FromDays(5);
  job_load_timing.connect_timing.dns_start = now - base::TimeDelta::FromDays(4);
  job_load_timing.connect_timing.dns_end = now - base::TimeDelta::FromDays(3);
  job_load_timing.connect_timing.connect_start =
      now - base::TimeDelta::FromDays(2);
  job_load_timing.connect_timing.connect_end =
      now - base::TimeDelta::FromDays(1);

  LoadTimingInfo load_timing_result =
      RunURLRequestInterceptorLoadTimingTest(
          job_load_timing, default_context(), interceptor());

  // Proxy times, connect times, and DNS times should all be replaced with
  // request_start.
  EXPECT_EQ(load_timing_result.request_start,
            load_timing_result.proxy_resolve_start);
  EXPECT_EQ(load_timing_result.request_start,
            load_timing_result.proxy_resolve_end);
  EXPECT_EQ(load_timing_result.request_start,
            load_timing_result.connect_timing.dns_start);
  EXPECT_EQ(load_timing_result.request_start,
            load_timing_result.connect_timing.dns_end);
  EXPECT_EQ(load_timing_result.request_start,
            load_timing_result.connect_timing.connect_start);
  EXPECT_EQ(load_timing_result.request_start,
            load_timing_result.connect_timing.connect_end);

  // Other times should have been left null.
  TestLoadTimingNotReusedWithProxy(load_timing_result,
                                   CONNECT_TIMING_HAS_DNS_TIMES);
}

// Same as above, but in the reused case.
TEST_F(URLRequestInterceptorTest,
       InterceptLoadTimingEarlyProxyResolutionReused) {
  base::TimeTicks now = base::TimeTicks::Now();
  LoadTimingInfo job_load_timing = NormalLoadTimingInfoReused(now, true);
  job_load_timing.proxy_resolve_start = now - base::TimeDelta::FromDays(4);
  job_load_timing.proxy_resolve_end = now - base::TimeDelta::FromDays(3);

  LoadTimingInfo load_timing_result =
      RunURLRequestInterceptorLoadTimingTest(
          job_load_timing, default_context(), interceptor());

  // Proxy times and connect times should all be replaced with request_start.
  EXPECT_EQ(load_timing_result.request_start,
            load_timing_result.proxy_resolve_start);
  EXPECT_EQ(load_timing_result.request_start,
            load_timing_result.proxy_resolve_end);

  // Other times should have been left null.
  TestLoadTimingReusedWithProxy(load_timing_result);
}

// Make sure that URLRequest correctly adjusts connect times when they're before
// |request_start|, due to reusing a connected socket.  The connected socket is
// not considered reused in this test (May be a preconnect).
//
// To mix things up, the request has SSL times, but no DNS times.
TEST_F(URLRequestInterceptorTest, InterceptLoadTimingEarlyConnect) {
  base::TimeTicks now = base::TimeTicks::Now();
  LoadTimingInfo job_load_timing =
      NormalLoadTimingInfo(now, CONNECT_TIMING_HAS_SSL_TIMES, false);
  job_load_timing.connect_timing.connect_start =
      now - base::TimeDelta::FromDays(1);
  job_load_timing.connect_timing.ssl_start = now - base::TimeDelta::FromDays(2);
  job_load_timing.connect_timing.ssl_end = now - base::TimeDelta::FromDays(3);
  job_load_timing.connect_timing.connect_end =
      now - base::TimeDelta::FromDays(4);

  LoadTimingInfo load_timing_result =
      RunURLRequestInterceptorLoadTimingTest(
          job_load_timing, default_context(), interceptor());

  // Connect times, and SSL times should be replaced with request_start.
  EXPECT_EQ(load_timing_result.request_start,
            load_timing_result.connect_timing.connect_start);
  EXPECT_EQ(load_timing_result.request_start,
            load_timing_result.connect_timing.ssl_start);
  EXPECT_EQ(load_timing_result.request_start,
            load_timing_result.connect_timing.ssl_end);
  EXPECT_EQ(load_timing_result.request_start,
            load_timing_result.connect_timing.connect_end);

  // Other times should have been left null.
  TestLoadTimingNotReused(load_timing_result, CONNECT_TIMING_HAS_SSL_TIMES);
}

// Make sure that URLRequest correctly adjusts connect times when they're before
// |request_start|, due to reusing a connected socket in the case that there
// are also proxy times.  The connected socket is not considered reused in this
// test (May be a preconnect).
//
// In this test, there are no SSL or DNS times.
TEST_F(URLRequestInterceptorTest, InterceptLoadTimingEarlyConnectWithProxy) {
  base::TimeTicks now = base::TimeTicks::Now();
  LoadTimingInfo job_load_timing =
      NormalLoadTimingInfo(now, CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY, true);
  job_load_timing.connect_timing.connect_start =
      now - base::TimeDelta::FromDays(1);
  job_load_timing.connect_timing.connect_end =
      now - base::TimeDelta::FromDays(2);

  LoadTimingInfo load_timing_result =
      RunURLRequestInterceptorLoadTimingTest(
          job_load_timing, default_context(), interceptor());

  // Connect times should be replaced with proxy_resolve_end.
  EXPECT_EQ(load_timing_result.proxy_resolve_end,
            load_timing_result.connect_timing.connect_start);
  EXPECT_EQ(load_timing_result.proxy_resolve_end,
            load_timing_result.connect_timing.connect_end);

  // Other times should have been left null.
  TestLoadTimingNotReusedWithProxy(load_timing_result,
                                   CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
}

// Check that two different URL requests have different identifiers.
TEST_F(URLRequestTest, Identifiers) {
  TestDelegate d;
  TestURLRequestContext context;
  scoped_ptr<URLRequest> req(
      context.CreateRequest(GURL("http://example.com"), DEFAULT_PRIORITY, &d));
  scoped_ptr<URLRequest> other_req(
      context.CreateRequest(GURL("http://example.com"), DEFAULT_PRIORITY, &d));

  ASSERT_NE(req->identifier(), other_req->identifier());
}

// Check that a failure to connect to the proxy is reported to the network
// delegate.
TEST_F(URLRequestTest, NetworkDelegateProxyError) {
  MockHostResolver host_resolver;
  host_resolver.rules()->AddSimulatedFailure("*");

  TestNetworkDelegate network_delegate;  // Must outlive URLRequests.
  TestURLRequestContextWithProxy context("myproxy:70", &network_delegate);

  TestDelegate d;
  scoped_ptr<URLRequest> req(
      context.CreateRequest(GURL("http://example.com"), DEFAULT_PRIORITY, &d));
  req->set_method("GET");

  req->Start();
  base::RunLoop().Run();

  // Check we see a failed request.
  EXPECT_FALSE(req->status().is_success());
  // The proxy server is not set before failure.
  EXPECT_TRUE(req->proxy_server().IsEmpty());
  EXPECT_EQ(URLRequestStatus::FAILED, req->status().status());
  EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, req->status().error());

  EXPECT_EQ(1, network_delegate.error_count());
  EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, network_delegate.last_error());
  EXPECT_EQ(1, network_delegate.completed_requests());
}

// Make sure that NetworkDelegate::NotifyCompleted is called if
// content is empty.
TEST_F(URLRequestTest, RequestCompletionForEmptyResponse) {
  TestDelegate d;
  scoped_ptr<URLRequest> req(
      default_context_.CreateRequest(GURL("data:,"), DEFAULT_PRIORITY, &d));
  req->Start();
  base::RunLoop().Run();
  EXPECT_EQ("", d.data_received());
  EXPECT_EQ(1, default_network_delegate_.completed_requests());
}

// Make sure that SetPriority actually sets the URLRequest's priority
// correctly, both before and after start.
TEST_F(URLRequestTest, SetPriorityBasic) {
  TestDelegate d;
  scoped_ptr<URLRequest> req(default_context_.CreateRequest(
      GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d));
  EXPECT_EQ(DEFAULT_PRIORITY, req->priority());

  req->SetPriority(LOW);
  EXPECT_EQ(LOW, req->priority());

  req->Start();
  EXPECT_EQ(LOW, req->priority());

  req->SetPriority(MEDIUM);
  EXPECT_EQ(MEDIUM, req->priority());
}

// Make sure that URLRequest calls SetPriority on a job before calling
// Start on it.
TEST_F(URLRequestTest, SetJobPriorityBeforeJobStart) {
  TestDelegate d;
  scoped_ptr<URLRequest> req(default_context_.CreateRequest(
      GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d));
  EXPECT_EQ(DEFAULT_PRIORITY, req->priority());

  scoped_refptr<URLRequestTestJob> job =
      new URLRequestTestJob(req.get(), &default_network_delegate_);
  AddTestInterceptor()->set_main_intercept_job(job.get());
  EXPECT_EQ(DEFAULT_PRIORITY, job->priority());

  req->SetPriority(LOW);

  req->Start();
  EXPECT_EQ(LOW, job->priority());
}

// Make sure that URLRequest passes on its priority updates to its
// job.
TEST_F(URLRequestTest, SetJobPriority) {
  TestDelegate d;
  scoped_ptr<URLRequest> req(default_context_.CreateRequest(
      GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d));

  scoped_refptr<URLRequestTestJob> job =
      new URLRequestTestJob(req.get(), &default_network_delegate_);
  AddTestInterceptor()->set_main_intercept_job(job.get());

  req->SetPriority(LOW);
  req->Start();
  EXPECT_EQ(LOW, job->priority());

  req->SetPriority(MEDIUM);
  EXPECT_EQ(MEDIUM, req->priority());
  EXPECT_EQ(MEDIUM, job->priority());
}

// Setting the IGNORE_LIMITS load flag should be okay if the priority
// is MAXIMUM_PRIORITY.
TEST_F(URLRequestTest, PriorityIgnoreLimits) {
  TestDelegate d;
  scoped_ptr<URLRequest> req(default_context_.CreateRequest(
      GURL("http://test_intercept/foo"), MAXIMUM_PRIORITY, &d));
  EXPECT_EQ(MAXIMUM_PRIORITY, req->priority());

  scoped_refptr<URLRequestTestJob> job =
      new URLRequestTestJob(req.get(), &default_network_delegate_);
  AddTestInterceptor()->set_main_intercept_job(job.get());

  req->SetLoadFlags(LOAD_IGNORE_LIMITS);
  EXPECT_EQ(MAXIMUM_PRIORITY, req->priority());

  req->SetPriority(MAXIMUM_PRIORITY);
  EXPECT_EQ(MAXIMUM_PRIORITY, req->priority());

  req->Start();
  EXPECT_EQ(MAXIMUM_PRIORITY, req->priority());
  EXPECT_EQ(MAXIMUM_PRIORITY, job->priority());
}

// TODO(droger): Support SpawnedTestServer on iOS (see http://crbug.com/148666).
#if !defined(OS_IOS)
namespace {

// Less verbose way of running a simple testserver for the tests below.
class LocalHttpTestServer : public SpawnedTestServer {
 public:
  explicit LocalHttpTestServer(const base::FilePath& document_root)
      : SpawnedTestServer(SpawnedTestServer::TYPE_HTTP,
                          SpawnedTestServer::kLocalhost,
                          document_root) {}
  LocalHttpTestServer()
      : SpawnedTestServer(SpawnedTestServer::TYPE_HTTP,
                          SpawnedTestServer::kLocalhost,
                          base::FilePath()) {}
};

}  // namespace

TEST_F(URLRequestTest, DelayedCookieCallback) {
  LocalHttpTestServer test_server;
  ASSERT_TRUE(test_server.Start());

  TestURLRequestContext context;
  scoped_refptr<DelayedCookieMonster> delayed_cm =
      new DelayedCookieMonster();
  scoped_refptr<CookieStore> cookie_store = delayed_cm;
  context.set_cookie_store(delayed_cm.get());

  // Set up a cookie.
  {
    TestNetworkDelegate network_delegate;
    context.set_network_delegate(&network_delegate);
    TestDelegate d;
    scoped_ptr<URLRequest> req(context.CreateRequest(
        test_server.GetURL("set-cookie?CookieToNotSend=1"), DEFAULT_PRIORITY,
        &d));
    req->Start();
    base::RunLoop().Run();
    EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
    EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
    EXPECT_EQ(1, network_delegate.set_cookie_count());
  }

  // Verify that the cookie is set.
  {
    TestNetworkDelegate network_delegate;
    context.set_network_delegate(&network_delegate);
    TestDelegate d;
    scoped_ptr<URLRequest> req(context.CreateRequest(
        test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d));
    req->Start();
    base::RunLoop().Run();

    EXPECT_TRUE(d.data_received().find("CookieToNotSend=1")
                != std::string::npos);
    EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
    EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
  }
}

TEST_F(URLRequestTest, DoNotSendCookies) {
  LocalHttpTestServer test_server;
  ASSERT_TRUE(test_server.Start());

  // Set up a cookie.
  {
    TestNetworkDelegate network_delegate;
    default_context_.set_network_delegate(&network_delegate);
    TestDelegate d;
    scoped_ptr<URLRequest> req(default_context_.CreateRequest(
        test_server.GetURL("set-cookie?CookieToNotSend=1"), DEFAULT_PRIORITY,
        &d));
    req->Start();
    base::RunLoop().Run();
    EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
    EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
  }

  // Verify that the cookie is set.
  {
    TestNetworkDelegate network_delegate;
    default_context_.set_network_delegate(&network_delegate);
    TestDelegate d;
    scoped_ptr<URLRequest> req(default_context_.CreateRequest(
        test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d));
    req->Start();
    base::RunLoop().Run();

    EXPECT_TRUE(d.data_received().find("CookieToNotSend=1")
                != std::string::npos);
    EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
    EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
  }

  // Verify that the cookie isn't sent when LOAD_DO_NOT_SEND_COOKIES is set.
  {
    TestNetworkDelegate network_delegate;
    default_context_.set_network_delegate(&network_delegate);
    TestDelegate d;
    scoped_ptr<URLRequest> req(default_context_.CreateRequest(
        test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d));
    req->SetLoadFlags(LOAD_DO_NOT_SEND_COOKIES);
    req->Start();
    base::RunLoop().Run();

    EXPECT_TRUE(d.data_received().find("Cookie: CookieToNotSend=1")
                == std::string::npos);

    // LOAD_DO_NOT_SEND_COOKIES does not trigger OnGetCookies.
    EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
    EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
  }
}

TEST_F(URLRequestTest, DoNotSaveCookies) {
  LocalHttpTestServer test_server;
  ASSERT_TRUE(test_server.Start());

  // Set up a cookie.
  {
    TestNetworkDelegate network_delegate;
    default_context_.set_network_delegate(&network_delegate);
    TestDelegate d;
    scoped_ptr<URLRequest> req(default_context_.CreateRequest(
        test_server.GetURL("set-cookie?CookieToNotUpdate=2"), DEFAULT_PRIORITY,
        &d));
    req->Start();
    base::RunLoop().Run();

    EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
    EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
    EXPECT_EQ(1, network_delegate.set_cookie_count());
  }

  // Try to set-up another cookie and update the previous cookie.
  {
    TestNetworkDelegate network_delegate;
    default_context_.set_network_delegate(&network_delegate);
    TestDelegate d;
    scoped_ptr<URLRequest> req(default_context_.CreateRequest(
        test_server.GetURL("set-cookie?CookieToNotSave=1&CookieToNotUpdate=1"),
        DEFAULT_PRIORITY, &d));
    req->SetLoadFlags(LOAD_DO_NOT_SAVE_COOKIES);
    req->Start();

    base::RunLoop().Run();

    // LOAD_DO_NOT_SAVE_COOKIES does not trigger OnSetCookie.
    EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
    EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
    EXPECT_EQ(0, network_delegate.set_cookie_count());
  }

  // Verify the cookies weren't saved or updated.
  {
    TestNetworkDelegate network_delegate;
    default_context_.set_network_delegate(&network_delegate);
    TestDelegate d;
    scoped_ptr<URLRequest> req(default_context_.CreateRequest(
        test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d));
    req->Start();
    base::RunLoop().Run();

    EXPECT_TRUE(d.data_received().find("CookieToNotSave=1")
                == std::string::npos);
    EXPECT_TRUE(d.data_received().find("CookieToNotUpdate=2")
                != std::string::npos);

    EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
    EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
    EXPECT_EQ(0, network_delegate.set_cookie_count());
  }
}

TEST_F(URLRequestTest, DoNotSendCookies_ViaPolicy) {
  LocalHttpTestServer test_server;
  ASSERT_TRUE(test_server.Start());

  // Set up a cookie.
  {
    TestNetworkDelegate network_delegate;
    default_context_.set_network_delegate(&network_delegate);
    TestDelegate d;
    scoped_ptr<URLRequest> req(default_context_.CreateRequest(
        test_server.GetURL("set-cookie?CookieToNotSend=1"), DEFAULT_PRIORITY,
        &d));
    req->Start();
    base::RunLoop().Run();

    EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
    EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
  }

  // Verify that the cookie is set.
  {
    TestNetworkDelegate network_delegate;
    default_context_.set_network_delegate(&network_delegate);
    TestDelegate d;
    scoped_ptr<URLRequest> req(default_context_.CreateRequest(
        test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d));
    req->Start();
    base::RunLoop().Run();

    EXPECT_TRUE(d.data_received().find("CookieToNotSend=1")
                != std::string::npos);

    EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
    EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
  }

  // Verify that the cookie isn't sent.
  {
    TestNetworkDelegate network_delegate;
    default_context_.set_network_delegate(&network_delegate);
    TestDelegate d;
    network_delegate.set_cookie_options(TestNetworkDelegate::NO_GET_COOKIES);
    scoped_ptr<URLRequest> req(default_context_.CreateRequest(
        test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d));
    req->Start();
    base::RunLoop().Run();

    EXPECT_TRUE(d.data_received().find("Cookie: CookieToNotSend=1")
                == std::string::npos);

    EXPECT_EQ(1, network_delegate.blocked_get_cookies_count());
    EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
  }
}

TEST_F(URLRequestTest, DoNotSaveCookies_ViaPolicy) {
  LocalHttpTestServer test_server;
  ASSERT_TRUE(test_server.Start());

  // Set up a cookie.
  {
    TestNetworkDelegate network_delegate;
    default_context_.set_network_delegate(&network_delegate);
    TestDelegate d;
    scoped_ptr<URLRequest> req(default_context_.CreateRequest(
        test_server.GetURL("set-cookie?CookieToNotUpdate=2"), DEFAULT_PRIORITY,
        &d));
    req->Start();
    base::RunLoop().Run();

    EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
    EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
  }

  // Try to set-up another cookie and update the previous cookie.
  {
    TestNetworkDelegate network_delegate;
    default_context_.set_network_delegate(&network_delegate);
    TestDelegate d;
    network_delegate.set_cookie_options(TestNetworkDelegate::NO_SET_COOKIE);
    scoped_ptr<URLRequest> req(default_context_.CreateRequest(
        test_server.GetURL("set-cookie?CookieToNotSave=1&CookieToNotUpdate=1"),
        DEFAULT_PRIORITY, &d));
    req->Start();

    base::RunLoop().Run();

    EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
    EXPECT_EQ(2, network_delegate.blocked_set_cookie_count());
  }

  // Verify the cookies weren't saved or updated.
  {
    TestNetworkDelegate network_delegate;
    default_context_.set_network_delegate(&network_delegate);
    TestDelegate d;
    scoped_ptr<URLRequest> req(default_context_.CreateRequest(
        test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d));
    req->Start();
    base::RunLoop().Run();

    EXPECT_TRUE(d.data_received().find("CookieToNotSave=1")
                == std::string::npos);
    EXPECT_TRUE(d.data_received().find("CookieToNotUpdate=2")
                != std::string::npos);

    EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
    EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
  }
}

TEST_F(URLRequestTest, DoNotSaveEmptyCookies) {
  LocalHttpTestServer test_server;
  ASSERT_TRUE(test_server.Start());

  // Set up an empty cookie.
  {
    TestNetworkDelegate network_delegate;
    default_context_.set_network_delegate(&network_delegate);
    TestDelegate d;
    scoped_ptr<URLRequest> req(default_context_.CreateRequest(
        test_server.GetURL("set-cookie"), DEFAULT_PRIORITY, &d));
    req->Start();
    base::RunLoop().Run();

    EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
    EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
    EXPECT_EQ(0, network_delegate.set_cookie_count());
  }
}

TEST_F(URLRequestTest, DoNotSendCookies_ViaPolicy_Async) {
  LocalHttpTestServer test_server;
  ASSERT_TRUE(test_server.Start());

  // Set up a cookie.
  {
    TestNetworkDelegate network_delegate;
    default_context_.set_network_delegate(&network_delegate);
    TestDelegate d;
    scoped_ptr<URLRequest> req(default_context_.CreateRequest(
        test_server.GetURL("set-cookie?CookieToNotSend=1"), DEFAULT_PRIORITY,
        &d));
    req->Start();
    base::RunLoop().Run();

    EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
    EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
  }

  // Verify that the cookie is set.
  {
    TestNetworkDelegate network_delegate;
    default_context_.set_network_delegate(&network_delegate);
    TestDelegate d;
    scoped_ptr<URLRequest> req(default_context_.CreateRequest(
        test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d));
    req->Start();
    base::RunLoop().Run();

    EXPECT_TRUE(d.data_received().find("CookieToNotSend=1")
                != std::string::npos);

    EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
    EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
  }

  // Verify that the cookie isn't sent.
  {
    TestNetworkDelegate network_delegate;
    default_context_.set_network_delegate(&network_delegate);
    TestDelegate d;
    network_delegate.set_cookie_options(TestNetworkDelegate::NO_GET_COOKIES);
    scoped_ptr<URLRequest> req(default_context_.CreateRequest(
        test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d));
    req->Start();
    base::RunLoop().Run();

    EXPECT_TRUE(d.data_received().find("Cookie: CookieToNotSend=1")
                == std::string::npos);

    EXPECT_EQ(1, network_delegate.blocked_get_cookies_count());
    EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
  }
}

TEST_F(URLRequestTest, DoNotSaveCookies_ViaPolicy_Async) {
  LocalHttpTestServer test_server;
  ASSERT_TRUE(test_server.Start());

  // Set up a cookie.
  {
    TestNetworkDelegate network_delegate;
    default_context_.set_network_delegate(&network_delegate);
    TestDelegate d;
    scoped_ptr<URLRequest> req(default_context_.CreateRequest(
        test_server.GetURL("set-cookie?CookieToNotUpdate=2"), DEFAULT_PRIORITY,
        &d));
    req->Start();
    base::RunLoop().Run();

    EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
    EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
  }

  // Try to set-up another cookie and update the previous cookie.
  {
    TestNetworkDelegate network_delegate;
    default_context_.set_network_delegate(&network_delegate);
    TestDelegate d;
    network_delegate.set_cookie_options(TestNetworkDelegate::NO_SET_COOKIE);
    scoped_ptr<URLRequest> req(default_context_.CreateRequest(
        test_server.GetURL("set-cookie?CookieToNotSave=1&CookieToNotUpdate=1"),
        DEFAULT_PRIORITY, &d));
    req->Start();

    base::RunLoop().Run();

    EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
    EXPECT_EQ(2, network_delegate.blocked_set_cookie_count());
  }

  // Verify the cookies weren't saved or updated.
  {
    TestNetworkDelegate network_delegate;
    default_context_.set_network_delegate(&network_delegate);
    TestDelegate d;
    scoped_ptr<URLRequest> req(default_context_.CreateRequest(
        test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d));
    req->Start();
    base::RunLoop().Run();

    EXPECT_TRUE(d.data_received().find("CookieToNotSave=1")
                == std::string::npos);
    EXPECT_TRUE(d.data_received().find("CookieToNotUpdate=2")
                != std::string::npos);

    EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
    EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
  }
}

TEST_F(URLRequestTest, FirstPartyOnlyCookiesEnabled) {
  LocalHttpTestServer test_server;
  ASSERT_TRUE(test_server.Start());

  // Set up a 'First-Party-Only' cookie (on '127.0.0.1', as that's where
  // LocalHttpTestServer points).
  {
    TestNetworkDelegate network_delegate;
    network_delegate.set_first_party_only_cookies_enabled(true);
    default_context_.set_network_delegate(&network_delegate);

    TestDelegate d;
    scoped_ptr<URLRequest> req(default_context_.CreateRequest(
        test_server.GetURL(
            "set-cookie?FirstPartyCookieToSet=1;First-Party-Only"),
        DEFAULT_PRIORITY, &d));
    req->Start();
    base::RunLoop().Run();
    EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
    EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
    EXPECT_EQ(1, network_delegate.set_cookie_count());
  }

  // Verify that the cookie is sent for first-party requests.
  {
    TestNetworkDelegate network_delegate;
    network_delegate.set_first_party_only_cookies_enabled(true);
    default_context_.set_network_delegate(&network_delegate);
    TestDelegate d;
    scoped_ptr<URLRequest> req(default_context_.CreateRequest(
        test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d));
    req->set_first_party_for_cookies(test_server.GetURL(""));
    req->Start();
    base::RunLoop().Run();

    EXPECT_TRUE(d.data_received().find("FirstPartyCookieToSet=1") !=
                std::string::npos);
    EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
    EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
  }

  // Verify that the cookie is not-sent for non-first-party requests.
  {
    TestNetworkDelegate network_delegate;
    network_delegate.set_first_party_only_cookies_enabled(true);
    default_context_.set_network_delegate(&network_delegate);
    TestDelegate d;
    scoped_ptr<URLRequest> req(default_context_.CreateRequest(
        test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d));
    req->set_first_party_for_cookies(GURL("http://third-party.test/"));
    req->Start();
    base::RunLoop().Run();

    EXPECT_TRUE(d.data_received().find("FirstPartyCookieToSet=1") ==
                std::string::npos);
    EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
    EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
  }
}

TEST_F(URLRequestTest, FirstPartyOnlyCookiesDisabled) {
  LocalHttpTestServer test_server;
  ASSERT_TRUE(test_server.Start());

  // Set up a 'First-Party-Only' cookie (on '127.0.0.1', as that's where
  // LocalHttpTestServer points).
  {
    TestNetworkDelegate network_delegate;
    network_delegate.set_first_party_only_cookies_enabled(false);
    default_context_.set_network_delegate(&network_delegate);

    TestDelegate d;
    scoped_ptr<URLRequest> req(default_context_.CreateRequest(
        test_server.GetURL(
            "set-cookie?FirstPartyCookieToSet=1;First-Party-Only"),
        DEFAULT_PRIORITY, &d));
    req->Start();
    base::RunLoop().Run();
    EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
    EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
    EXPECT_EQ(1, network_delegate.set_cookie_count());
  }

  // Verify that the cookie is sent for first-party requests.
  {
    TestNetworkDelegate network_delegate;
    network_delegate.set_first_party_only_cookies_enabled(false);
    default_context_.set_network_delegate(&network_delegate);
    TestDelegate d;
    scoped_ptr<URLRequest> req(default_context_.CreateRequest(
        test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d));
    req->set_first_party_for_cookies(test_server.GetURL(""));
    req->Start();
    base::RunLoop().Run();

    EXPECT_TRUE(d.data_received().find("FirstPartyCookieToSet=1") !=
                std::string::npos);
    EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
    EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
  }

  // Verify that the cookie is also sent for non-first-party requests.
  {
    TestNetworkDelegate network_delegate;
    network_delegate.set_first_party_only_cookies_enabled(false);
    default_context_.set_network_delegate(&network_delegate);
    TestDelegate d;
    scoped_ptr<URLRequest> req(default_context_.CreateRequest(
        test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d));
    req->set_first_party_for_cookies(GURL("http://third-party.test/"));
    req->Start();
    base::RunLoop().Run();

    EXPECT_TRUE(d.data_received().find("FirstPartyCookieToSet=1") !=
                std::string::npos);
    EXPECT_EQ(0, network_delegate.blocked_get_cookies_count());
    EXPECT_EQ(0, network_delegate.blocked_set_cookie_count());
  }
}

// Tests that a request is cancelled while entering suspend mode. Uses mocks
// rather than a spawned test server because the connection used to talk to
// the test server is affected by entering suspend mode on Android.
TEST_F(URLRequestTest, CancelOnSuspend) {
  TestPowerMonitorSource* power_monitor_source = new TestPowerMonitorSource();
  base::PowerMonitor power_monitor(make_scoped_ptr(power_monitor_source));

  URLRequestFailedJob::AddUrlHandler();

  TestDelegate d;
  // Request that just hangs.
  GURL url(URLRequestFailedJob::GetMockHttpUrl(ERR_IO_PENDING));
  scoped_ptr<URLRequest> r(
      default_context_.CreateRequest(url, DEFAULT_PRIORITY, &d));
  r->Start();

  power_monitor_source->Suspend();
  // Wait for the suspend notification to cause the request to fail.
  base::RunLoop().Run();
  EXPECT_EQ(URLRequestStatus::CANCELED, r->status().status());
  EXPECT_TRUE(d.request_failed());
  EXPECT_EQ(1, default_network_delegate_.completed_requests());

  URLRequestFilter::GetInstance()->ClearHandlers();

  // Shouldn't be needed, but just in case.
  power_monitor_source->Resume();
}

// FixedDateNetworkDelegate swaps out the server's HTTP Date response header
// value for the |fixed_date| argument given to the constructor.
class FixedDateNetworkDelegate : public TestNetworkDelegate {
 public:
  explicit FixedDateNetworkDelegate(const std::string& fixed_date)
      : fixed_date_(fixed_date) {}
  ~FixedDateNetworkDelegate() override {}

  // NetworkDelegate implementation
  int OnHeadersReceived(
      URLRequest* request,
      const CompletionCallback& callback,
      const HttpResponseHeaders* original_response_headers,
      scoped_refptr<HttpResponseHeaders>* override_response_headers,
      GURL* allowed_unsafe_redirect_url) override;

 private:
  std::string fixed_date_;

  DISALLOW_COPY_AND_ASSIGN(FixedDateNetworkDelegate);
};

int FixedDateNetworkDelegate::OnHeadersReceived(
    URLRequest* request,
    const CompletionCallback& callback,
    const HttpResponseHeaders* original_response_headers,
    scoped_refptr<HttpResponseHeaders>* override_response_headers,
    GURL* allowed_unsafe_redirect_url) {
  HttpResponseHeaders* new_response_headers =
      new HttpResponseHeaders(original_response_headers->raw_headers());

  new_response_headers->RemoveHeader("Date");
  new_response_headers->AddHeader("Date: " + fixed_date_);

  *override_response_headers = new_response_headers;
  return TestNetworkDelegate::OnHeadersReceived(request,
                                                callback,
                                                original_response_headers,
                                                override_response_headers,
                                                allowed_unsafe_redirect_url);
}

// Test that cookie expiration times are adjusted for server/client clock
// skew and that we handle incorrect timezone specifier "UTC" in HTTP Date
// headers by defaulting to GMT. (crbug.com/135131)
TEST_F(URLRequestTest, AcceptClockSkewCookieWithWrongDateTimezone) {
  LocalHttpTestServer test_server;
  ASSERT_TRUE(test_server.Start());

  // Set up an expired cookie.
  {
    TestNetworkDelegate network_delegate;
    default_context_.set_network_delegate(&network_delegate);
    TestDelegate d;
    scoped_ptr<URLRequest> req(default_context_.CreateRequest(
        test_server.GetURL(
            "set-cookie?StillGood=1;expires=Mon,18-Apr-1977,22:50:13,GMT"),
        DEFAULT_PRIORITY, &d));
    req->Start();
    base::RunLoop().Run();
  }
  // Verify that the cookie is not set.
  {
    TestNetworkDelegate network_delegate;
    default_context_.set_network_delegate(&network_delegate);
    TestDelegate d;
    scoped_ptr<URLRequest> req(default_context_.CreateRequest(
        test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d));
    req->Start();
    base::RunLoop().Run();

    EXPECT_TRUE(d.data_received().find("StillGood=1") == std::string::npos);
  }
  // Set up a cookie with clock skew and "UTC" HTTP Date timezone specifier.
  {
    FixedDateNetworkDelegate network_delegate("18-Apr-1977 22:49:13 UTC");
    default_context_.set_network_delegate(&network_delegate);
    TestDelegate d;
    scoped_ptr<URLRequest> req(default_context_.CreateRequest(
        test_server.GetURL(
            "set-cookie?StillGood=1;expires=Mon,18-Apr-1977,22:50:13,GMT"),
        DEFAULT_PRIORITY, &d));
    req->Start();
    base::RunLoop().Run();
  }
  // Verify that the cookie is set.
  {
    TestNetworkDelegate network_delegate;
    default_context_.set_network_delegate(&network_delegate);
    TestDelegate d;
    scoped_ptr<URLRequest> req(default_context_.CreateRequest(
        test_server.GetURL("echoheader?Cookie"), DEFAULT_PRIORITY, &d));
    req->Start();
    base::RunLoop().Run();

    EXPECT_TRUE(d.data_received().find("StillGood=1") != std::string::npos);
  }
}


// Check that it is impossible to change the referrer in the extra headers of
// an URLRequest.
TEST_F(URLRequestTest, DoNotOverrideReferrer) {
  LocalHttpTestServer test_server;
  ASSERT_TRUE(test_server.Start());

  // If extra headers contain referer and the request contains a referer,
  // only the latter shall be respected.
  {
    TestDelegate d;
    scoped_ptr<URLRequest> req(default_context_.CreateRequest(
        test_server.GetURL("echoheader?Referer"), DEFAULT_PRIORITY, &d));
    req->SetReferrer("http://foo.com/");

    HttpRequestHeaders headers;
    headers.SetHeader(HttpRequestHeaders::kReferer, "http://bar.com/");
    req->SetExtraRequestHeaders(headers);

    req->Start();
    base::RunLoop().Run();

    EXPECT_EQ("http://foo.com/", d.data_received());
  }

  // If extra headers contain a referer but the request does not, no referer
  // shall be sent in the header.
  {
    TestDelegate d;
    scoped_ptr<URLRequest> req(default_context_.CreateRequest(
        test_server.GetURL("echoheader?Referer"), DEFAULT_PRIORITY, &d));

    HttpRequestHeaders headers;
    headers.SetHeader(HttpRequestHeaders::kReferer, "http://bar.com/");
    req->SetExtraRequestHeaders(headers);
    req->SetLoadFlags(LOAD_VALIDATE_CACHE);

    req->Start();
    base::RunLoop().Run();

    EXPECT_EQ("None", d.data_received());
  }
}

class URLRequestTestHTTP : public URLRequestTest {
 public:
  URLRequestTestHTTP() : test_server_(base::FilePath(kTestFilePath)) {}

 protected:
  // Requests |redirect_url|, which must return a HTTP 3xx redirect.
  // |request_method| is the method to use for the initial request.
  // |redirect_method| is the method that is expected to be used for the second
  // request, after redirection.
  // If |include_data| is true, data is uploaded with the request.  The
  // response body is expected to match it exactly, if and only if
  // |request_method| == |redirect_method|.
  void HTTPRedirectMethodTest(const GURL& redirect_url,
                              const std::string& request_method,
                              const std::string& redirect_method,
                              bool include_data) {
    static const char kData[] = "hello world";
    TestDelegate d;
    scoped_ptr<URLRequest> req(
        default_context_.CreateRequest(redirect_url, DEFAULT_PRIORITY, &d));
    req->set_method(request_method);
    if (include_data) {
      req->set_upload(CreateSimpleUploadData(kData));
      HttpRequestHeaders headers;
      headers.SetHeader(HttpRequestHeaders::kContentLength,
                        base::SizeTToString(arraysize(kData) - 1));
      req->SetExtraRequestHeaders(headers);
    }
    req->Start();
    base::RunLoop().Run();
    EXPECT_EQ(redirect_method, req->method());
    EXPECT_EQ(URLRequestStatus::SUCCESS, req->status().status());
    EXPECT_EQ(OK, req->status().error());
    if (include_data) {
      if (request_method == redirect_method) {
        EXPECT_EQ(kData, d.data_received());
      } else {
        EXPECT_NE(kData, d.data_received());
      }
    }
    if (HasFailure())
      LOG(WARNING) << "Request method was: " << request_method;
  }

  // Requests |redirect_url|, which must return a HTTP 3xx redirect.
  // |request_method| is the method to use for the initial request.
  // |redirect_method| is the method that is expected to be used for the second
  // request, after redirection.
  // |origin_value| is the expected value for the Origin header after
  // redirection. If empty, expects that there will be no Origin header.
  void HTTPRedirectOriginHeaderTest(const GURL& redirect_url,
                                    const std::string& request_method,
                                    const std::string& redirect_method,
                                    const std::string& origin_value) {
    TestDelegate d;
    scoped_ptr<URLRequest> req(
        default_context_.CreateRequest(redirect_url, DEFAULT_PRIORITY, &d));
    req->set_method(request_method);
    req->SetExtraRequestHeaderByName(HttpRequestHeaders::kOrigin,
                                     redirect_url.GetOrigin().spec(), false);
    req->Start();

    base::RunLoop().Run();

    EXPECT_EQ(redirect_method, req->method());
    // Note that there is no check for request success here because, for
    // purposes of testing, the request very well may fail. For example, if the
    // test redirects to an HTTPS server from an HTTP origin, thus it is cross
    // origin, there is not an HTTPS server in this unit test framework, so the
    // request would fail. However, that's fine, as long as the request headers
    // are in order and pass the checks below.
    if (origin_value.empty()) {
      EXPECT_FALSE(
          req->extra_request_headers().HasHeader(HttpRequestHeaders::kOrigin));
    } else {
      std::string origin_header;
      EXPECT_TRUE(req->extra_request_headers().GetHeader(
          HttpRequestHeaders::kOrigin, &origin_header));
      EXPECT_EQ(origin_value, origin_header);
    }
  }

  void HTTPUploadDataOperationTest(const std::string& method) {
    const int kMsgSize = 20000;  // multiple of 10
    const int kIterations = 50;
    char* uploadBytes = new char[kMsgSize+1];
    char* ptr = uploadBytes;
    char marker = 'a';
    for (int idx = 0; idx < kMsgSize/10; idx++) {
      memcpy(ptr, "----------", 10);
      ptr += 10;
      if (idx % 100 == 0) {
        ptr--;
        *ptr++ = marker;
        if (++marker > 'z')
          marker = 'a';
      }
    }
    uploadBytes[kMsgSize] = '\0';

    for (int i = 0; i < kIterations; ++i) {
      TestDelegate d;
      scoped_ptr<URLRequest> r(default_context_.CreateRequest(
          test_server_.GetURL("echo"), DEFAULT_PRIORITY, &d));
      r->set_method(method.c_str());

      r->set_upload(CreateSimpleUploadData(uploadBytes));

      r->Start();
      EXPECT_TRUE(r->is_pending());

      base::RunLoop().Run();

      ASSERT_EQ(1, d.response_started_count())
          << "request failed: " << r->status().status()
          << ", os error: " << r->status().error();

      EXPECT_FALSE(d.received_data_before_response());
      EXPECT_EQ(uploadBytes, d.data_received());
    }
    delete[] uploadBytes;
  }

  void AddChunksToUpload(URLRequest* r) {
    r->AppendChunkToUpload("a", 1, false);
    r->AppendChunkToUpload("bcd", 3, false);
    r->AppendChunkToUpload("this is a longer chunk than before.", 35, false);
    r->AppendChunkToUpload("\r\n\r\n", 4, false);
    r->AppendChunkToUpload("0", 1, false);
    r->AppendChunkToUpload("2323", 4, true);
  }

  void VerifyReceivedDataMatchesChunks(URLRequest* r, TestDelegate* d) {
    // This should match the chunks sent by AddChunksToUpload().
    const std::string expected_data =
        "abcdthis is a longer chunk than before.\r\n\r\n02323";

    ASSERT_EQ(1, d->response_started_count())
        << "request failed: " << r->status().status()
        << ", os error: " << r->status().error();

    EXPECT_FALSE(d->received_data_before_response());

    EXPECT_EQ(expected_data.size(), static_cast<size_t>(d->bytes_received()));
    EXPECT_EQ(expected_data, d->data_received());
  }

  bool DoManyCookiesRequest(int num_cookies) {
    TestDelegate d;
    scoped_ptr<URLRequest> r(default_context_.CreateRequest(
        test_server_.GetURL("set-many-cookies?" +
                            base::IntToString(num_cookies)),
        DEFAULT_PRIORITY, &d));

    r->Start();
    EXPECT_TRUE(r->is_pending());

    base::RunLoop().Run();

    bool is_success = r->status().is_success();

    if (!is_success) {
      EXPECT_TRUE(r->status().error() == ERR_RESPONSE_HEADERS_TOO_BIG);
      // The test server appears to be unable to handle subsequent requests
      // after this error is triggered. Force it to restart.
      EXPECT_TRUE(test_server_.Stop());
      EXPECT_TRUE(test_server_.Start());
    }

    return is_success;
  }

  LocalHttpTestServer* test_server() {
    return &test_server_;
  }

 protected:
  LocalHttpTestServer test_server_;
};

// In this unit test, we're using the HTTPTestServer as a proxy server and
// issuing a CONNECT request with the magic host name "www.redirect.com".
// The HTTPTestServer will return a 302 response, which we should not
// follow.
TEST_F(URLRequestTestHTTP, ProxyTunnelRedirectTest) {
  ASSERT_TRUE(test_server_.Start());

  TestNetworkDelegate network_delegate;  // Must outlive URLRequest.
  TestURLRequestContextWithProxy context(
      test_server_.host_port_pair().ToString(), &network_delegate);

  TestDelegate d;
  {
    scoped_ptr<URLRequest> r(context.CreateRequest(
        GURL("https://www.redirect.com/"), DEFAULT_PRIORITY, &d));
    r->Start();
    EXPECT_TRUE(r->is_pending());

    base::RunLoop().Run();

    EXPECT_EQ(URLRequestStatus::FAILED, r->status().status());
    // The proxy server is not set before failure.
    EXPECT_TRUE(r->proxy_server().IsEmpty());
    EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, r->status().error());
    EXPECT_EQ(1, d.response_started_count());
    // We should not have followed the redirect.
    EXPECT_EQ(0, d.received_redirect_count());
  }
}

// This is the same as the previous test, but checks that the network delegate
// registers the error.
TEST_F(URLRequestTestHTTP, NetworkDelegateTunnelConnectionFailed) {
  ASSERT_TRUE(test_server_.Start());

  TestNetworkDelegate network_delegate;  // Must outlive URLRequest.
  TestURLRequestContextWithProxy context(
      test_server_.host_port_pair().ToString(), &network_delegate);

  TestDelegate d;
  {
    scoped_ptr<URLRequest> r(context.CreateRequest(
        GURL("https://www.redirect.com/"), DEFAULT_PRIORITY, &d));
    r->Start();
    EXPECT_TRUE(r->is_pending());

    base::RunLoop().Run();

    EXPECT_EQ(URLRequestStatus::FAILED, r->status().status());
    // The proxy server is not set before failure.
    EXPECT_TRUE(r->proxy_server().IsEmpty());
    EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, r->status().error());
    EXPECT_EQ(1, d.response_started_count());
    // We should not have followed the redirect.
    EXPECT_EQ(0, d.received_redirect_count());

    EXPECT_EQ(1, network_delegate.error_count());
    EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, network_delegate.last_error());
  }
}

// Tests that we can block and asynchronously return OK in various stages.
TEST_F(URLRequestTestHTTP, NetworkDelegateBlockAsynchronously) {
  static const BlockingNetworkDelegate::Stage blocking_stages[] = {
    BlockingNetworkDelegate::ON_BEFORE_URL_REQUEST,
    BlockingNetworkDelegate::ON_BEFORE_SEND_HEADERS,
    BlockingNetworkDelegate::ON_HEADERS_RECEIVED
  };
  static const size_t blocking_stages_length = arraysize(blocking_stages);

  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  BlockingNetworkDelegate network_delegate(
      BlockingNetworkDelegate::USER_CALLBACK);
  network_delegate.set_block_on(
      BlockingNetworkDelegate::ON_BEFORE_URL_REQUEST |
      BlockingNetworkDelegate::ON_BEFORE_SEND_HEADERS |
      BlockingNetworkDelegate::ON_HEADERS_RECEIVED);

  TestURLRequestContext context(true);
  context.set_network_delegate(&network_delegate);
  context.Init();

  {
    scoped_ptr<URLRequest> r(context.CreateRequest(
        test_server_.GetURL("empty.html"), DEFAULT_PRIORITY, &d));

    r->Start();
    for (size_t i = 0; i < blocking_stages_length; ++i) {
      base::RunLoop().Run();
      EXPECT_EQ(blocking_stages[i],
                network_delegate.stage_blocked_for_callback());
      network_delegate.DoCallback(OK);
    }
    base::RunLoop().Run();
    EXPECT_EQ(200, r->GetResponseCode());
    EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
    EXPECT_EQ(1, network_delegate.created_requests());
    EXPECT_EQ(0, network_delegate.destroyed_requests());
  }
  EXPECT_EQ(1, network_delegate.destroyed_requests());
}

// Tests that the network delegate can block and cancel a request.
TEST_F(URLRequestTestHTTP, NetworkDelegateCancelRequest) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  BlockingNetworkDelegate network_delegate(
      BlockingNetworkDelegate::AUTO_CALLBACK);
  network_delegate.set_block_on(BlockingNetworkDelegate::ON_BEFORE_URL_REQUEST);
  network_delegate.set_retval(ERR_EMPTY_RESPONSE);

  TestURLRequestContextWithProxy context(
      test_server_.host_port_pair().ToString(), &network_delegate);

  {
    scoped_ptr<URLRequest> r(context.CreateRequest(
        test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d));

    r->Start();
    base::RunLoop().Run();

    EXPECT_EQ(URLRequestStatus::FAILED, r->status().status());
    // The proxy server is not set before cancellation.
    EXPECT_TRUE(r->proxy_server().IsEmpty());
    EXPECT_EQ(ERR_EMPTY_RESPONSE, r->status().error());
    EXPECT_EQ(1, network_delegate.created_requests());
    EXPECT_EQ(0, network_delegate.destroyed_requests());
  }
  EXPECT_EQ(1, network_delegate.destroyed_requests());
}

// Helper function for NetworkDelegateCancelRequestAsynchronously and
// NetworkDelegateCancelRequestSynchronously. Sets up a blocking network
// delegate operating in |block_mode| and a request for |url|. It blocks the
// request in |stage| and cancels it with ERR_BLOCKED_BY_CLIENT.
void NetworkDelegateCancelRequest(BlockingNetworkDelegate::BlockMode block_mode,
                                  BlockingNetworkDelegate::Stage stage,
                                  const GURL& url) {
  TestDelegate d;
  BlockingNetworkDelegate network_delegate(block_mode);
  network_delegate.set_retval(ERR_BLOCKED_BY_CLIENT);
  network_delegate.set_block_on(stage);

  TestURLRequestContext context(true);
  context.set_network_delegate(&network_delegate);
  context.Init();

  {
    scoped_ptr<URLRequest> r(context.CreateRequest(url, DEFAULT_PRIORITY, &d));

    r->Start();
    base::RunLoop().Run();

    EXPECT_EQ(URLRequestStatus::FAILED, r->status().status());
    // The proxy server is not set before cancellation.
    EXPECT_TRUE(r->proxy_server().IsEmpty());
    EXPECT_EQ(ERR_BLOCKED_BY_CLIENT, r->status().error());
    EXPECT_EQ(1, network_delegate.created_requests());
    EXPECT_EQ(0, network_delegate.destroyed_requests());
  }
  EXPECT_EQ(1, network_delegate.destroyed_requests());
}

// The following 3 tests check that the network delegate can cancel a request
// synchronously in various stages of the request.
TEST_F(URLRequestTestHTTP, NetworkDelegateCancelRequestSynchronously1) {
  ASSERT_TRUE(test_server_.Start());
  NetworkDelegateCancelRequest(BlockingNetworkDelegate::SYNCHRONOUS,
                               BlockingNetworkDelegate::ON_BEFORE_URL_REQUEST,
                               test_server_.GetURL(std::string()));
}

TEST_F(URLRequestTestHTTP, NetworkDelegateCancelRequestSynchronously2) {
  ASSERT_TRUE(test_server_.Start());
  NetworkDelegateCancelRequest(BlockingNetworkDelegate::SYNCHRONOUS,
                               BlockingNetworkDelegate::ON_BEFORE_SEND_HEADERS,
                               test_server_.GetURL(std::string()));
}

TEST_F(URLRequestTestHTTP, NetworkDelegateCancelRequestSynchronously3) {
  ASSERT_TRUE(test_server_.Start());
  NetworkDelegateCancelRequest(BlockingNetworkDelegate::SYNCHRONOUS,
                               BlockingNetworkDelegate::ON_HEADERS_RECEIVED,
                               test_server_.GetURL(std::string()));
}

// The following 3 tests check that the network delegate can cancel a request
// asynchronously in various stages of the request.
TEST_F(URLRequestTestHTTP, NetworkDelegateCancelRequestAsynchronously1) {
  ASSERT_TRUE(test_server_.Start());
  NetworkDelegateCancelRequest(BlockingNetworkDelegate::AUTO_CALLBACK,
                               BlockingNetworkDelegate::ON_BEFORE_URL_REQUEST,
                               test_server_.GetURL(std::string()));
}

TEST_F(URLRequestTestHTTP, NetworkDelegateCancelRequestAsynchronously2) {
  ASSERT_TRUE(test_server_.Start());
  NetworkDelegateCancelRequest(BlockingNetworkDelegate::AUTO_CALLBACK,
                               BlockingNetworkDelegate::ON_BEFORE_SEND_HEADERS,
                               test_server_.GetURL(std::string()));
}

TEST_F(URLRequestTestHTTP, NetworkDelegateCancelRequestAsynchronously3) {
  ASSERT_TRUE(test_server_.Start());
  NetworkDelegateCancelRequest(BlockingNetworkDelegate::AUTO_CALLBACK,
                               BlockingNetworkDelegate::ON_HEADERS_RECEIVED,
                               test_server_.GetURL(std::string()));
}

// Tests that the network delegate can block and redirect a request to a new
// URL.
TEST_F(URLRequestTestHTTP, NetworkDelegateRedirectRequest) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  BlockingNetworkDelegate network_delegate(
      BlockingNetworkDelegate::AUTO_CALLBACK);
  network_delegate.set_block_on(BlockingNetworkDelegate::ON_BEFORE_URL_REQUEST);
  GURL redirect_url(test_server_.GetURL("simple.html"));
  network_delegate.set_redirect_url(redirect_url);

  TestURLRequestContextWithProxy context(
      test_server_.host_port_pair().ToString(), &network_delegate);

  {
    GURL original_url(test_server_.GetURL("empty.html"));
    scoped_ptr<URLRequest> r(
        context.CreateRequest(original_url, DEFAULT_PRIORITY, &d));

    // Quit after hitting the redirect, so can check the headers.
    d.set_quit_on_redirect(true);
    r->Start();
    base::RunLoop().Run();

    // Check headers from URLRequestJob.
    EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
    EXPECT_EQ(307, r->GetResponseCode());
    EXPECT_EQ(307, r->response_headers()->response_code());
    std::string location;
    ASSERT_TRUE(r->response_headers()->EnumerateHeader(NULL, "Location",
                                                       &location));
    EXPECT_EQ(redirect_url, GURL(location));

    // Let the request finish.
    r->FollowDeferredRedirect();
    base::RunLoop().Run();
    EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
    EXPECT_TRUE(r->proxy_server().Equals(test_server_.host_port_pair()));
    EXPECT_EQ(
        1, network_delegate.observed_before_proxy_headers_sent_callbacks());
    EXPECT_TRUE(
        network_delegate.last_observed_proxy().Equals(
            test_server_.host_port_pair()));

    EXPECT_EQ(0, r->status().error());
    EXPECT_EQ(redirect_url, r->url());
    EXPECT_EQ(original_url, r->original_url());
    EXPECT_EQ(2U, r->url_chain().size());
    EXPECT_EQ(1, network_delegate.created_requests());
    EXPECT_EQ(0, network_delegate.destroyed_requests());
  }
  EXPECT_EQ(1, network_delegate.destroyed_requests());
}

// Tests that the network delegate can block and redirect a request to a new
// URL by setting a redirect_url and returning in OnBeforeURLRequest directly.
TEST_F(URLRequestTestHTTP, NetworkDelegateRedirectRequestSynchronously) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  BlockingNetworkDelegate network_delegate(
      BlockingNetworkDelegate::SYNCHRONOUS);
  GURL redirect_url(test_server_.GetURL("simple.html"));
  network_delegate.set_redirect_url(redirect_url);

  TestURLRequestContextWithProxy context(
      test_server_.host_port_pair().ToString(), &network_delegate);

  {
    GURL original_url(test_server_.GetURL("empty.html"));
    scoped_ptr<URLRequest> r(
        context.CreateRequest(original_url, DEFAULT_PRIORITY, &d));

    // Quit after hitting the redirect, so can check the headers.
    d.set_quit_on_redirect(true);
    r->Start();
    base::RunLoop().Run();

    // Check headers from URLRequestJob.
    EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
    EXPECT_EQ(307, r->GetResponseCode());
    EXPECT_EQ(307, r->response_headers()->response_code());
    std::string location;
    ASSERT_TRUE(r->response_headers()->EnumerateHeader(NULL, "Location",
                                                       &location));
    EXPECT_EQ(redirect_url, GURL(location));

    // Let the request finish.
    r->FollowDeferredRedirect();
    base::RunLoop().Run();

    EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
    EXPECT_TRUE(r->proxy_server().Equals(test_server_.host_port_pair()));
    EXPECT_EQ(
        1, network_delegate.observed_before_proxy_headers_sent_callbacks());
    EXPECT_TRUE(
        network_delegate.last_observed_proxy().Equals(
            test_server_.host_port_pair()));
    EXPECT_EQ(0, r->status().error());
    EXPECT_EQ(redirect_url, r->url());
    EXPECT_EQ(original_url, r->original_url());
    EXPECT_EQ(2U, r->url_chain().size());
    EXPECT_EQ(1, network_delegate.created_requests());
    EXPECT_EQ(0, network_delegate.destroyed_requests());
  }
  EXPECT_EQ(1, network_delegate.destroyed_requests());
}

// Tests that redirects caused by the network delegate preserve POST data.
TEST_F(URLRequestTestHTTP, NetworkDelegateRedirectRequestPost) {
  ASSERT_TRUE(test_server_.Start());

  const char kData[] = "hello world";

  TestDelegate d;
  BlockingNetworkDelegate network_delegate(
      BlockingNetworkDelegate::AUTO_CALLBACK);
  network_delegate.set_block_on(BlockingNetworkDelegate::ON_BEFORE_URL_REQUEST);
  GURL redirect_url(test_server_.GetURL("echo"));
  network_delegate.set_redirect_url(redirect_url);

  TestURLRequestContext context(true);
  context.set_network_delegate(&network_delegate);
  context.Init();

  {
    GURL original_url(test_server_.GetURL("empty.html"));
    scoped_ptr<URLRequest> r(
        context.CreateRequest(original_url, DEFAULT_PRIORITY, &d));
    r->set_method("POST");
    r->set_upload(CreateSimpleUploadData(kData));
    HttpRequestHeaders headers;
    headers.SetHeader(HttpRequestHeaders::kContentLength,
                      base::SizeTToString(arraysize(kData) - 1));
    r->SetExtraRequestHeaders(headers);

    // Quit after hitting the redirect, so can check the headers.
    d.set_quit_on_redirect(true);
    r->Start();
    base::RunLoop().Run();

    // Check headers from URLRequestJob.
    EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
    EXPECT_EQ(307, r->GetResponseCode());
    EXPECT_EQ(307, r->response_headers()->response_code());
    std::string location;
    ASSERT_TRUE(r->response_headers()->EnumerateHeader(NULL, "Location",
                                                       &location));
    EXPECT_EQ(redirect_url, GURL(location));

    // Let the request finish.
    r->FollowDeferredRedirect();
    base::RunLoop().Run();

    EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
    EXPECT_EQ(0, r->status().error());
    EXPECT_EQ(redirect_url, r->url());
    EXPECT_EQ(original_url, r->original_url());
    EXPECT_EQ(2U, r->url_chain().size());
    EXPECT_EQ(1, network_delegate.created_requests());
    EXPECT_EQ(0, network_delegate.destroyed_requests());
    EXPECT_EQ("POST", r->method());
    EXPECT_EQ(kData, d.data_received());
  }
  EXPECT_EQ(1, network_delegate.destroyed_requests());
}

// Tests that the network delegate can block and redirect a request to a new
// URL during OnHeadersReceived.
TEST_F(URLRequestTestHTTP, NetworkDelegateRedirectRequestOnHeadersReceived) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  BlockingNetworkDelegate network_delegate(
      BlockingNetworkDelegate::AUTO_CALLBACK);
  network_delegate.set_block_on(BlockingNetworkDelegate::ON_HEADERS_RECEIVED);
  GURL redirect_url(test_server_.GetURL("simple.html"));
  network_delegate.set_redirect_on_headers_received_url(redirect_url);

  TestURLRequestContextWithProxy context(
      test_server_.host_port_pair().ToString(), &network_delegate);

  {
    GURL original_url(test_server_.GetURL("empty.html"));
    scoped_ptr<URLRequest> r(
        context.CreateRequest(original_url, DEFAULT_PRIORITY, &d));

    r->Start();
    base::RunLoop().Run();

    EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
    EXPECT_TRUE(r->proxy_server().Equals(test_server_.host_port_pair()));
    EXPECT_EQ(
        2, network_delegate.observed_before_proxy_headers_sent_callbacks());
    EXPECT_TRUE(
        network_delegate.last_observed_proxy().Equals(
            test_server_.host_port_pair()));

    EXPECT_EQ(OK, r->status().error());
    EXPECT_EQ(redirect_url, r->url());
    EXPECT_EQ(original_url, r->original_url());
    EXPECT_EQ(2U, r->url_chain().size());
    EXPECT_EQ(2, network_delegate.created_requests());
    EXPECT_EQ(0, network_delegate.destroyed_requests());
  }
  EXPECT_EQ(1, network_delegate.destroyed_requests());
}

// Tests that the network delegate can synchronously complete OnAuthRequired
// by taking no action. This indicates that the NetworkDelegate does not want to
// handle the challenge, and is passing the buck along to the
// URLRequest::Delegate.
TEST_F(URLRequestTestHTTP, NetworkDelegateOnAuthRequiredSyncNoAction) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  BlockingNetworkDelegate network_delegate(
      BlockingNetworkDelegate::SYNCHRONOUS);

  TestURLRequestContext context(true);
  context.set_network_delegate(&network_delegate);
  context.Init();

  d.set_credentials(AuthCredentials(kUser, kSecret));

  {
    GURL url(test_server_.GetURL("auth-basic"));
    scoped_ptr<URLRequest> r(context.CreateRequest(url, DEFAULT_PRIORITY, &d));
    r->Start();

    base::RunLoop().Run();

    EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
    EXPECT_EQ(0, r->status().error());
    EXPECT_EQ(200, r->GetResponseCode());
    EXPECT_TRUE(d.auth_required_called());
    EXPECT_EQ(1, network_delegate.created_requests());
    EXPECT_EQ(0, network_delegate.destroyed_requests());
  }
  EXPECT_EQ(1, network_delegate.destroyed_requests());
}

TEST_F(URLRequestTestHTTP,
    NetworkDelegateOnAuthRequiredSyncNoAction_GetFullRequestHeaders) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  BlockingNetworkDelegate network_delegate(
      BlockingNetworkDelegate::SYNCHRONOUS);

  TestURLRequestContext context(true);
  context.set_network_delegate(&network_delegate);
  context.Init();

  d.set_credentials(AuthCredentials(kUser, kSecret));

  {
    GURL url(test_server_.GetURL("auth-basic"));
    scoped_ptr<URLRequest> r(context.CreateRequest(url, DEFAULT_PRIORITY, &d));
    r->Start();

    {
      HttpRequestHeaders headers;
      EXPECT_TRUE(r->GetFullRequestHeaders(&headers));
      EXPECT_FALSE(headers.HasHeader("Authorization"));
    }

    base::RunLoop().Run();

    EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
    EXPECT_EQ(0, r->status().error());
    EXPECT_EQ(200, r->GetResponseCode());
    EXPECT_TRUE(d.auth_required_called());
    EXPECT_EQ(1, network_delegate.created_requests());
    EXPECT_EQ(0, network_delegate.destroyed_requests());
  }
  EXPECT_EQ(1, network_delegate.destroyed_requests());
}

// Tests that the network delegate can synchronously complete OnAuthRequired
// by setting credentials.
TEST_F(URLRequestTestHTTP, NetworkDelegateOnAuthRequiredSyncSetAuth) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  BlockingNetworkDelegate network_delegate(
      BlockingNetworkDelegate::SYNCHRONOUS);
  network_delegate.set_block_on(BlockingNetworkDelegate::ON_AUTH_REQUIRED);
  network_delegate.set_auth_retval(
      NetworkDelegate::AUTH_REQUIRED_RESPONSE_SET_AUTH);

  network_delegate.set_auth_credentials(AuthCredentials(kUser, kSecret));

  TestURLRequestContext context(true);
  context.set_network_delegate(&network_delegate);
  context.Init();

  {
    GURL url(test_server_.GetURL("auth-basic"));
    scoped_ptr<URLRequest> r(context.CreateRequest(url, DEFAULT_PRIORITY, &d));
    r->Start();
    base::RunLoop().Run();

    EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
    EXPECT_EQ(0, r->status().error());
    EXPECT_EQ(200, r->GetResponseCode());
    EXPECT_FALSE(d.auth_required_called());
    EXPECT_EQ(1, network_delegate.created_requests());
    EXPECT_EQ(0, network_delegate.destroyed_requests());
  }
  EXPECT_EQ(1, network_delegate.destroyed_requests());
}

// Same as above, but also tests that GetFullRequestHeaders returns the proper
// headers (for the first or second request) when called at the proper times.
TEST_F(URLRequestTestHTTP,
    NetworkDelegateOnAuthRequiredSyncSetAuth_GetFullRequestHeaders) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  BlockingNetworkDelegate network_delegate(
      BlockingNetworkDelegate::SYNCHRONOUS);
  network_delegate.set_block_on(BlockingNetworkDelegate::ON_AUTH_REQUIRED);
  network_delegate.set_auth_retval(
      NetworkDelegate::AUTH_REQUIRED_RESPONSE_SET_AUTH);

  network_delegate.set_auth_credentials(AuthCredentials(kUser, kSecret));

  TestURLRequestContext context(true);
  context.set_network_delegate(&network_delegate);
  context.Init();

  {
    GURL url(test_server_.GetURL("auth-basic"));
    scoped_ptr<URLRequest> r(context.CreateRequest(url, DEFAULT_PRIORITY, &d));
    r->Start();
    base::RunLoop().Run();

    EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
    EXPECT_EQ(0, r->status().error());
    EXPECT_EQ(200, r->GetResponseCode());
    EXPECT_FALSE(d.auth_required_called());
    EXPECT_EQ(1, network_delegate.created_requests());
    EXPECT_EQ(0, network_delegate.destroyed_requests());

    {
      HttpRequestHeaders headers;
      EXPECT_TRUE(r->GetFullRequestHeaders(&headers));
      EXPECT_TRUE(headers.HasHeader("Authorization"));
    }
  }
  EXPECT_EQ(1, network_delegate.destroyed_requests());
}

// Tests that the network delegate can synchronously complete OnAuthRequired
// by cancelling authentication.
TEST_F(URLRequestTestHTTP, NetworkDelegateOnAuthRequiredSyncCancel) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  BlockingNetworkDelegate network_delegate(
      BlockingNetworkDelegate::SYNCHRONOUS);
  network_delegate.set_block_on(BlockingNetworkDelegate::ON_AUTH_REQUIRED);
  network_delegate.set_auth_retval(
      NetworkDelegate::AUTH_REQUIRED_RESPONSE_CANCEL_AUTH);

  TestURLRequestContext context(true);
  context.set_network_delegate(&network_delegate);
  context.Init();

  {
    GURL url(test_server_.GetURL("auth-basic"));
    scoped_ptr<URLRequest> r(context.CreateRequest(url, DEFAULT_PRIORITY, &d));
    r->Start();
    base::RunLoop().Run();

    EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
    EXPECT_EQ(OK, r->status().error());
    EXPECT_EQ(401, r->GetResponseCode());
    EXPECT_FALSE(d.auth_required_called());
    EXPECT_EQ(1, network_delegate.created_requests());
    EXPECT_EQ(0, network_delegate.destroyed_requests());
  }
  EXPECT_EQ(1, network_delegate.destroyed_requests());
}

// Tests that the network delegate can asynchronously complete OnAuthRequired
// by taking no action. This indicates that the NetworkDelegate does not want
// to handle the challenge, and is passing the buck along to the
// URLRequest::Delegate.
TEST_F(URLRequestTestHTTP, NetworkDelegateOnAuthRequiredAsyncNoAction) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  BlockingNetworkDelegate network_delegate(
      BlockingNetworkDelegate::AUTO_CALLBACK);
  network_delegate.set_block_on(BlockingNetworkDelegate::ON_AUTH_REQUIRED);

  TestURLRequestContext context(true);
  context.set_network_delegate(&network_delegate);
  context.Init();

  d.set_credentials(AuthCredentials(kUser, kSecret));

  {
    GURL url(test_server_.GetURL("auth-basic"));
    scoped_ptr<URLRequest> r(context.CreateRequest(url, DEFAULT_PRIORITY, &d));
    r->Start();
    base::RunLoop().Run();

    EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
    EXPECT_EQ(0, r->status().error());
    EXPECT_EQ(200, r->GetResponseCode());
    EXPECT_TRUE(d.auth_required_called());
    EXPECT_EQ(1, network_delegate.created_requests());
    EXPECT_EQ(0, network_delegate.destroyed_requests());
  }
  EXPECT_EQ(1, network_delegate.destroyed_requests());
}

// Tests that the network delegate can asynchronously complete OnAuthRequired
// by setting credentials.
TEST_F(URLRequestTestHTTP, NetworkDelegateOnAuthRequiredAsyncSetAuth) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  BlockingNetworkDelegate network_delegate(
      BlockingNetworkDelegate::AUTO_CALLBACK);
  network_delegate.set_block_on(BlockingNetworkDelegate::ON_AUTH_REQUIRED);
  network_delegate.set_auth_retval(
      NetworkDelegate::AUTH_REQUIRED_RESPONSE_SET_AUTH);

  AuthCredentials auth_credentials(kUser, kSecret);
  network_delegate.set_auth_credentials(auth_credentials);

  TestURLRequestContext context(true);
  context.set_network_delegate(&network_delegate);
  context.Init();

  {
    GURL url(test_server_.GetURL("auth-basic"));
    scoped_ptr<URLRequest> r(context.CreateRequest(url, DEFAULT_PRIORITY, &d));
    r->Start();
    base::RunLoop().Run();

    EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
    EXPECT_EQ(0, r->status().error());

    EXPECT_EQ(200, r->GetResponseCode());
    EXPECT_FALSE(d.auth_required_called());
    EXPECT_EQ(1, network_delegate.created_requests());
    EXPECT_EQ(0, network_delegate.destroyed_requests());
  }
  EXPECT_EQ(1, network_delegate.destroyed_requests());
}

// Tests that the network delegate can asynchronously complete OnAuthRequired
// by cancelling authentication.
TEST_F(URLRequestTestHTTP, NetworkDelegateOnAuthRequiredAsyncCancel) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  BlockingNetworkDelegate network_delegate(
      BlockingNetworkDelegate::AUTO_CALLBACK);
  network_delegate.set_block_on(BlockingNetworkDelegate::ON_AUTH_REQUIRED);
  network_delegate.set_auth_retval(
      NetworkDelegate::AUTH_REQUIRED_RESPONSE_CANCEL_AUTH);

  TestURLRequestContext context(true);
  context.set_network_delegate(&network_delegate);
  context.Init();

  {
    GURL url(test_server_.GetURL("auth-basic"));
    scoped_ptr<URLRequest> r(context.CreateRequest(url, DEFAULT_PRIORITY, &d));
    r->Start();
    base::RunLoop().Run();

    EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
    EXPECT_EQ(OK, r->status().error());
    EXPECT_EQ(401, r->GetResponseCode());
    EXPECT_FALSE(d.auth_required_called());
    EXPECT_EQ(1, network_delegate.created_requests());
    EXPECT_EQ(0, network_delegate.destroyed_requests());
  }
  EXPECT_EQ(1, network_delegate.destroyed_requests());
}

// Tests that we can handle when a network request was canceled while we were
// waiting for the network delegate.
// Part 1: Request is cancelled while waiting for OnBeforeURLRequest callback.
TEST_F(URLRequestTestHTTP, NetworkDelegateCancelWhileWaiting1) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  BlockingNetworkDelegate network_delegate(
      BlockingNetworkDelegate::USER_CALLBACK);
  network_delegate.set_block_on(BlockingNetworkDelegate::ON_BEFORE_URL_REQUEST);

  TestURLRequestContext context(true);
  context.set_network_delegate(&network_delegate);
  context.Init();

  {
    scoped_ptr<URLRequest> r(context.CreateRequest(
        test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d));

    r->Start();
    base::RunLoop().Run();
    EXPECT_EQ(BlockingNetworkDelegate::ON_BEFORE_URL_REQUEST,
              network_delegate.stage_blocked_for_callback());
    EXPECT_EQ(0, network_delegate.completed_requests());
    // Cancel before callback.
    r->Cancel();
    // Ensure that network delegate is notified.
    EXPECT_EQ(1, network_delegate.completed_requests());
    EXPECT_EQ(URLRequestStatus::CANCELED, r->status().status());
    EXPECT_EQ(ERR_ABORTED, r->status().error());
    EXPECT_EQ(1, network_delegate.created_requests());
    EXPECT_EQ(0, network_delegate.destroyed_requests());
  }
  EXPECT_EQ(1, network_delegate.destroyed_requests());
}

// Tests that we can handle when a network request was canceled while we were
// waiting for the network delegate.
// Part 2: Request is cancelled while waiting for OnBeforeSendHeaders callback.
TEST_F(URLRequestTestHTTP, NetworkDelegateCancelWhileWaiting2) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  BlockingNetworkDelegate network_delegate(
      BlockingNetworkDelegate::USER_CALLBACK);
  network_delegate.set_block_on(
      BlockingNetworkDelegate::ON_BEFORE_SEND_HEADERS);

  TestURLRequestContext context(true);
  context.set_network_delegate(&network_delegate);
  context.Init();

  {
    scoped_ptr<URLRequest> r(context.CreateRequest(
        test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d));

    r->Start();
    base::RunLoop().Run();
    EXPECT_EQ(BlockingNetworkDelegate::ON_BEFORE_SEND_HEADERS,
              network_delegate.stage_blocked_for_callback());
    EXPECT_EQ(0, network_delegate.completed_requests());
    // Cancel before callback.
    r->Cancel();
    // Ensure that network delegate is notified.
    EXPECT_EQ(1, network_delegate.completed_requests());
    EXPECT_EQ(URLRequestStatus::CANCELED, r->status().status());
    EXPECT_EQ(ERR_ABORTED, r->status().error());
    EXPECT_EQ(1, network_delegate.created_requests());
    EXPECT_EQ(0, network_delegate.destroyed_requests());
  }
  EXPECT_EQ(1, network_delegate.destroyed_requests());
}

// Tests that we can handle when a network request was canceled while we were
// waiting for the network delegate.
// Part 3: Request is cancelled while waiting for OnHeadersReceived callback.
TEST_F(URLRequestTestHTTP, NetworkDelegateCancelWhileWaiting3) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  BlockingNetworkDelegate network_delegate(
      BlockingNetworkDelegate::USER_CALLBACK);
  network_delegate.set_block_on(BlockingNetworkDelegate::ON_HEADERS_RECEIVED);

  TestURLRequestContext context(true);
  context.set_network_delegate(&network_delegate);
  context.Init();

  {
    scoped_ptr<URLRequest> r(context.CreateRequest(
        test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d));

    r->Start();
    base::RunLoop().Run();
    EXPECT_EQ(BlockingNetworkDelegate::ON_HEADERS_RECEIVED,
              network_delegate.stage_blocked_for_callback());
    EXPECT_EQ(0, network_delegate.completed_requests());
    // Cancel before callback.
    r->Cancel();
    // Ensure that network delegate is notified.
    EXPECT_EQ(1, network_delegate.completed_requests());
    EXPECT_EQ(URLRequestStatus::CANCELED, r->status().status());
    EXPECT_EQ(ERR_ABORTED, r->status().error());
    EXPECT_EQ(1, network_delegate.created_requests());
    EXPECT_EQ(0, network_delegate.destroyed_requests());
  }
  EXPECT_EQ(1, network_delegate.destroyed_requests());
}

// Tests that we can handle when a network request was canceled while we were
// waiting for the network delegate.
// Part 4: Request is cancelled while waiting for OnAuthRequired callback.
TEST_F(URLRequestTestHTTP, NetworkDelegateCancelWhileWaiting4) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  BlockingNetworkDelegate network_delegate(
      BlockingNetworkDelegate::USER_CALLBACK);
  network_delegate.set_block_on(BlockingNetworkDelegate::ON_AUTH_REQUIRED);

  TestURLRequestContext context(true);
  context.set_network_delegate(&network_delegate);
  context.Init();

  {
    scoped_ptr<URLRequest> r(context.CreateRequest(
        test_server_.GetURL("auth-basic"), DEFAULT_PRIORITY, &d));

    r->Start();
    base::RunLoop().Run();
    EXPECT_EQ(BlockingNetworkDelegate::ON_AUTH_REQUIRED,
              network_delegate.stage_blocked_for_callback());
    EXPECT_EQ(0, network_delegate.completed_requests());
    // Cancel before callback.
    r->Cancel();
    // Ensure that network delegate is notified.
    EXPECT_EQ(1, network_delegate.completed_requests());
    EXPECT_EQ(URLRequestStatus::CANCELED, r->status().status());
    EXPECT_EQ(ERR_ABORTED, r->status().error());
    EXPECT_EQ(1, network_delegate.created_requests());
    EXPECT_EQ(0, network_delegate.destroyed_requests());
  }
  EXPECT_EQ(1, network_delegate.destroyed_requests());
}

// In this unit test, we're using the HTTPTestServer as a proxy server and
// issuing a CONNECT request with the magic host name "www.server-auth.com".
// The HTTPTestServer will return a 401 response, which we should balk at.
TEST_F(URLRequestTestHTTP, UnexpectedServerAuthTest) {
  ASSERT_TRUE(test_server_.Start());

  TestNetworkDelegate network_delegate;  // Must outlive URLRequest.
  TestURLRequestContextWithProxy context(
      test_server_.host_port_pair().ToString(), &network_delegate);

  TestDelegate d;
  {
    scoped_ptr<URLRequest> r(context.CreateRequest(
        GURL("https://www.server-auth.com/"), DEFAULT_PRIORITY, &d));

    r->Start();
    EXPECT_TRUE(r->is_pending());

    base::RunLoop().Run();

    EXPECT_EQ(URLRequestStatus::FAILED, r->status().status());
    // The proxy server is not set before failure.
    EXPECT_TRUE(r->proxy_server().IsEmpty());
    EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, r->status().error());
  }
}

TEST_F(URLRequestTestHTTP, GetTest_NoCache) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  {
    scoped_ptr<URLRequest> r(default_context_.CreateRequest(
        test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d));

    r->Start();
    EXPECT_TRUE(r->is_pending());

    base::RunLoop().Run();

    EXPECT_EQ(1, d.response_started_count());
    EXPECT_FALSE(d.received_data_before_response());
    EXPECT_NE(0, d.bytes_received());
    EXPECT_EQ(test_server_.host_port_pair().host(),
              r->GetSocketAddress().host());
    EXPECT_EQ(test_server_.host_port_pair().port(),
              r->GetSocketAddress().port());

    // TODO(eroman): Add back the NetLog tests...
  }
}

// This test has the server send a large number of cookies to the client.
// To ensure that no number of cookies causes a crash, a galloping binary
// search is used to estimate that maximum number of cookies that are accepted
// by the browser. Beyond the maximum number, the request will fail with
// ERR_RESPONSE_HEADERS_TOO_BIG.
#if defined(OS_WIN)
// http://crbug.com/177916
#define MAYBE_GetTest_ManyCookies DISABLED_GetTest_ManyCookies
#else
#define MAYBE_GetTest_ManyCookies GetTest_ManyCookies
#endif  // defined(OS_WIN)
TEST_F(URLRequestTestHTTP, MAYBE_GetTest_ManyCookies) {
  ASSERT_TRUE(test_server_.Start());

  int lower_bound = 0;
  int upper_bound = 1;

  // Double the number of cookies until the response header limits are
  // exceeded.
  while (DoManyCookiesRequest(upper_bound)) {
    lower_bound = upper_bound;
    upper_bound *= 2;
    ASSERT_LT(upper_bound, 1000000);
  }

  int tolerance = static_cast<int>(upper_bound * 0.005);
  if (tolerance < 2)
    tolerance = 2;

  // Perform a binary search to find the highest possible number of cookies,
  // within the desired tolerance.
  while (upper_bound - lower_bound >= tolerance) {
    int num_cookies = (lower_bound + upper_bound) / 2;

    if (DoManyCookiesRequest(num_cookies))
      lower_bound = num_cookies;
    else
      upper_bound = num_cookies;
  }
  // Success: the test did not crash.
}

TEST_F(URLRequestTestHTTP, GetTest) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  {
    scoped_ptr<URLRequest> r(default_context_.CreateRequest(
        test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d));

    r->Start();
    EXPECT_TRUE(r->is_pending());

    base::RunLoop().Run();

    EXPECT_EQ(1, d.response_started_count());
    EXPECT_FALSE(d.received_data_before_response());
    EXPECT_NE(0, d.bytes_received());
    EXPECT_EQ(test_server_.host_port_pair().host(),
              r->GetSocketAddress().host());
    EXPECT_EQ(test_server_.host_port_pair().port(),
              r->GetSocketAddress().port());
  }
}

TEST_F(URLRequestTestHTTP, GetTest_GetFullRequestHeaders) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  {
    GURL test_url(test_server_.GetURL(std::string()));
    scoped_ptr<URLRequest> r(
        default_context_.CreateRequest(test_url, DEFAULT_PRIORITY, &d));

    HttpRequestHeaders headers;
    EXPECT_FALSE(r->GetFullRequestHeaders(&headers));

    r->Start();
    EXPECT_TRUE(r->is_pending());

    base::RunLoop().Run();

    EXPECT_EQ(1, d.response_started_count());
    EXPECT_FALSE(d.received_data_before_response());
    EXPECT_NE(0, d.bytes_received());
    EXPECT_EQ(test_server_.host_port_pair().host(),
              r->GetSocketAddress().host());
    EXPECT_EQ(test_server_.host_port_pair().port(),
              r->GetSocketAddress().port());

    EXPECT_TRUE(d.have_full_request_headers());
    CheckFullRequestHeaders(d.full_request_headers(), test_url);
  }
}

TEST_F(URLRequestTestHTTP, GetTestLoadTiming) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  {
    scoped_ptr<URLRequest> r(default_context_.CreateRequest(
        test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d));

    r->Start();
    EXPECT_TRUE(r->is_pending());

    base::RunLoop().Run();

    LoadTimingInfo load_timing_info;
    r->GetLoadTimingInfo(&load_timing_info);
    TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);

    EXPECT_EQ(1, d.response_started_count());
    EXPECT_FALSE(d.received_data_before_response());
    EXPECT_NE(0, d.bytes_received());
    EXPECT_EQ(test_server_.host_port_pair().host(),
              r->GetSocketAddress().host());
    EXPECT_EQ(test_server_.host_port_pair().port(),
              r->GetSocketAddress().port());
  }
}

TEST_F(URLRequestTestHTTP, GetZippedTest) {
  ASSERT_TRUE(test_server_.Start());

  // Parameter that specifies the Content-Length field in the response:
  // C - Compressed length.
  // U - Uncompressed length.
  // L - Large length (larger than both C & U).
  // M - Medium length (between C & U).
  // S - Small length (smaller than both C & U).
  const char test_parameters[] = "CULMS";
  const int num_tests = arraysize(test_parameters)- 1;  // Skip NULL.
  // C & U should be OK.
  // L & M are larger than the data sent, and show an error.
  // S has too little data, but we seem to accept it.
  const bool test_expect_success[num_tests] =
      { true, true, false, false, true };

  for (int i = 0; i < num_tests ; i++) {
    TestDelegate d;
    {
      std::string test_file =
          base::StringPrintf("compressedfiles/BullRunSpeech.txt?%c",
                             test_parameters[i]);

      TestNetworkDelegate network_delegate;  // Must outlive URLRequest.
      TestURLRequestContext context(true);
      context.set_network_delegate(&network_delegate);
      context.Init();

      scoped_ptr<URLRequest> r(context.CreateRequest(
          test_server_.GetURL(test_file), DEFAULT_PRIORITY, &d));
      r->Start();
      EXPECT_TRUE(r->is_pending());

      base::RunLoop().Run();

      EXPECT_EQ(1, d.response_started_count());
      EXPECT_FALSE(d.received_data_before_response());
      VLOG(1) << " Received " << d.bytes_received() << " bytes"
              << " status = " << r->status().status()
              << " error = " << r->status().error();
      if (test_expect_success[i]) {
        EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status())
            << " Parameter = \"" << test_file << "\"";
      } else {
        EXPECT_EQ(URLRequestStatus::FAILED, r->status().status());
        EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, r->status().error())
            << " Parameter = \"" << test_file << "\"";
      }
    }
  }
}

TEST_F(URLRequestTestHTTP, NetworkQualityEstimator) {
  ASSERT_TRUE(test_server_.Start());
  // Enable requests to local host to be used for network quality estimation.
  std::map<std::string, std::string> variation_params;
  NetworkQualityEstimator estimator(scoped_ptr<net::ExternalEstimateProvider>(),
                                    variation_params, true, true);

  TestDelegate d;
  TestNetworkDelegate network_delegate;  // Must outlive URLRequest.
  TestURLRequestContext context(true);
  context.set_network_quality_estimator(&estimator);
  context.set_network_delegate(&network_delegate);
  context.Init();

  std::string url = "echo.html";

  scoped_ptr<URLRequest> r(
      context.CreateRequest(test_server_.GetURL(url), DEFAULT_PRIORITY, &d));
  r->Start();

  base::RunLoop().Run();

  base::TimeDelta rtt;
  int32_t kbps;
  EXPECT_TRUE(estimator.GetRTTEstimate(&rtt));
  EXPECT_TRUE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps));
  EXPECT_GE(rtt, base::TimeDelta());
  EXPECT_LT(rtt, base::TimeDelta::Max());
  EXPECT_GT(kbps, 0);

  // Verify that histograms are not populated. They should populate only when
  // there is a change in ConnectionType.
  base::HistogramTester histogram_tester;
  histogram_tester.ExpectTotalCount("NQE.PeakKbps.Unknown", 0);
  histogram_tester.ExpectTotalCount("NQE.FastestRTT.Unknown", 0);

  NetworkChangeNotifier::NotifyObserversOfConnectionTypeChangeForTests(
      NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI);
  base::MessageLoop::current()->RunUntilIdle();
  histogram_tester.ExpectTotalCount("NQE.PeakKbps.Unknown", 1);
  histogram_tester.ExpectTotalCount("NQE.FastestRTT.Unknown", 1);
}

TEST_F(URLRequestTestHTTP, RedirectLoadTiming) {
  ASSERT_TRUE(test_server_.Start());

  GURL destination_url = test_server_.GetURL(std::string());
  GURL original_url =
      test_server_.GetURL("server-redirect?" + destination_url.spec());
  TestDelegate d;
  scoped_ptr<URLRequest> req(
      default_context_.CreateRequest(original_url, DEFAULT_PRIORITY, &d));
  req->Start();
  base::RunLoop().Run();

  EXPECT_EQ(1, d.response_started_count());
  EXPECT_EQ(1, d.received_redirect_count());
  EXPECT_EQ(destination_url, req->url());
  EXPECT_EQ(original_url, req->original_url());
  ASSERT_EQ(2U, req->url_chain().size());
  EXPECT_EQ(original_url, req->url_chain()[0]);
  EXPECT_EQ(destination_url, req->url_chain()[1]);

  LoadTimingInfo load_timing_info_before_redirect;
  EXPECT_TRUE(default_network_delegate_.GetLoadTimingInfoBeforeRedirect(
      &load_timing_info_before_redirect));
  TestLoadTimingNotReused(load_timing_info_before_redirect,
                          CONNECT_TIMING_HAS_DNS_TIMES);

  LoadTimingInfo load_timing_info;
  req->GetLoadTimingInfo(&load_timing_info);
  TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);

  // Check that a new socket was used on redirect, since the server does not
  // supposed keep-alive sockets, and that the times before the redirect are
  // before the ones recorded for the second request.
  EXPECT_NE(load_timing_info_before_redirect.socket_log_id,
            load_timing_info.socket_log_id);
  EXPECT_LE(load_timing_info_before_redirect.receive_headers_end,
            load_timing_info.connect_timing.connect_start);
}

TEST_F(URLRequestTestHTTP, MultipleRedirectTest) {
  ASSERT_TRUE(test_server_.Start());

  GURL destination_url = test_server_.GetURL(std::string());
  GURL middle_redirect_url =
      test_server_.GetURL("server-redirect?" + destination_url.spec());
  GURL original_url = test_server_.GetURL(
      "server-redirect?" + middle_redirect_url.spec());
  TestDelegate d;
  scoped_ptr<URLRequest> req(
      default_context_.CreateRequest(original_url, DEFAULT_PRIORITY, &d));
  req->Start();
  base::RunLoop().Run();

  EXPECT_EQ(1, d.response_started_count());
  EXPECT_EQ(2, d.received_redirect_count());
  EXPECT_EQ(destination_url, req->url());
  EXPECT_EQ(original_url, req->original_url());
  ASSERT_EQ(3U, req->url_chain().size());
  EXPECT_EQ(original_url, req->url_chain()[0]);
  EXPECT_EQ(middle_redirect_url, req->url_chain()[1]);
  EXPECT_EQ(destination_url, req->url_chain()[2]);
}

// First and second pieces of information logged by delegates to URLRequests.
const char kFirstDelegateInfo[] = "Wonderful delegate";
const char kSecondDelegateInfo[] = "Exciting delegate";

// Logs delegate information to a URLRequest.  The first string is logged
// synchronously on Start(), using DELEGATE_INFO_DEBUG_ONLY.  The second is
// logged asynchronously, using DELEGATE_INFO_DISPLAY_TO_USER.  Then
// another asynchronous call is used to clear the delegate information
// before calling a callback.  The object then deletes itself.
class AsyncDelegateLogger : public base::RefCounted<AsyncDelegateLogger> {
 public:
  typedef base::Callback<void()> Callback;

  // Each time delegate information is added to the URLRequest, the resulting
  // load state is checked.  The expected load state after each request is
  // passed in as an argument.
  static void Run(URLRequest* url_request,
                  LoadState expected_first_load_state,
                  LoadState expected_second_load_state,
                  LoadState expected_third_load_state,
                  const Callback& callback) {
    AsyncDelegateLogger* logger = new AsyncDelegateLogger(
        url_request,
        expected_first_load_state,
        expected_second_load_state,
        expected_third_load_state,
        callback);
    logger->Start();
  }

  // Checks that the log entries, starting with log_position, contain the
  // DELEGATE_INFO NetLog events that an AsyncDelegateLogger should have
  // recorded.  Returns the index of entry after the expected number of
  // events this logged, or entries.size() if there aren't enough entries.
  static size_t CheckDelegateInfo(const TestNetLogEntry::List& entries,
                                  size_t log_position) {
    // There should be 4 DELEGATE_INFO events: Two begins and two ends.
    if (log_position + 3 >= entries.size()) {
      ADD_FAILURE() << "Not enough log entries";
      return entries.size();
    }
    std::string delegate_info;
    EXPECT_EQ(NetLog::TYPE_DELEGATE_INFO, entries[log_position].type);
    EXPECT_EQ(NetLog::PHASE_BEGIN, entries[log_position].phase);
    EXPECT_TRUE(entries[log_position].GetStringValue("delegate_info",
                                                     &delegate_info));
    EXPECT_EQ(kFirstDelegateInfo, delegate_info);

    ++log_position;
    EXPECT_EQ(NetLog::TYPE_DELEGATE_INFO, entries[log_position].type);
    EXPECT_EQ(NetLog::PHASE_END, entries[log_position].phase);

    ++log_position;
    EXPECT_EQ(NetLog::TYPE_DELEGATE_INFO, entries[log_position].type);
    EXPECT_EQ(NetLog::PHASE_BEGIN, entries[log_position].phase);
    EXPECT_TRUE(entries[log_position].GetStringValue("delegate_info",
                                                     &delegate_info));
    EXPECT_EQ(kSecondDelegateInfo, delegate_info);

    ++log_position;
    EXPECT_EQ(NetLog::TYPE_DELEGATE_INFO, entries[log_position].type);
    EXPECT_EQ(NetLog::PHASE_END, entries[log_position].phase);

    return log_position + 1;
  }

  // Find delegate request begin and end messages for OnBeforeNetworkStart.
  // Returns the position of the end message.
  static size_t ExpectBeforeNetworkEvents(const TestNetLogEntry::List& entries,
                                          size_t log_position) {
    log_position =
        ExpectLogContainsSomewhereAfter(entries,
                                        log_position,
                                        NetLog::TYPE_URL_REQUEST_DELEGATE,
                                        NetLog::PHASE_BEGIN);
    EXPECT_EQ(NetLog::TYPE_URL_REQUEST_DELEGATE,
              entries[log_position + 1].type);
    EXPECT_EQ(NetLog::PHASE_END, entries[log_position + 1].phase);
    return log_position + 1;
  }

 private:
  friend class base::RefCounted<AsyncDelegateLogger>;

  AsyncDelegateLogger(URLRequest* url_request,
                      LoadState expected_first_load_state,
                      LoadState expected_second_load_state,
                      LoadState expected_third_load_state,
                      const Callback& callback)
      : url_request_(url_request),
        expected_first_load_state_(expected_first_load_state),
        expected_second_load_state_(expected_second_load_state),
        expected_third_load_state_(expected_third_load_state),
        callback_(callback) {
  }

  ~AsyncDelegateLogger() {}

  void Start() {
    url_request_->LogBlockedBy(kFirstDelegateInfo);
    LoadStateWithParam load_state = url_request_->GetLoadState();
    EXPECT_EQ(expected_first_load_state_, load_state.state);
    EXPECT_NE(ASCIIToUTF16(kFirstDelegateInfo), load_state.param);
    base::ThreadTaskRunnerHandle::Get()->PostTask(
        FROM_HERE, base::Bind(&AsyncDelegateLogger::LogSecondDelegate, this));
  }

  void LogSecondDelegate() {
    url_request_->LogAndReportBlockedBy(kSecondDelegateInfo);
    LoadStateWithParam load_state = url_request_->GetLoadState();
    EXPECT_EQ(expected_second_load_state_, load_state.state);
    if (expected_second_load_state_ == LOAD_STATE_WAITING_FOR_DELEGATE) {
      EXPECT_EQ(ASCIIToUTF16(kSecondDelegateInfo), load_state.param);
    } else {
      EXPECT_NE(ASCIIToUTF16(kSecondDelegateInfo), load_state.param);
    }
    base::ThreadTaskRunnerHandle::Get()->PostTask(
        FROM_HERE, base::Bind(&AsyncDelegateLogger::LogComplete, this));
  }

  void LogComplete() {
    url_request_->LogUnblocked();
    LoadStateWithParam load_state = url_request_->GetLoadState();
    EXPECT_EQ(expected_third_load_state_, load_state.state);
    if (expected_second_load_state_ == LOAD_STATE_WAITING_FOR_DELEGATE)
      EXPECT_EQ(base::string16(), load_state.param);
    callback_.Run();
  }

  URLRequest* url_request_;
  const int expected_first_load_state_;
  const int expected_second_load_state_;
  const int expected_third_load_state_;
  const Callback callback_;

  DISALLOW_COPY_AND_ASSIGN(AsyncDelegateLogger);
};

// NetworkDelegate that logs delegate information before a request is started,
// before headers are sent, when headers are read, and when auth information
// is requested.  Uses AsyncDelegateLogger.
class AsyncLoggingNetworkDelegate : public TestNetworkDelegate {
 public:
  AsyncLoggingNetworkDelegate() {}
  ~AsyncLoggingNetworkDelegate() override {}

  // NetworkDelegate implementation.
  int OnBeforeURLRequest(URLRequest* request,
                         const CompletionCallback& callback,
                         GURL* new_url) override {
    TestNetworkDelegate::OnBeforeURLRequest(request, callback, new_url);
    return RunCallbackAsynchronously(request, callback);
  }

  int OnBeforeSendHeaders(URLRequest* request,
                          const CompletionCallback& callback,
                          HttpRequestHeaders* headers) override {
    TestNetworkDelegate::OnBeforeSendHeaders(request, callback, headers);
    return RunCallbackAsynchronously(request, callback);
  }

  int OnHeadersReceived(
      URLRequest* request,
      const CompletionCallback& callback,
      const HttpResponseHeaders* original_response_headers,
      scoped_refptr<HttpResponseHeaders>* override_response_headers,
      GURL* allowed_unsafe_redirect_url) override {
    TestNetworkDelegate::OnHeadersReceived(request,
                                           callback,
                                           original_response_headers,
                                           override_response_headers,
                                           allowed_unsafe_redirect_url);
    return RunCallbackAsynchronously(request, callback);
  }

  NetworkDelegate::AuthRequiredResponse OnAuthRequired(
      URLRequest* request,
      const AuthChallengeInfo& auth_info,
      const AuthCallback& callback,
      AuthCredentials* credentials) override {
    AsyncDelegateLogger::Run(
        request,
        LOAD_STATE_WAITING_FOR_DELEGATE,
        LOAD_STATE_WAITING_FOR_DELEGATE,
        LOAD_STATE_WAITING_FOR_DELEGATE,
        base::Bind(&AsyncLoggingNetworkDelegate::SetAuthAndResume,
                   callback, credentials));
    return AUTH_REQUIRED_RESPONSE_IO_PENDING;
  }

 private:
  static int RunCallbackAsynchronously(
      URLRequest* request,
      const CompletionCallback& callback) {
    AsyncDelegateLogger::Run(
        request,
        LOAD_STATE_WAITING_FOR_DELEGATE,
        LOAD_STATE_WAITING_FOR_DELEGATE,
        LOAD_STATE_WAITING_FOR_DELEGATE,
        base::Bind(callback, OK));
    return ERR_IO_PENDING;
  }

  static void SetAuthAndResume(const AuthCallback& callback,
                               AuthCredentials* credentials) {
    *credentials = AuthCredentials(kUser, kSecret);
    callback.Run(NetworkDelegate::AUTH_REQUIRED_RESPONSE_SET_AUTH);
  }

  DISALLOW_COPY_AND_ASSIGN(AsyncLoggingNetworkDelegate);
};

// URLRequest::Delegate that logs delegate information when the headers
// are received, when each read completes, and during redirects.  Uses
// AsyncDelegateLogger.  Can optionally cancel a request in any phase.
//
// Inherits from TestDelegate to reuse the TestDelegate code to handle
// advancing to the next step in most cases, as well as cancellation.
class AsyncLoggingUrlRequestDelegate : public TestDelegate {
 public:
  enum CancelStage {
    NO_CANCEL = 0,
    CANCEL_ON_RECEIVED_REDIRECT,
    CANCEL_ON_RESPONSE_STARTED,
    CANCEL_ON_READ_COMPLETED
  };

  explicit AsyncLoggingUrlRequestDelegate(CancelStage cancel_stage)
      : cancel_stage_(cancel_stage) {
    if (cancel_stage == CANCEL_ON_RECEIVED_REDIRECT)
      set_cancel_in_received_redirect(true);
    else if (cancel_stage == CANCEL_ON_RESPONSE_STARTED)
      set_cancel_in_response_started(true);
    else if (cancel_stage == CANCEL_ON_READ_COMPLETED)
      set_cancel_in_received_data(true);
  }
  ~AsyncLoggingUrlRequestDelegate() override {}

  // URLRequest::Delegate implementation:
  void OnReceivedRedirect(URLRequest* request,
                          const RedirectInfo& redirect_info,
                          bool* defer_redirect) override {
    *defer_redirect = true;
    AsyncDelegateLogger::Run(
        request,
        LOAD_STATE_WAITING_FOR_DELEGATE,
        LOAD_STATE_WAITING_FOR_DELEGATE,
        LOAD_STATE_WAITING_FOR_DELEGATE,
        base::Bind(
            &AsyncLoggingUrlRequestDelegate::OnReceivedRedirectLoggingComplete,
            base::Unretained(this), request, redirect_info));
  }

  void OnResponseStarted(URLRequest* request) override {
    AsyncDelegateLogger::Run(
      request,
      LOAD_STATE_WAITING_FOR_DELEGATE,
      LOAD_STATE_WAITING_FOR_DELEGATE,
      LOAD_STATE_WAITING_FOR_DELEGATE,
      base::Bind(
          &AsyncLoggingUrlRequestDelegate::OnResponseStartedLoggingComplete,
          base::Unretained(this), request));
  }

  void OnReadCompleted(URLRequest* request, int bytes_read) override {
    AsyncDelegateLogger::Run(
        request,
        LOAD_STATE_IDLE,
        LOAD_STATE_IDLE,
        LOAD_STATE_IDLE,
        base::Bind(
            &AsyncLoggingUrlRequestDelegate::AfterReadCompletedLoggingComplete,
            base::Unretained(this), request, bytes_read));
  }

 private:
  void OnReceivedRedirectLoggingComplete(URLRequest* request,
                                         const RedirectInfo& redirect_info) {
    bool defer_redirect = false;
    TestDelegate::OnReceivedRedirect(request, redirect_info, &defer_redirect);
    // FollowDeferredRedirect should not be called after cancellation.
    if (cancel_stage_ == CANCEL_ON_RECEIVED_REDIRECT)
      return;
    if (!defer_redirect)
      request->FollowDeferredRedirect();
  }

  void OnResponseStartedLoggingComplete(URLRequest* request) {
    // The parent class continues the request.
    TestDelegate::OnResponseStarted(request);
  }

  void AfterReadCompletedLoggingComplete(URLRequest* request, int bytes_read) {
    // The parent class continues the request.
    TestDelegate::OnReadCompleted(request, bytes_read);
  }

  const CancelStage cancel_stage_;

  DISALLOW_COPY_AND_ASSIGN(AsyncLoggingUrlRequestDelegate);
};

// Tests handling of delegate info before a request starts.
TEST_F(URLRequestTestHTTP, DelegateInfoBeforeStart) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate request_delegate;
  TestURLRequestContext context(true);
  context.set_network_delegate(NULL);
  context.set_net_log(&net_log_);
  context.Init();

  {
    scoped_ptr<URLRequest> r(
        context.CreateRequest(test_server_.GetURL("empty.html"),
                              DEFAULT_PRIORITY, &request_delegate));
    LoadStateWithParam load_state = r->GetLoadState();
    EXPECT_EQ(LOAD_STATE_IDLE, load_state.state);
    EXPECT_EQ(base::string16(), load_state.param);

    AsyncDelegateLogger::Run(
        r.get(),
        LOAD_STATE_WAITING_FOR_DELEGATE,
        LOAD_STATE_WAITING_FOR_DELEGATE,
        LOAD_STATE_IDLE,
        base::Bind(&URLRequest::Start, base::Unretained(r.get())));

    base::RunLoop().Run();

    EXPECT_EQ(200, r->GetResponseCode());
    EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
  }

  TestNetLogEntry::List entries;
  net_log_.GetEntries(&entries);
  size_t log_position = ExpectLogContainsSomewhereAfter(
      entries,
      0,
      NetLog::TYPE_DELEGATE_INFO,
      NetLog::PHASE_BEGIN);

  log_position = AsyncDelegateLogger::CheckDelegateInfo(entries, log_position);

  // Nothing else should add any delegate info to the request.
  EXPECT_FALSE(LogContainsEntryWithTypeAfter(
      entries, log_position + 1, NetLog::TYPE_DELEGATE_INFO));
}

// Tests handling of delegate info from a network delegate.
TEST_F(URLRequestTestHTTP, NetworkDelegateInfo) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate request_delegate;
  AsyncLoggingNetworkDelegate network_delegate;
  TestURLRequestContext context(true);
  context.set_network_delegate(&network_delegate);
  context.set_net_log(&net_log_);
  context.Init();

  {
    scoped_ptr<URLRequest> r(
        context.CreateRequest(test_server_.GetURL("simple.html"),
                              DEFAULT_PRIORITY, &request_delegate));
    LoadStateWithParam load_state = r->GetLoadState();
    EXPECT_EQ(LOAD_STATE_IDLE, load_state.state);
    EXPECT_EQ(base::string16(), load_state.param);

    r->Start();
    base::RunLoop().Run();

    EXPECT_EQ(200, r->GetResponseCode());
    EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
    EXPECT_EQ(1, network_delegate.created_requests());
    EXPECT_EQ(0, network_delegate.destroyed_requests());
  }
  EXPECT_EQ(1, network_delegate.destroyed_requests());

  size_t log_position = 0;
  TestNetLogEntry::List entries;
  net_log_.GetEntries(&entries);
  for (size_t i = 0; i < 3; ++i) {
    log_position = ExpectLogContainsSomewhereAfter(
        entries,
        log_position + 1,
        NetLog::TYPE_URL_REQUEST_DELEGATE,
        NetLog::PHASE_BEGIN);

    log_position = AsyncDelegateLogger::CheckDelegateInfo(entries,
                                                          log_position + 1);

    ASSERT_LT(log_position, entries.size());
    EXPECT_EQ(NetLog::TYPE_URL_REQUEST_DELEGATE, entries[log_position].type);
    EXPECT_EQ(NetLog::PHASE_END, entries[log_position].phase);

    if (i == 1) {
      log_position = AsyncDelegateLogger::ExpectBeforeNetworkEvents(
          entries, log_position + 1);
    }
  }

  EXPECT_FALSE(LogContainsEntryWithTypeAfter(
      entries, log_position + 1, NetLog::TYPE_DELEGATE_INFO));
}

// Tests handling of delegate info from a network delegate in the case of an
// HTTP redirect.
TEST_F(URLRequestTestHTTP, NetworkDelegateInfoRedirect) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate request_delegate;
  AsyncLoggingNetworkDelegate network_delegate;
  TestURLRequestContext context(true);
  context.set_network_delegate(&network_delegate);
  context.set_net_log(&net_log_);
  context.Init();

  {
    scoped_ptr<URLRequest> r(context.CreateRequest(
        test_server_.GetURL("server-redirect?simple.html"), DEFAULT_PRIORITY,
        &request_delegate));
    LoadStateWithParam load_state = r->GetLoadState();
    EXPECT_EQ(LOAD_STATE_IDLE, load_state.state);
    EXPECT_EQ(base::string16(), load_state.param);

    r->Start();
    base::RunLoop().Run();

    EXPECT_EQ(200, r->GetResponseCode());
    EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
    EXPECT_EQ(2, network_delegate.created_requests());
    EXPECT_EQ(0, network_delegate.destroyed_requests());
  }
  EXPECT_EQ(1, network_delegate.destroyed_requests());

  size_t log_position = 0;
  TestNetLogEntry::List entries;
  net_log_.GetEntries(&entries);
  // The NetworkDelegate logged information in OnBeforeURLRequest,
  // OnBeforeSendHeaders, and OnHeadersReceived.
  for (size_t i = 0; i < 3; ++i) {
    log_position = ExpectLogContainsSomewhereAfter(
        entries,
        log_position + 1,
        NetLog::TYPE_URL_REQUEST_DELEGATE,
        NetLog::PHASE_BEGIN);

    log_position = AsyncDelegateLogger::CheckDelegateInfo(entries,
                                                          log_position + 1);

    ASSERT_LT(log_position, entries.size());
    EXPECT_EQ(NetLog::TYPE_URL_REQUEST_DELEGATE, entries[log_position].type);
    EXPECT_EQ(NetLog::PHASE_END, entries[log_position].phase);

    if (i == 1) {
      log_position = AsyncDelegateLogger::ExpectBeforeNetworkEvents(
          entries, log_position + 1);
    }
  }

  // The URLRequest::Delegate then gets informed about the redirect.
  log_position = ExpectLogContainsSomewhereAfter(
      entries,
      log_position + 1,
      NetLog::TYPE_URL_REQUEST_DELEGATE,
      NetLog::PHASE_BEGIN);

  // The NetworkDelegate logged information in the same three events as before.
  for (size_t i = 0; i < 3; ++i) {
    log_position = ExpectLogContainsSomewhereAfter(
        entries,
        log_position + 1,
        NetLog::TYPE_URL_REQUEST_DELEGATE,
        NetLog::PHASE_BEGIN);

    log_position = AsyncDelegateLogger::CheckDelegateInfo(entries,
                                                          log_position + 1);

    ASSERT_LT(log_position, entries.size());
    EXPECT_EQ(NetLog::TYPE_URL_REQUEST_DELEGATE, entries[log_position].type);
    EXPECT_EQ(NetLog::PHASE_END, entries[log_position].phase);
  }

  EXPECT_FALSE(LogContainsEntryWithTypeAfter(
      entries, log_position + 1, NetLog::TYPE_DELEGATE_INFO));
}

// Tests handling of delegate info from a network delegate in the case of HTTP
// AUTH.
TEST_F(URLRequestTestHTTP, NetworkDelegateInfoAuth) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate request_delegate;
  AsyncLoggingNetworkDelegate network_delegate;
  TestURLRequestContext context(true);
  context.set_network_delegate(&network_delegate);
  context.set_net_log(&net_log_);
  context.Init();

  {
    scoped_ptr<URLRequest> r(
        context.CreateRequest(test_server_.GetURL("auth-basic"),
                              DEFAULT_PRIORITY, &request_delegate));
    LoadStateWithParam load_state = r->GetLoadState();
    EXPECT_EQ(LOAD_STATE_IDLE, load_state.state);
    EXPECT_EQ(base::string16(), load_state.param);

    r->Start();
    base::RunLoop().Run();

    EXPECT_EQ(200, r->GetResponseCode());
    EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
    EXPECT_EQ(1, network_delegate.created_requests());
    EXPECT_EQ(0, network_delegate.destroyed_requests());
  }
  EXPECT_EQ(1, network_delegate.destroyed_requests());

  size_t log_position = 0;
  TestNetLogEntry::List entries;
  net_log_.GetEntries(&entries);
  // The NetworkDelegate should have logged information in OnBeforeURLRequest,
  // OnBeforeSendHeaders, OnHeadersReceived, OnAuthRequired, and then again in
  // OnBeforeURLRequest and OnBeforeSendHeaders.
  for (size_t i = 0; i < 6; ++i) {
    log_position = ExpectLogContainsSomewhereAfter(
        entries,
        log_position + 1,
        NetLog::TYPE_URL_REQUEST_DELEGATE,
        NetLog::PHASE_BEGIN);

    log_position = AsyncDelegateLogger::CheckDelegateInfo(entries,
                                                          log_position + 1);

    ASSERT_LT(log_position, entries.size());
    EXPECT_EQ(NetLog::TYPE_URL_REQUEST_DELEGATE, entries[log_position].type);
    EXPECT_EQ(NetLog::PHASE_END, entries[log_position].phase);

    if (i == 1) {
      log_position = AsyncDelegateLogger::ExpectBeforeNetworkEvents(
          entries, log_position + 1);
    }
  }

  EXPECT_FALSE(LogContainsEntryWithTypeAfter(
      entries, log_position + 1, NetLog::TYPE_DELEGATE_INFO));
}

// Tests handling of delegate info from a URLRequest::Delegate.
TEST_F(URLRequestTestHTTP, URLRequestDelegateInfo) {
  ASSERT_TRUE(test_server_.Start());

  AsyncLoggingUrlRequestDelegate request_delegate(
      AsyncLoggingUrlRequestDelegate::NO_CANCEL);
  TestURLRequestContext context(true);
  context.set_network_delegate(NULL);
  context.set_net_log(&net_log_);
  context.Init();

  {
    // A chunked response with delays between chunks is used to make sure that
    // attempts by the URLRequest delegate to log information while reading the
    // body are ignored.  Since they are ignored, this test is robust against
    // the possibility of multiple reads being combined in the unlikely event
    // that it occurs.
    scoped_ptr<URLRequest> r(context.CreateRequest(
        test_server_.GetURL("chunked?waitBetweenChunks=20"), DEFAULT_PRIORITY,
        &request_delegate));
    LoadStateWithParam load_state = r->GetLoadState();
    r->Start();
    base::RunLoop().Run();

    EXPECT_EQ(200, r->GetResponseCode());
    EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
  }

  TestNetLogEntry::List entries;
  net_log_.GetEntries(&entries);

  size_t log_position = 0;

  log_position = AsyncDelegateLogger::ExpectBeforeNetworkEvents(
      entries, log_position);

  // The delegate info should only have been logged on header complete.  Other
  // times it should silently be ignored.
  log_position =
      ExpectLogContainsSomewhereAfter(entries,
                                      log_position + 1,
                                      NetLog::TYPE_URL_REQUEST_DELEGATE,
                                      NetLog::PHASE_BEGIN);

  log_position = AsyncDelegateLogger::CheckDelegateInfo(entries,
                                                        log_position + 1);

  ASSERT_LT(log_position, entries.size());
  EXPECT_EQ(NetLog::TYPE_URL_REQUEST_DELEGATE, entries[log_position].type);
  EXPECT_EQ(NetLog::PHASE_END, entries[log_position].phase);

  EXPECT_FALSE(LogContainsEntryWithTypeAfter(
      entries, log_position + 1, NetLog::TYPE_DELEGATE_INFO));
  EXPECT_FALSE(LogContainsEntryWithTypeAfter(
      entries, log_position + 1, NetLog::TYPE_URL_REQUEST_DELEGATE));
}

// Tests handling of delegate info from a URLRequest::Delegate in the case of
// an HTTP redirect.
TEST_F(URLRequestTestHTTP, URLRequestDelegateInfoOnRedirect) {
  ASSERT_TRUE(test_server_.Start());

  AsyncLoggingUrlRequestDelegate request_delegate(
      AsyncLoggingUrlRequestDelegate::NO_CANCEL);
  TestURLRequestContext context(true);
  context.set_network_delegate(NULL);
  context.set_net_log(&net_log_);
  context.Init();

  {
    scoped_ptr<URLRequest> r(context.CreateRequest(
        test_server_.GetURL("server-redirect?simple.html"), DEFAULT_PRIORITY,
        &request_delegate));
    LoadStateWithParam load_state = r->GetLoadState();
    r->Start();
    base::RunLoop().Run();

    EXPECT_EQ(200, r->GetResponseCode());
    EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
  }

  TestNetLogEntry::List entries;
  net_log_.GetEntries(&entries);

  // Delegate info should only have been logged in OnReceivedRedirect and
  // OnResponseStarted.
  size_t log_position = 0;
  for (int i = 0; i < 2; ++i) {
    if (i == 0) {
      log_position = AsyncDelegateLogger::ExpectBeforeNetworkEvents(
                         entries, log_position) + 1;
    }

    log_position = ExpectLogContainsSomewhereAfter(
            entries,
            log_position,
            NetLog::TYPE_URL_REQUEST_DELEGATE,
            NetLog::PHASE_BEGIN);

    log_position = AsyncDelegateLogger::CheckDelegateInfo(entries,
                                                          log_position + 1);

    ASSERT_LT(log_position, entries.size());
    EXPECT_EQ(NetLog::TYPE_URL_REQUEST_DELEGATE, entries[log_position].type);
    EXPECT_EQ(NetLog::PHASE_END, entries[log_position].phase);
  }

  EXPECT_FALSE(LogContainsEntryWithTypeAfter(
      entries, log_position + 1, NetLog::TYPE_DELEGATE_INFO));
  EXPECT_FALSE(LogContainsEntryWithTypeAfter(
      entries, log_position + 1, NetLog::TYPE_URL_REQUEST_DELEGATE));
}

// Tests handling of delegate info from a URLRequest::Delegate in the case of
// an HTTP redirect, with cancellation at various points.
TEST_F(URLRequestTestHTTP, URLRequestDelegateOnRedirectCancelled) {
  ASSERT_TRUE(test_server_.Start());

  const AsyncLoggingUrlRequestDelegate::CancelStage kCancelStages[] = {
    AsyncLoggingUrlRequestDelegate::CANCEL_ON_RECEIVED_REDIRECT,
    AsyncLoggingUrlRequestDelegate::CANCEL_ON_RESPONSE_STARTED,
    AsyncLoggingUrlRequestDelegate::CANCEL_ON_READ_COMPLETED,
  };

  for (size_t test_case = 0; test_case < arraysize(kCancelStages);
       ++test_case) {
    AsyncLoggingUrlRequestDelegate request_delegate(kCancelStages[test_case]);
    TestURLRequestContext context(true);
    TestNetLog net_log;
    context.set_network_delegate(NULL);
    context.set_net_log(&net_log);
    context.Init();

    {
      scoped_ptr<URLRequest> r(context.CreateRequest(
          test_server_.GetURL("server-redirect?simple.html"), DEFAULT_PRIORITY,
          &request_delegate));
      LoadStateWithParam load_state = r->GetLoadState();
      r->Start();
      base::RunLoop().Run();
      EXPECT_EQ(URLRequestStatus::CANCELED, r->status().status());
    }

    TestNetLogEntry::List entries;
    net_log.GetEntries(&entries);

    // Delegate info is always logged in both OnReceivedRedirect and
    // OnResponseStarted.  In the CANCEL_ON_RECEIVED_REDIRECT, the
    // OnResponseStarted delegate call is after cancellation, but logging is
    // still currently supported in that call.
    size_t log_position = 0;
    for (int i = 0; i < 2; ++i) {
      if (i == 0) {
        log_position = AsyncDelegateLogger::ExpectBeforeNetworkEvents(
                           entries, log_position) + 1;
      }

      log_position = ExpectLogContainsSomewhereAfter(
              entries,
              log_position,
              NetLog::TYPE_URL_REQUEST_DELEGATE,
              NetLog::PHASE_BEGIN);

      log_position = AsyncDelegateLogger::CheckDelegateInfo(entries,
                                                            log_position + 1);

      ASSERT_LT(log_position, entries.size());
      EXPECT_EQ(NetLog::TYPE_URL_REQUEST_DELEGATE, entries[log_position].type);
      EXPECT_EQ(NetLog::PHASE_END, entries[log_position].phase);
    }

    EXPECT_FALSE(LogContainsEntryWithTypeAfter(
        entries, log_position + 1, NetLog::TYPE_DELEGATE_INFO));
    EXPECT_FALSE(LogContainsEntryWithTypeAfter(
        entries, log_position + 1, NetLog::TYPE_URL_REQUEST_DELEGATE));
  }
}

namespace {

const char kExtraHeader[] = "Allow-Snafu";
const char kExtraValue[] = "fubar";

class RedirectWithAdditionalHeadersDelegate : public TestDelegate {
  void OnReceivedRedirect(URLRequest* request,
                          const RedirectInfo& redirect_info,
                          bool* defer_redirect) override {
    TestDelegate::OnReceivedRedirect(request, redirect_info, defer_redirect);
    request->SetExtraRequestHeaderByName(kExtraHeader, kExtraValue, false);
  }
};

}  // namespace

TEST_F(URLRequestTestHTTP, RedirectWithAdditionalHeadersTest) {
  ASSERT_TRUE(test_server_.Start());

  GURL destination_url = test_server_.GetURL(
      "echoheader?" + std::string(kExtraHeader));
  GURL original_url = test_server_.GetURL(
      "server-redirect?" + destination_url.spec());
  RedirectWithAdditionalHeadersDelegate d;
  scoped_ptr<URLRequest> req(
      default_context_.CreateRequest(original_url, DEFAULT_PRIORITY, &d));
  req->Start();
  base::RunLoop().Run();

  std::string value;
  const HttpRequestHeaders& headers = req->extra_request_headers();
  EXPECT_TRUE(headers.GetHeader(kExtraHeader, &value));
  EXPECT_EQ(kExtraValue, value);
  EXPECT_FALSE(req->is_pending());
  EXPECT_FALSE(req->is_redirecting());
  EXPECT_EQ(kExtraValue, d.data_received());
}

namespace {

const char kExtraHeaderToRemove[] = "To-Be-Removed";

class RedirectWithHeaderRemovalDelegate : public TestDelegate {
  void OnReceivedRedirect(URLRequest* request,
                          const RedirectInfo& redirect_info,
                          bool* defer_redirect) override {
    TestDelegate::OnReceivedRedirect(request, redirect_info, defer_redirect);
    request->RemoveRequestHeaderByName(kExtraHeaderToRemove);
  }
};

}  // namespace

TEST_F(URLRequestTestHTTP, RedirectWithHeaderRemovalTest) {
  ASSERT_TRUE(test_server_.Start());

  GURL destination_url = test_server_.GetURL(
      "echoheader?" + std::string(kExtraHeaderToRemove));
  GURL original_url = test_server_.GetURL(
      "server-redirect?" + destination_url.spec());
  RedirectWithHeaderRemovalDelegate d;
  scoped_ptr<URLRequest> req(
      default_context_.CreateRequest(original_url, DEFAULT_PRIORITY, &d));
  req->SetExtraRequestHeaderByName(kExtraHeaderToRemove, "dummy", false);
  req->Start();
  base::RunLoop().Run();

  std::string value;
  const HttpRequestHeaders& headers = req->extra_request_headers();
  EXPECT_FALSE(headers.GetHeader(kExtraHeaderToRemove, &value));
  EXPECT_FALSE(req->is_pending());
  EXPECT_FALSE(req->is_redirecting());
  EXPECT_EQ("None", d.data_received());
}

TEST_F(URLRequestTestHTTP, CancelTest) {
  TestDelegate d;
  {
    scoped_ptr<URLRequest> r(default_context_.CreateRequest(
        GURL("http://www.google.com/"), DEFAULT_PRIORITY, &d));

    r->Start();
    EXPECT_TRUE(r->is_pending());

    r->Cancel();

    base::RunLoop().Run();

    // We expect to receive OnResponseStarted even though the request has been
    // cancelled.
    EXPECT_EQ(1, d.response_started_count());
    EXPECT_EQ(0, d.bytes_received());
    EXPECT_FALSE(d.received_data_before_response());
  }
}

TEST_F(URLRequestTestHTTP, CancelTest2) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  {
    scoped_ptr<URLRequest> r(default_context_.CreateRequest(
        test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d));

    d.set_cancel_in_response_started(true);

    r->Start();
    EXPECT_TRUE(r->is_pending());

    base::RunLoop().Run();

    EXPECT_EQ(1, d.response_started_count());
    EXPECT_EQ(0, d.bytes_received());
    EXPECT_FALSE(d.received_data_before_response());
    EXPECT_EQ(URLRequestStatus::CANCELED, r->status().status());
  }
}

TEST_F(URLRequestTestHTTP, CancelTest3) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  {
    scoped_ptr<URLRequest> r(default_context_.CreateRequest(
        test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d));

    d.set_cancel_in_received_data(true);

    r->Start();
    EXPECT_TRUE(r->is_pending());

    base::RunLoop().Run();

    EXPECT_EQ(1, d.response_started_count());
    // There is no guarantee about how much data was received
    // before the cancel was issued.  It could have been 0 bytes,
    // or it could have been all the bytes.
    // EXPECT_EQ(0, d.bytes_received());
    EXPECT_FALSE(d.received_data_before_response());
    EXPECT_EQ(URLRequestStatus::CANCELED, r->status().status());
  }
}

TEST_F(URLRequestTestHTTP, CancelTest4) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  {
    scoped_ptr<URLRequest> r(default_context_.CreateRequest(
        test_server_.GetURL(std::string()), DEFAULT_PRIORITY, &d));

    r->Start();
    EXPECT_TRUE(r->is_pending());

    // The request will be implicitly canceled when it is destroyed. The
    // test delegate must not post a quit message when this happens because
    // this test doesn't actually have a message loop. The quit message would
    // get put on this thread's message queue and the next test would exit
    // early, causing problems.
    d.set_quit_on_complete(false);
  }
  // expect things to just cleanup properly.

  // we won't actually get a received reponse here because we've never run the
  // message loop
  EXPECT_FALSE(d.received_data_before_response());
  EXPECT_EQ(0, d.bytes_received());
}

TEST_F(URLRequestTestHTTP, CancelTest5) {
  ASSERT_TRUE(test_server_.Start());

  // populate cache
  {
    TestDelegate d;
    scoped_ptr<URLRequest> r(default_context_.CreateRequest(
        test_server_.GetURL("cachetime"), DEFAULT_PRIORITY, &d));
    r->Start();
    base::RunLoop().Run();
    EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
  }

  // cancel read from cache (see bug 990242)
  {
    TestDelegate d;
    scoped_ptr<URLRequest> r(default_context_.CreateRequest(
        test_server_.GetURL("cachetime"), DEFAULT_PRIORITY, &d));
    r->Start();
    r->Cancel();
    base::RunLoop().Run();

    EXPECT_EQ(URLRequestStatus::CANCELED, r->status().status());
    EXPECT_EQ(1, d.response_started_count());
    EXPECT_EQ(0, d.bytes_received());
    EXPECT_FALSE(d.received_data_before_response());
  }
}

TEST_F(URLRequestTestHTTP, PostTest) {
  ASSERT_TRUE(test_server_.Start());
  HTTPUploadDataOperationTest("POST");
}

TEST_F(URLRequestTestHTTP, PutTest) {
  ASSERT_TRUE(test_server_.Start());
  HTTPUploadDataOperationTest("PUT");
}

TEST_F(URLRequestTestHTTP, PostEmptyTest) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  {
    scoped_ptr<URLRequest> r(default_context_.CreateRequest(
        test_server_.GetURL("echo"), DEFAULT_PRIORITY, &d));
    r->set_method("POST");

    r->Start();
    EXPECT_TRUE(r->is_pending());

    base::RunLoop().Run();

    ASSERT_EQ(1, d.response_started_count())
        << "request failed: " << r->status().status()
        << ", error: " << r->status().error();

    EXPECT_FALSE(d.received_data_before_response());
    EXPECT_TRUE(d.data_received().empty());
  }
}

TEST_F(URLRequestTestHTTP, PostFileTest) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  {
    scoped_ptr<URLRequest> r(default_context_.CreateRequest(
        test_server_.GetURL("echo"), DEFAULT_PRIORITY, &d));
    r->set_method("POST");

    base::FilePath dir;
    PathService::Get(base::DIR_EXE, &dir);
    base::SetCurrentDirectory(dir);

    ScopedVector<UploadElementReader> element_readers;

    base::FilePath path;
    PathService::Get(base::DIR_SOURCE_ROOT, &path);
    path = path.Append(kTestFilePath);
    path = path.Append(FILE_PATH_LITERAL("with-headers.html"));
    element_readers.push_back(
        new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
                                    path, 0, kuint64max, base::Time()));
    r->set_upload(make_scoped_ptr<UploadDataStream>(
        new ElementsUploadDataStream(element_readers.Pass(), 0)));

    r->Start();
    EXPECT_TRUE(r->is_pending());

    base::RunLoop().Run();

    int64 size64 = 0;
    ASSERT_EQ(true, base::GetFileSize(path, &size64));
    ASSERT_LE(size64, std::numeric_limits<int>::max());
    int size = static_cast<int>(size64);
    scoped_ptr<char[]> buf(new char[size]);

    ASSERT_EQ(size, base::ReadFile(path, buf.get(), size));

    ASSERT_EQ(1, d.response_started_count())
        << "request failed: " << r->status().status()
        << ", error: " << r->status().error();

    EXPECT_FALSE(d.received_data_before_response());

    EXPECT_EQ(size, d.bytes_received());
    EXPECT_EQ(std::string(&buf[0], size), d.data_received());
  }
}

TEST_F(URLRequestTestHTTP, PostUnreadableFileTest) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  {
    scoped_ptr<URLRequest> r(default_context_.CreateRequest(
        test_server_.GetURL("echo"), DEFAULT_PRIORITY, &d));
    r->set_method("POST");

    ScopedVector<UploadElementReader> element_readers;

    element_readers.push_back(new UploadFileElementReader(
        base::ThreadTaskRunnerHandle::Get().get(),
        base::FilePath(FILE_PATH_LITERAL(
            "c:\\path\\to\\non\\existant\\file.randomness.12345")),
        0, kuint64max, base::Time()));
    r->set_upload(make_scoped_ptr<UploadDataStream>(
        new ElementsUploadDataStream(element_readers.Pass(), 0)));

    r->Start();
    EXPECT_TRUE(r->is_pending());

    base::RunLoop().Run();

    EXPECT_TRUE(d.request_failed());
    EXPECT_FALSE(d.received_data_before_response());
    EXPECT_EQ(0, d.bytes_received());
    EXPECT_EQ(URLRequestStatus::FAILED, r->status().status());
    EXPECT_EQ(ERR_FILE_NOT_FOUND, r->status().error());
  }
}

TEST_F(URLRequestTestHTTP, TestPostChunkedDataBeforeStart) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  {
    scoped_ptr<URLRequest> r(default_context_.CreateRequest(
        test_server_.GetURL("echo"), DEFAULT_PRIORITY, &d));
    r->EnableChunkedUpload();
    r->set_method("POST");
    AddChunksToUpload(r.get());
    r->Start();
    EXPECT_TRUE(r->is_pending());

    base::RunLoop().Run();

    VerifyReceivedDataMatchesChunks(r.get(), &d);
  }
}

TEST_F(URLRequestTestHTTP, TestPostChunkedDataJustAfterStart) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  {
    scoped_ptr<URLRequest> r(default_context_.CreateRequest(
        test_server_.GetURL("echo"), DEFAULT_PRIORITY, &d));
    r->EnableChunkedUpload();
    r->set_method("POST");
    r->Start();
    EXPECT_TRUE(r->is_pending());
    AddChunksToUpload(r.get());
    base::RunLoop().Run();

    VerifyReceivedDataMatchesChunks(r.get(), &d);
  }
}

TEST_F(URLRequestTestHTTP, TestPostChunkedDataAfterStart) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  {
    scoped_ptr<URLRequest> r(default_context_.CreateRequest(
        test_server_.GetURL("echo"), DEFAULT_PRIORITY, &d));
    r->EnableChunkedUpload();
    r->set_method("POST");
    r->Start();
    EXPECT_TRUE(r->is_pending());

    base::RunLoop().RunUntilIdle();
    AddChunksToUpload(r.get());
    base::RunLoop().Run();

    VerifyReceivedDataMatchesChunks(r.get(), &d);
  }
}

TEST_F(URLRequestTestHTTP, ResponseHeadersTest) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  scoped_ptr<URLRequest> req(default_context_.CreateRequest(
      test_server_.GetURL("files/with-headers.html"), DEFAULT_PRIORITY, &d));
  req->Start();
  base::RunLoop().Run();

  const HttpResponseHeaders* headers = req->response_headers();

  // Simple sanity check that response_info() accesses the same data.
  EXPECT_EQ(headers, req->response_info().headers.get());

  std::string header;
  EXPECT_TRUE(headers->GetNormalizedHeader("cache-control", &header));
  EXPECT_EQ("private", header);

  header.clear();
  EXPECT_TRUE(headers->GetNormalizedHeader("content-type", &header));
  EXPECT_EQ("text/html; charset=ISO-8859-1", header);

  // The response has two "X-Multiple-Entries" headers.
  // This verfies our output has them concatenated together.
  header.clear();
  EXPECT_TRUE(headers->GetNormalizedHeader("x-multiple-entries", &header));
  EXPECT_EQ("a, b", header);
}

TEST_F(URLRequestTestHTTP, ProcessSTS) {
  SpawnedTestServer::SSLOptions ssl_options(
      SpawnedTestServer::SSLOptions::CERT_COMMON_NAME_IS_DOMAIN);
  SpawnedTestServer https_test_server(SpawnedTestServer::TYPE_HTTPS,
                                      ssl_options,
                                      base::FilePath(kTestFilePath));
  ASSERT_TRUE(https_test_server.Start());

  std::string test_server_hostname = https_test_server.GetURL("").host();

  TestDelegate d;
  scoped_ptr<URLRequest> request(default_context_.CreateRequest(
      https_test_server.GetURL("files/hsts-headers.html"), DEFAULT_PRIORITY,
      &d));
  request->Start();
  base::RunLoop().Run();

  TransportSecurityState* security_state =
      default_context_.transport_security_state();
  TransportSecurityState::STSState sts_state;
  TransportSecurityState::PKPState pkp_state;
  EXPECT_TRUE(
      security_state->GetDynamicSTSState(test_server_hostname, &sts_state));
  EXPECT_FALSE(
      security_state->GetDynamicPKPState(test_server_hostname, &pkp_state));
  EXPECT_EQ(TransportSecurityState::STSState::MODE_FORCE_HTTPS,
            sts_state.upgrade_mode);
  EXPECT_TRUE(sts_state.include_subdomains);
  EXPECT_FALSE(pkp_state.include_subdomains);
#if defined(OS_ANDROID)
  // Android's CertVerifyProc does not (yet) handle pins.
#else
  EXPECT_FALSE(pkp_state.HasPublicKeyPins());
#endif
}

TEST_F(URLRequestTestHTTP, STSNotProcessedOnIP) {
  SpawnedTestServer https_test_server(SpawnedTestServer::TYPE_HTTPS,
                                      SpawnedTestServer::SSLOptions(),
                                      base::FilePath(kTestFilePath));
  ASSERT_TRUE(https_test_server.Start());
  // Make sure this test fails if the test server is changed to not
  // listen on an IP by default.
  ASSERT_TRUE(https_test_server.GetURL("").HostIsIPAddress());
  std::string test_server_hostname = https_test_server.GetURL("").host();

  TestDelegate d;
  scoped_ptr<URLRequest> request(default_context_.CreateRequest(
      https_test_server.GetURL("files/hsts-headers.html"), DEFAULT_PRIORITY,
      &d));
  request->Start();
  base::RunLoop().Run();

  TransportSecurityState* security_state =
      default_context_.transport_security_state();
  TransportSecurityState::STSState sts_state;
  EXPECT_FALSE(
      security_state->GetDynamicSTSState(test_server_hostname, &sts_state));
}

// Android's CertVerifyProc does not (yet) handle pins. Therefore, it will
// reject HPKP headers, and a test setting only HPKP headers will fail (no
// PKPState present because header rejected).
#if defined(OS_ANDROID)
#define MAYBE_ProcessPKP DISABLED_ProcessPKP
#define MAYBE_ProcessPKPAndSendReport DISABLED_ProcessPKPAndSendReport
#define MAYBE_ProcessPKPReportOnly DISABLED_ProcessPKPReportOnly
#define MAYBE_ProcessPKPReportOnlyWithNoViolation \
  DISABLED_ProcessPKPReportOnlyWithNoViolation
#else
#define MAYBE_ProcessPKP ProcessPKP
#define MAYBE_ProcessPKPAndSendReport ProcessPKPAndSendReport
#define MAYBE_ProcessPKPReportOnly ProcessPKPReportOnly
#define MAYBE_ProcessPKPReportOnlyWithNoViolation \
  ProcessPKPReportOnlyWithNoViolation
#endif

namespace {
const char kHPKPReportUri[] = "https://hpkp-report.test";
}  // namespace

// Tests that enabling HPKP on a domain does not affect the HSTS
// validity/expiration.
TEST_F(URLRequestTestHTTP, MAYBE_ProcessPKP) {
  GURL report_uri(kHPKPReportUri);
  SpawnedTestServer::SSLOptions ssl_options(
      SpawnedTestServer::SSLOptions::CERT_COMMON_NAME_IS_DOMAIN);
  SpawnedTestServer https_test_server(SpawnedTestServer::TYPE_HTTPS,
                                      ssl_options,
                                      base::FilePath(kTestFilePath));
  ASSERT_TRUE(https_test_server.Start());

  std::string test_server_hostname = https_test_server.GetURL("").host();

  TestDelegate d;
  scoped_ptr<URLRequest> request(default_context_.CreateRequest(
      https_test_server.GetURL("files/hpkp-headers.html"), DEFAULT_PRIORITY,
      &d));
  request->Start();
  base::RunLoop().Run();

  TransportSecurityState* security_state =
      default_context_.transport_security_state();
  TransportSecurityState::STSState sts_state;
  TransportSecurityState::PKPState pkp_state;
  EXPECT_FALSE(
      security_state->GetDynamicSTSState(test_server_hostname, &sts_state));
  EXPECT_TRUE(
      security_state->GetDynamicPKPState(test_server_hostname, &pkp_state));
  EXPECT_EQ(TransportSecurityState::STSState::MODE_DEFAULT,
            sts_state.upgrade_mode);
  EXPECT_FALSE(sts_state.include_subdomains);
  EXPECT_FALSE(pkp_state.include_subdomains);
  EXPECT_TRUE(pkp_state.HasPublicKeyPins());
  EXPECT_EQ(report_uri, pkp_state.report_uri);
  EXPECT_NE(sts_state.expiry, pkp_state.expiry);
}

// Tests that reports get sent on HPKP violations when a report-uri is set.
TEST_F(URLRequestTestHTTP, MAYBE_ProcessPKPAndSendReport) {
  GURL report_uri(kHPKPReportUri);
  SpawnedTestServer::SSLOptions ssl_options(
      SpawnedTestServer::SSLOptions::CERT_COMMON_NAME_IS_DOMAIN);
  SpawnedTestServer https_test_server(SpawnedTestServer::TYPE_HTTPS,
                                      ssl_options,
                                      base::FilePath(kTestFilePath));

  ASSERT_TRUE(https_test_server.Start());

  std::string test_server_hostname = https_test_server.GetURL("").host();

  // Set up a pin for |test_server_hostname|.
  TransportSecurityState security_state;
  const base::Time current_time(base::Time::Now());
  const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
  HashValueVector hashes;
  HashValue hash1;
  HashValue hash2;
  // The values here don't matter, as long as they are different from
  // the mocked CertVerifyResult below.
  ASSERT_TRUE(
      hash1.FromString("sha256/1111111111111111111111111111111111111111111="));
  ASSERT_TRUE(
      hash2.FromString("sha256/2222222222222222222222222222222222222222222="));
  hashes.push_back(hash1);
  hashes.push_back(hash2);
  security_state.AddHPKP(test_server_hostname, expiry,
                         false, /* include subdomains */
                         hashes, report_uri);

  MockCertificateReportSender mock_report_sender;
  security_state.SetReportSender(&mock_report_sender);

  // Set up a MockCertVerifier to trigger a violation of the previously
  // set pin.
  scoped_refptr<X509Certificate> cert = https_test_server.GetCertificate();
  ASSERT_TRUE(cert);

  MockCertVerifier cert_verifier;
  CertVerifyResult verify_result;
  verify_result.verified_cert = cert;
  verify_result.is_issued_by_known_root = true;
  HashValue hash3;
  ASSERT_TRUE(
      hash3.FromString("sha256/3333333333333333333333333333333333333333333="));
  verify_result.public_key_hashes.push_back(hash3);
  cert_verifier.AddResultForCert(cert.get(), verify_result, OK);

  TestNetworkDelegate network_delegate;
  TestURLRequestContext context(true);
  context.set_transport_security_state(&security_state);
  context.set_network_delegate(&network_delegate);
  context.set_cert_verifier(&cert_verifier);
  context.Init();

  // Now send a request to trigger the violation.
  TestDelegate d;
  scoped_ptr<URLRequest> violating_request(context.CreateRequest(
      https_test_server.GetURL("files/simple.html"), DEFAULT_PRIORITY, &d));
  violating_request->Start();
  base::RunLoop().Run();

  // Check that a report was sent.
  EXPECT_EQ(report_uri, mock_report_sender.latest_report_uri());
  ASSERT_FALSE(mock_report_sender.latest_report().empty());
  scoped_ptr<base::Value> value(
      base::JSONReader::Read(mock_report_sender.latest_report()));
  ASSERT_TRUE(value);
  ASSERT_TRUE(value->IsType(base::Value::TYPE_DICTIONARY));
  base::DictionaryValue* report_dict;
  ASSERT_TRUE(value->GetAsDictionary(&report_dict));
  std::string report_hostname;
  EXPECT_TRUE(report_dict->GetString("hostname", &report_hostname));
  EXPECT_EQ(test_server_hostname, report_hostname);
}

// Tests that reports get sent on requests with
// Public-Key-Pins-Report-Only headers.
TEST_F(URLRequestTestHTTP, MAYBE_ProcessPKPReportOnly) {
  GURL report_uri(kHPKPReportUri);
  SpawnedTestServer::SSLOptions ssl_options(
      SpawnedTestServer::SSLOptions::CERT_COMMON_NAME_IS_DOMAIN);
  SpawnedTestServer https_test_server(SpawnedTestServer::TYPE_HTTPS,
                                      ssl_options,
                                      base::FilePath(kTestFilePath));

  ASSERT_TRUE(https_test_server.Start());

  std::string test_server_hostname = https_test_server.GetURL("").host();

  TransportSecurityState security_state;
  MockCertificateReportSender mock_report_sender;
  security_state.SetReportSender(&mock_report_sender);

  // Set up a MockCertVerifier to violate the pin in the Report-Only
  // header.
  scoped_refptr<X509Certificate> cert = https_test_server.GetCertificate();
  ASSERT_TRUE(cert);

  MockCertVerifier cert_verifier;
  CertVerifyResult verify_result;
  verify_result.verified_cert = cert;
  verify_result.is_issued_by_known_root = true;
  HashValue hash;
  // This value doesn't matter, as long as it is different from the pins
  // for the request to hpkp-headers-report-only.html.
  ASSERT_TRUE(
      hash.FromString("sha256/1111111111111111111111111111111111111111111="));
  verify_result.public_key_hashes.push_back(hash);
  cert_verifier.AddResultForCert(cert.get(), verify_result, OK);

  TestNetworkDelegate network_delegate;
  TestURLRequestContext context(true);
  context.set_transport_security_state(&security_state);
  context.set_network_delegate(&network_delegate);
  context.set_cert_verifier(&cert_verifier);
  context.Init();

  // Now send a request to trigger the violation.
  TestDelegate d;
  scoped_ptr<URLRequest> violating_request(context.CreateRequest(
      https_test_server.GetURL("files/hpkp-headers-report-only.html"),
      DEFAULT_PRIORITY, &d));
  violating_request->Start();
  base::RunLoop().Run();

  // Check that a report was sent.
  EXPECT_EQ(report_uri, mock_report_sender.latest_report_uri());
  ASSERT_FALSE(mock_report_sender.latest_report().empty());
  scoped_ptr<base::Value> value(
      base::JSONReader::Read(mock_report_sender.latest_report()));
  ASSERT_TRUE(value);
  ASSERT_TRUE(value->IsType(base::Value::TYPE_DICTIONARY));
  base::DictionaryValue* report_dict;
  ASSERT_TRUE(value->GetAsDictionary(&report_dict));
  std::string report_hostname;
  EXPECT_TRUE(report_dict->GetString("hostname", &report_hostname));
  EXPECT_EQ(test_server_hostname, report_hostname);
}

// Tests that reports do not get sent on requests with
// Public-Key-Pins-Report-Only headers that don't have pin violations.
TEST_F(URLRequestTestHTTP, MAYBE_ProcessPKPReportOnlyWithNoViolation) {
  GURL report_uri(kHPKPReportUri);
  SpawnedTestServer::SSLOptions ssl_options(
      SpawnedTestServer::SSLOptions::CERT_COMMON_NAME_IS_DOMAIN);
  SpawnedTestServer https_test_server(SpawnedTestServer::TYPE_HTTPS,
                                      ssl_options,
                                      base::FilePath(kTestFilePath));

  ASSERT_TRUE(https_test_server.Start());

  std::string test_server_hostname = https_test_server.GetURL("").host();

  TransportSecurityState security_state;
  MockCertificateReportSender mock_report_sender;
  security_state.SetReportSender(&mock_report_sender);

  TestNetworkDelegate network_delegate;
  MockCertVerifier mock_cert_verifier;
  TestURLRequestContext context(true);
  context.set_transport_security_state(&security_state);
  context.set_network_delegate(&network_delegate);
  context.set_cert_verifier(&mock_cert_verifier);
  mock_cert_verifier.set_default_result(OK);
  context.Init();

  // Now send a request that does not trigger the violation.
  TestDelegate d;
  scoped_ptr<URLRequest> request(context.CreateRequest(
      https_test_server.GetURL("files/hpkp-headers-report-only.html"),
      DEFAULT_PRIORITY, &d));
  request->Start();
  base::RunLoop().Run();

  // Check that a report was not sent.
  EXPECT_EQ(GURL(), mock_report_sender.latest_report_uri());
  EXPECT_EQ(std::string(), mock_report_sender.latest_report());
}

TEST_F(URLRequestTestHTTP, PKPNotProcessedOnIP) {
  SpawnedTestServer https_test_server(SpawnedTestServer::TYPE_HTTPS,
                                      SpawnedTestServer::SSLOptions(),
                                      base::FilePath(kTestFilePath));
  ASSERT_TRUE(https_test_server.Start());
  // Make sure this test fails if the test server is changed to not
  // listen on an IP by default.
  ASSERT_TRUE(https_test_server.GetURL("").HostIsIPAddress());
  std::string test_server_hostname = https_test_server.GetURL("").host();

  TestDelegate d;
  scoped_ptr<URLRequest> request(default_context_.CreateRequest(
      https_test_server.GetURL("files/hpkp-headers.html"), DEFAULT_PRIORITY,
      &d));
  request->Start();
  base::RunLoop().Run();

  TransportSecurityState* security_state =
      default_context_.transport_security_state();
  TransportSecurityState::PKPState pkp_state;
  EXPECT_FALSE(
      security_state->GetDynamicPKPState(test_server_hostname, &pkp_state));
}

TEST_F(URLRequestTestHTTP, ProcessSTSOnce) {
  SpawnedTestServer::SSLOptions ssl_options(
      SpawnedTestServer::SSLOptions::CERT_COMMON_NAME_IS_DOMAIN);
  SpawnedTestServer https_test_server(SpawnedTestServer::TYPE_HTTPS,
                                      ssl_options,
                                      base::FilePath(kTestFilePath));
  ASSERT_TRUE(https_test_server.Start());

  std::string test_server_hostname = https_test_server.GetURL("").host();

  TestDelegate d;
  scoped_ptr<URLRequest> request(default_context_.CreateRequest(
      https_test_server.GetURL("files/hsts-multiple-headers.html"),
      DEFAULT_PRIORITY, &d));
  request->Start();
  base::RunLoop().Run();

  // We should have set parameters from the first header, not the second.
  TransportSecurityState* security_state =
      default_context_.transport_security_state();
  TransportSecurityState::STSState sts_state;
  EXPECT_TRUE(
      security_state->GetDynamicSTSState(test_server_hostname, &sts_state));
  EXPECT_EQ(TransportSecurityState::STSState::MODE_FORCE_HTTPS,
            sts_state.upgrade_mode);
  EXPECT_FALSE(sts_state.include_subdomains);
  EXPECT_FALSE(sts_state.include_subdomains);
}

TEST_F(URLRequestTestHTTP, ProcessSTSAndPKP) {
  SpawnedTestServer::SSLOptions ssl_options(
      SpawnedTestServer::SSLOptions::CERT_COMMON_NAME_IS_DOMAIN);
  SpawnedTestServer https_test_server(SpawnedTestServer::TYPE_HTTPS,
                                      ssl_options,
                                      base::FilePath(kTestFilePath));
  ASSERT_TRUE(https_test_server.Start());

  std::string test_server_hostname = https_test_server.GetURL("").host();

  TestDelegate d;
  scoped_ptr<URLRequest> request(default_context_.CreateRequest(
      https_test_server.GetURL("files/hsts-and-hpkp-headers.html"),
      DEFAULT_PRIORITY, &d));
  request->Start();
  base::RunLoop().Run();

  // We should have set parameters from the first header, not the second.
  TransportSecurityState* security_state =
      default_context_.transport_security_state();
  TransportSecurityState::STSState sts_state;
  TransportSecurityState::PKPState pkp_state;
  EXPECT_TRUE(
      security_state->GetDynamicSTSState(test_server_hostname, &sts_state));
  EXPECT_TRUE(
      security_state->GetDynamicPKPState(test_server_hostname, &pkp_state));
  EXPECT_EQ(TransportSecurityState::STSState::MODE_FORCE_HTTPS,
            sts_state.upgrade_mode);
#if defined(OS_ANDROID)
  // Android's CertVerifyProc does not (yet) handle pins.
#else
  EXPECT_TRUE(pkp_state.HasPublicKeyPins());
#endif
  EXPECT_NE(sts_state.expiry, pkp_state.expiry);

  // Even though there is an HSTS header asserting includeSubdomains, it is
  // the *second* such header, and we MUST process only the first.
  EXPECT_FALSE(sts_state.include_subdomains);
  // includeSubdomains does not occur in the test HPKP header.
  EXPECT_FALSE(pkp_state.include_subdomains);
}

// Tests that when multiple HPKP headers are present, asserting different
// policies, that only the first such policy is processed.
TEST_F(URLRequestTestHTTP, ProcessSTSAndPKP2) {
  SpawnedTestServer::SSLOptions ssl_options(
      SpawnedTestServer::SSLOptions::CERT_COMMON_NAME_IS_DOMAIN);
  SpawnedTestServer https_test_server(SpawnedTestServer::TYPE_HTTPS,
                                      ssl_options,
                                      base::FilePath(kTestFilePath));
  ASSERT_TRUE(https_test_server.Start());

  std::string test_server_hostname = https_test_server.GetURL("").host();

  TestDelegate d;
  scoped_ptr<URLRequest> request(default_context_.CreateRequest(
      https_test_server.GetURL("files/hsts-and-hpkp-headers2.html"),
      DEFAULT_PRIORITY, &d));
  request->Start();
  base::RunLoop().Run();

  TransportSecurityState* security_state =
      default_context_.transport_security_state();
  TransportSecurityState::STSState sts_state;
  TransportSecurityState::PKPState pkp_state;
  EXPECT_TRUE(
      security_state->GetDynamicSTSState(test_server_hostname, &sts_state));
  EXPECT_TRUE(
      security_state->GetDynamicPKPState(test_server_hostname, &pkp_state));
  EXPECT_EQ(TransportSecurityState::STSState::MODE_FORCE_HTTPS,
            sts_state.upgrade_mode);
#if defined(OS_ANDROID)
  // Android's CertVerifyProc does not (yet) handle pins.
#else
  EXPECT_TRUE(pkp_state.HasPublicKeyPins());
#endif
  EXPECT_NE(sts_state.expiry, pkp_state.expiry);

  EXPECT_TRUE(sts_state.include_subdomains);
  EXPECT_FALSE(pkp_state.include_subdomains);
}

TEST_F(URLRequestTestHTTP, ContentTypeNormalizationTest) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  scoped_ptr<URLRequest> req(default_context_.CreateRequest(
      test_server_.GetURL("files/content-type-normalization.html"),
      DEFAULT_PRIORITY, &d));
  req->Start();
  base::RunLoop().Run();

  std::string mime_type;
  req->GetMimeType(&mime_type);
  EXPECT_EQ("text/html", mime_type);

  std::string charset;
  req->GetCharset(&charset);
  EXPECT_EQ("utf-8", charset);
  req->Cancel();
}

TEST_F(URLRequestTestHTTP, ProtocolHandlerAndFactoryRestrictDataRedirects) {
  // Test URLRequestJobFactory::ProtocolHandler::IsSafeRedirectTarget().
  GURL data_url("data:,foo");
  DataProtocolHandler data_protocol_handler;
  EXPECT_FALSE(data_protocol_handler.IsSafeRedirectTarget(data_url));

  // Test URLRequestJobFactoryImpl::IsSafeRedirectTarget().
  EXPECT_FALSE(job_factory_->IsSafeRedirectTarget(data_url));
}

#if !defined(DISABLE_FILE_SUPPORT)
TEST_F(URLRequestTestHTTP, ProtocolHandlerAndFactoryRestrictFileRedirects) {
  // Test URLRequestJobFactory::ProtocolHandler::IsSafeRedirectTarget().
  GURL file_url("file:///foo.txt");
  FileProtocolHandler file_protocol_handler(
      base::ThreadTaskRunnerHandle::Get());
  EXPECT_FALSE(file_protocol_handler.IsSafeRedirectTarget(file_url));

  // Test URLRequestJobFactoryImpl::IsSafeRedirectTarget().
  EXPECT_FALSE(job_factory_->IsSafeRedirectTarget(file_url));
}

TEST_F(URLRequestTestHTTP, RestrictFileRedirects) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  scoped_ptr<URLRequest> req(default_context_.CreateRequest(
      test_server_.GetURL("files/redirect-to-file.html"), DEFAULT_PRIORITY,
      &d));
  req->Start();
  base::RunLoop().Run();

  EXPECT_EQ(URLRequestStatus::FAILED, req->status().status());
  EXPECT_EQ(ERR_UNSAFE_REDIRECT, req->status().error());
}
#endif  // !defined(DISABLE_FILE_SUPPORT)

TEST_F(URLRequestTestHTTP, RestrictDataRedirects) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  scoped_ptr<URLRequest> req(default_context_.CreateRequest(
      test_server_.GetURL("files/redirect-to-data.html"), DEFAULT_PRIORITY,
      &d));
  req->Start();
  base::MessageLoop::current()->Run();

  EXPECT_EQ(URLRequestStatus::FAILED, req->status().status());
  EXPECT_EQ(ERR_UNSAFE_REDIRECT, req->status().error());
}

TEST_F(URLRequestTestHTTP, RedirectToInvalidURL) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  scoped_ptr<URLRequest> req(default_context_.CreateRequest(
      test_server_.GetURL("files/redirect-to-invalid-url.html"),
      DEFAULT_PRIORITY, &d));
  req->Start();
  base::RunLoop().Run();

  EXPECT_EQ(URLRequestStatus::FAILED, req->status().status());
  EXPECT_EQ(ERR_INVALID_URL, req->status().error());
}

// Make sure redirects are cached, despite not reading their bodies.
TEST_F(URLRequestTestHTTP, CacheRedirect) {
  ASSERT_TRUE(test_server_.Start());
  GURL redirect_url =
      test_server_.GetURL("files/redirect302-to-echo-cacheable");

  {
    TestDelegate d;
    scoped_ptr<URLRequest> req(
        default_context_.CreateRequest(redirect_url, DEFAULT_PRIORITY, &d));
    req->Start();
    base::RunLoop().Run();
    EXPECT_EQ(URLRequestStatus::SUCCESS, req->status().status());
    EXPECT_EQ(1, d.received_redirect_count());
    EXPECT_EQ(test_server_.GetURL("echo"), req->url());
  }

  {
    TestDelegate d;
    d.set_quit_on_redirect(true);
    scoped_ptr<URLRequest> req(
        default_context_.CreateRequest(redirect_url, DEFAULT_PRIORITY, &d));
    req->Start();
    base::RunLoop().Run();

    EXPECT_EQ(1, d.received_redirect_count());
    EXPECT_EQ(0, d.response_started_count());
    EXPECT_TRUE(req->was_cached());

    req->FollowDeferredRedirect();
    base::RunLoop().Run();
    EXPECT_EQ(1, d.received_redirect_count());
    EXPECT_EQ(1, d.response_started_count());
    EXPECT_EQ(URLRequestStatus::SUCCESS, req->status().status());
    EXPECT_EQ(test_server_.GetURL("echo"), req->url());
  }
}

// Make sure a request isn't cached when a NetworkDelegate forces a redirect
// when the headers are read, since the body won't have been read.
TEST_F(URLRequestTestHTTP, NoCacheOnNetworkDelegateRedirect) {
  ASSERT_TRUE(test_server_.Start());
  // URL that is normally cached.
  GURL initial_url = test_server_.GetURL("cachetime");

  {
    // Set up the TestNetworkDelegate tp force a redirect.
    GURL redirect_to_url = test_server_.GetURL("echo");
    default_network_delegate_.set_redirect_on_headers_received_url(
        redirect_to_url);

    TestDelegate d;
    scoped_ptr<URLRequest> req(
        default_context_.CreateRequest(initial_url, DEFAULT_PRIORITY, &d));
    req->Start();
    base::RunLoop().Run();
    EXPECT_EQ(URLRequestStatus::SUCCESS, req->status().status());
    EXPECT_EQ(1, d.received_redirect_count());
    EXPECT_EQ(redirect_to_url, req->url());
  }

  {
    TestDelegate d;
    scoped_ptr<URLRequest> req(
        default_context_.CreateRequest(initial_url, DEFAULT_PRIORITY, &d));
    req->Start();
    base::RunLoop().Run();

    EXPECT_EQ(URLRequestStatus::SUCCESS, req->status().status());
    EXPECT_FALSE(req->was_cached());
    EXPECT_EQ(0, d.received_redirect_count());
    EXPECT_EQ(initial_url, req->url());
  }
}

// Tests that redirection to an unsafe URL is allowed when it has been marked as
// safe.
TEST_F(URLRequestTestHTTP, UnsafeRedirectToWhitelistedUnsafeURL) {
  ASSERT_TRUE(test_server_.Start());

  GURL unsafe_url("data:text/html,this-is-considered-an-unsafe-url");
  default_network_delegate_.set_redirect_on_headers_received_url(unsafe_url);
  default_network_delegate_.set_allowed_unsafe_redirect_url(unsafe_url);

  TestDelegate d;
  {
    scoped_ptr<URLRequest> r(default_context_.CreateRequest(
        test_server_.GetURL("whatever"), DEFAULT_PRIORITY, &d));

    r->Start();
    base::RunLoop().Run();

    EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());

    EXPECT_EQ(2U, r->url_chain().size());
    EXPECT_EQ(OK, r->status().error());
    EXPECT_EQ(unsafe_url, r->url());
    EXPECT_EQ("this-is-considered-an-unsafe-url", d.data_received());
  }
}

// Tests that a redirect to a different unsafe URL is blocked, even after adding
// some other URL to the whitelist.
TEST_F(URLRequestTestHTTP, UnsafeRedirectToDifferentUnsafeURL) {
  ASSERT_TRUE(test_server_.Start());

  GURL unsafe_url("data:text/html,something");
  GURL different_unsafe_url("data:text/html,something-else");
  default_network_delegate_.set_redirect_on_headers_received_url(unsafe_url);
  default_network_delegate_.set_allowed_unsafe_redirect_url(
      different_unsafe_url);

  TestDelegate d;
  {
    scoped_ptr<URLRequest> r(default_context_.CreateRequest(
        test_server_.GetURL("whatever"), DEFAULT_PRIORITY, &d));

    r->Start();
    base::RunLoop().Run();

    EXPECT_EQ(URLRequestStatus::FAILED, r->status().status());
    EXPECT_EQ(ERR_UNSAFE_REDIRECT, r->status().error());
  }
}

// Redirects from an URL with fragment to an unsafe URL with fragment should
// be allowed, and the reference fragment of the target URL should be preserved.
TEST_F(URLRequestTestHTTP, UnsafeRedirectWithDifferentReferenceFragment) {
  ASSERT_TRUE(test_server_.Start());

  GURL original_url(test_server_.GetURL("original#fragment1"));
  GURL unsafe_url("data:,url-marked-safe-and-used-in-redirect#fragment2");
  GURL expected_url("data:,url-marked-safe-and-used-in-redirect#fragment2");

  default_network_delegate_.set_redirect_on_headers_received_url(unsafe_url);
  default_network_delegate_.set_allowed_unsafe_redirect_url(unsafe_url);

  TestDelegate d;
  {
    scoped_ptr<URLRequest> r(
        default_context_.CreateRequest(original_url, DEFAULT_PRIORITY, &d));

    r->Start();
    base::RunLoop().Run();

    EXPECT_EQ(2U, r->url_chain().size());
    EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
    EXPECT_EQ(OK, r->status().error());
    EXPECT_EQ(original_url, r->original_url());
    EXPECT_EQ(expected_url, r->url());
  }
}

// When a delegate has specified a safe redirect URL, but it does not match the
// redirect target, then do not prevent the reference fragment from being added.
TEST_F(URLRequestTestHTTP, RedirectWithReferenceFragmentAndUnrelatedUnsafeUrl) {
  ASSERT_TRUE(test_server_.Start());

  GURL original_url(test_server_.GetURL("original#expected-fragment"));
  GURL unsafe_url("data:text/html,this-url-does-not-match-redirect-url");
  GURL redirect_url(test_server_.GetURL("target"));
  GURL expected_redirect_url(test_server_.GetURL("target#expected-fragment"));

  default_network_delegate_.set_redirect_on_headers_received_url(redirect_url);
  default_network_delegate_.set_allowed_unsafe_redirect_url(unsafe_url);

  TestDelegate d;
  {
    scoped_ptr<URLRequest> r(
        default_context_.CreateRequest(original_url, DEFAULT_PRIORITY, &d));

    r->Start();
    base::RunLoop().Run();

    EXPECT_EQ(2U, r->url_chain().size());
    EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
    EXPECT_EQ(OK, r->status().error());
    EXPECT_EQ(original_url, r->original_url());
    EXPECT_EQ(expected_redirect_url, r->url());
  }
}

// When a delegate has specified a safe redirect URL, assume that the redirect
// URL should not be changed. In particular, the reference fragment should not
// be modified.
TEST_F(URLRequestTestHTTP, RedirectWithReferenceFragment) {
  ASSERT_TRUE(test_server_.Start());

  GURL original_url(test_server_.GetURL("original#should-not-be-appended"));
  GURL redirect_url("data:text/html,expect-no-reference-fragment");

  default_network_delegate_.set_redirect_on_headers_received_url(redirect_url);
  default_network_delegate_.set_allowed_unsafe_redirect_url(redirect_url);

  TestDelegate d;
  {
    scoped_ptr<URLRequest> r(
        default_context_.CreateRequest(original_url, DEFAULT_PRIORITY, &d));

    r->Start();
    base::RunLoop().Run();

    EXPECT_EQ(2U, r->url_chain().size());
    EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
    EXPECT_EQ(OK, r->status().error());
    EXPECT_EQ(original_url, r->original_url());
    EXPECT_EQ(redirect_url, r->url());
  }
}

// When a URLRequestRedirectJob is created, the redirection must be followed and
// the reference fragment of the target URL must not be modified.
TEST_F(URLRequestTestHTTP, RedirectJobWithReferenceFragment) {
  ASSERT_TRUE(test_server_.Start());

  GURL original_url(test_server_.GetURL("original#should-not-be-appended"));
  GURL redirect_url(test_server_.GetURL("echo"));

  TestDelegate d;
  scoped_ptr<URLRequest> r(
      default_context_.CreateRequest(original_url, DEFAULT_PRIORITY, &d));

  URLRequestRedirectJob* job = new URLRequestRedirectJob(
      r.get(), &default_network_delegate_, redirect_url,
      URLRequestRedirectJob::REDIRECT_302_FOUND, "Very Good Reason");
  AddTestInterceptor()->set_main_intercept_job(job);

  r->Start();
  base::RunLoop().Run();

  EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
  EXPECT_EQ(OK, r->status().error());
  EXPECT_EQ(original_url, r->original_url());
  EXPECT_EQ(redirect_url, r->url());
}

TEST_F(URLRequestTestHTTP, NoUserPassInReferrer) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  scoped_ptr<URLRequest> req(default_context_.CreateRequest(
      test_server_.GetURL("echoheader?Referer"), DEFAULT_PRIORITY, &d));
  req->SetReferrer("http://user:pass@foo.com/");
  req->Start();
  base::RunLoop().Run();

  EXPECT_EQ(std::string("http://foo.com/"), d.data_received());
}

TEST_F(URLRequestTestHTTP, NoFragmentInReferrer) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  scoped_ptr<URLRequest> req(default_context_.CreateRequest(
      test_server_.GetURL("echoheader?Referer"), DEFAULT_PRIORITY, &d));
  req->SetReferrer("http://foo.com/test#fragment");
  req->Start();
  base::RunLoop().Run();

  EXPECT_EQ(std::string("http://foo.com/test"), d.data_received());
}

TEST_F(URLRequestTestHTTP, EmptyReferrerAfterValidReferrer) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  scoped_ptr<URLRequest> req(default_context_.CreateRequest(
      test_server_.GetURL("echoheader?Referer"), DEFAULT_PRIORITY, &d));
  req->SetReferrer("http://foo.com/test#fragment");
  req->SetReferrer("");
  req->Start();
  base::RunLoop().Run();

  EXPECT_EQ(std::string("None"), d.data_received());
}

// Defer network start and then resume, checking that the request was a success
// and bytes were received.
TEST_F(URLRequestTestHTTP, DeferredBeforeNetworkStart) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  {
    d.set_quit_on_network_start(true);
    GURL test_url(test_server_.GetURL("echo"));
    scoped_ptr<URLRequest> req(
        default_context_.CreateRequest(test_url, DEFAULT_PRIORITY, &d));

    req->Start();
    base::RunLoop().Run();

    EXPECT_EQ(1, d.received_before_network_start_count());
    EXPECT_EQ(0, d.response_started_count());

    req->ResumeNetworkStart();
    base::RunLoop().Run();

    EXPECT_EQ(1, d.response_started_count());
    EXPECT_NE(0, d.bytes_received());
    EXPECT_EQ(URLRequestStatus::SUCCESS, req->status().status());
  }
}

// Check that OnBeforeNetworkStart is only called once even if there is a
// redirect.
TEST_F(URLRequestTestHTTP, BeforeNetworkStartCalledOnce) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  {
    d.set_quit_on_redirect(true);
    d.set_quit_on_network_start(true);
    scoped_ptr<URLRequest> req(default_context_.CreateRequest(
        test_server_.GetURL("server-redirect?echo"), DEFAULT_PRIORITY, &d));

    req->Start();
    base::RunLoop().Run();

    EXPECT_EQ(1, d.received_before_network_start_count());
    EXPECT_EQ(0, d.response_started_count());
    EXPECT_EQ(0, d.received_redirect_count());

    req->ResumeNetworkStart();
    base::RunLoop().Run();

    EXPECT_EQ(1, d.received_redirect_count());
    req->FollowDeferredRedirect();
    base::RunLoop().Run();

    // Check that the redirect's new network transaction does not get propagated
    // to a second OnBeforeNetworkStart() notification.
    EXPECT_EQ(1, d.received_before_network_start_count());

    EXPECT_EQ(1, d.response_started_count());
    EXPECT_NE(0, d.bytes_received());
    EXPECT_EQ(URLRequestStatus::SUCCESS, req->status().status());
  }
}

// Cancel the request after learning that the request would use the network.
TEST_F(URLRequestTestHTTP, CancelOnBeforeNetworkStart) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  {
    d.set_quit_on_network_start(true);
    GURL test_url(test_server_.GetURL("echo"));
    scoped_ptr<URLRequest> req(
        default_context_.CreateRequest(test_url, DEFAULT_PRIORITY, &d));

    req->Start();
    base::RunLoop().Run();

    EXPECT_EQ(1, d.received_before_network_start_count());
    EXPECT_EQ(0, d.response_started_count());

    req->Cancel();
    base::RunLoop().Run();

    EXPECT_EQ(1, d.response_started_count());
    EXPECT_EQ(0, d.bytes_received());
    EXPECT_EQ(URLRequestStatus::CANCELED, req->status().status());
  }
}

TEST_F(URLRequestTestHTTP, CancelRedirect) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  {
    d.set_cancel_in_received_redirect(true);
    scoped_ptr<URLRequest> req(default_context_.CreateRequest(
        test_server_.GetURL("files/redirect-test.html"), DEFAULT_PRIORITY, &d));
    req->Start();
    base::RunLoop().Run();

    EXPECT_EQ(1, d.response_started_count());
    EXPECT_EQ(0, d.bytes_received());
    EXPECT_FALSE(d.received_data_before_response());
    EXPECT_EQ(URLRequestStatus::CANCELED, req->status().status());
  }
}

TEST_F(URLRequestTestHTTP, DeferredRedirect) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  {
    d.set_quit_on_redirect(true);
    GURL test_url(test_server_.GetURL("files/redirect-test.html"));
    scoped_ptr<URLRequest> req(
        default_context_.CreateRequest(test_url, DEFAULT_PRIORITY, &d));

    req->Start();
    base::RunLoop().Run();

    EXPECT_EQ(1, d.received_redirect_count());

    req->FollowDeferredRedirect();
    base::RunLoop().Run();

    EXPECT_EQ(1, d.response_started_count());
    EXPECT_FALSE(d.received_data_before_response());
    EXPECT_EQ(URLRequestStatus::SUCCESS, req->status().status());

    base::FilePath path;
    PathService::Get(base::DIR_SOURCE_ROOT, &path);
    path = path.Append(kTestFilePath);
    path = path.Append(FILE_PATH_LITERAL("with-headers.html"));

    std::string contents;
    EXPECT_TRUE(base::ReadFileToString(path, &contents));
    EXPECT_EQ(contents, d.data_received());
  }
}

TEST_F(URLRequestTestHTTP, DeferredRedirect_GetFullRequestHeaders) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  {
    d.set_quit_on_redirect(true);
    GURL test_url(test_server_.GetURL("files/redirect-test.html"));
    scoped_ptr<URLRequest> req(
        default_context_.CreateRequest(test_url, DEFAULT_PRIORITY, &d));

    EXPECT_FALSE(d.have_full_request_headers());

    req->Start();
    base::RunLoop().Run();

    EXPECT_EQ(1, d.received_redirect_count());
    EXPECT_TRUE(d.have_full_request_headers());
    CheckFullRequestHeaders(d.full_request_headers(), test_url);
    d.ClearFullRequestHeaders();

    req->FollowDeferredRedirect();
    base::RunLoop().Run();

    GURL target_url(test_server_.GetURL("files/with-headers.html"));
    EXPECT_EQ(1, d.response_started_count());
    EXPECT_TRUE(d.have_full_request_headers());
    CheckFullRequestHeaders(d.full_request_headers(), target_url);
    EXPECT_FALSE(d.received_data_before_response());
    EXPECT_EQ(URLRequestStatus::SUCCESS, req->status().status());

    base::FilePath path;
    PathService::Get(base::DIR_SOURCE_ROOT, &path);
    path = path.Append(kTestFilePath);
    path = path.Append(FILE_PATH_LITERAL("with-headers.html"));

    std::string contents;
    EXPECT_TRUE(base::ReadFileToString(path, &contents));
    EXPECT_EQ(contents, d.data_received());
  }
}

TEST_F(URLRequestTestHTTP, CancelDeferredRedirect) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  {
    d.set_quit_on_redirect(true);
    scoped_ptr<URLRequest> req(default_context_.CreateRequest(
        test_server_.GetURL("files/redirect-test.html"), DEFAULT_PRIORITY, &d));
    req->Start();
    base::RunLoop().Run();

    EXPECT_EQ(1, d.received_redirect_count());

    req->Cancel();
    base::RunLoop().Run();

    EXPECT_EQ(1, d.response_started_count());
    EXPECT_EQ(0, d.bytes_received());
    EXPECT_FALSE(d.received_data_before_response());
    EXPECT_EQ(URLRequestStatus::CANCELED, req->status().status());
  }
}

TEST_F(URLRequestTestHTTP, VaryHeader) {
  ASSERT_TRUE(test_server_.Start());

  // Populate the cache.
  {
    TestDelegate d;
    scoped_ptr<URLRequest> req(default_context_.CreateRequest(
        test_server_.GetURL("echoheadercache?foo"), DEFAULT_PRIORITY, &d));
    HttpRequestHeaders headers;
    headers.SetHeader("foo", "1");
    req->SetExtraRequestHeaders(headers);
    req->Start();
    base::RunLoop().Run();

    LoadTimingInfo load_timing_info;
    req->GetLoadTimingInfo(&load_timing_info);
    TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
  }

  // Expect a cache hit.
  {
    TestDelegate d;
    scoped_ptr<URLRequest> req(default_context_.CreateRequest(
        test_server_.GetURL("echoheadercache?foo"), DEFAULT_PRIORITY, &d));
    HttpRequestHeaders headers;
    headers.SetHeader("foo", "1");
    req->SetExtraRequestHeaders(headers);
    req->Start();
    base::RunLoop().Run();

    EXPECT_TRUE(req->was_cached());

    LoadTimingInfo load_timing_info;
    req->GetLoadTimingInfo(&load_timing_info);
    TestLoadTimingCacheHitNoNetwork(load_timing_info);
  }

  // Expect a cache miss.
  {
    TestDelegate d;
    scoped_ptr<URLRequest> req(default_context_.CreateRequest(
        test_server_.GetURL("echoheadercache?foo"), DEFAULT_PRIORITY, &d));
    HttpRequestHeaders headers;
    headers.SetHeader("foo", "2");
    req->SetExtraRequestHeaders(headers);
    req->Start();
    base::RunLoop().Run();

    EXPECT_FALSE(req->was_cached());

    LoadTimingInfo load_timing_info;
    req->GetLoadTimingInfo(&load_timing_info);
    TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
  }
}

TEST_F(URLRequestTestHTTP, BasicAuth) {
  ASSERT_TRUE(test_server_.Start());

  // populate the cache
  {
    TestDelegate d;
    d.set_credentials(AuthCredentials(kUser, kSecret));

    scoped_ptr<URLRequest> r(default_context_.CreateRequest(
        test_server_.GetURL("auth-basic"), DEFAULT_PRIORITY, &d));
    r->Start();

    base::RunLoop().Run();

    EXPECT_TRUE(d.data_received().find("user/secret") != std::string::npos);
  }

  // repeat request with end-to-end validation.  since auth-basic results in a
  // cachable page, we expect this test to result in a 304.  in which case, the
  // response should be fetched from the cache.
  {
    TestDelegate d;
    d.set_credentials(AuthCredentials(kUser, kSecret));

    scoped_ptr<URLRequest> r(default_context_.CreateRequest(
        test_server_.GetURL("auth-basic"), DEFAULT_PRIORITY, &d));
    r->SetLoadFlags(LOAD_VALIDATE_CACHE);
    r->Start();

    base::RunLoop().Run();

    EXPECT_TRUE(d.data_received().find("user/secret") != std::string::npos);

    // Should be the same cached document.
    EXPECT_TRUE(r->was_cached());
  }
}

// Check that Set-Cookie headers in 401 responses are respected.
// http://crbug.com/6450
TEST_F(URLRequestTestHTTP, BasicAuthWithCookies) {
  ASSERT_TRUE(test_server_.Start());

  GURL url_requiring_auth =
      test_server_.GetURL("auth-basic?set-cookie-if-challenged");

  // Request a page that will give a 401 containing a Set-Cookie header.
  // Verify that when the transaction is restarted, it includes the new cookie.
  {
    TestNetworkDelegate network_delegate;  // Must outlive URLRequest.
    TestURLRequestContext context(true);
    context.set_network_delegate(&network_delegate);
    context.Init();

    TestDelegate d;
    d.set_credentials(AuthCredentials(kUser, kSecret));

    scoped_ptr<URLRequest> r(
        context.CreateRequest(url_requiring_auth, DEFAULT_PRIORITY, &d));
    r->Start();

    base::RunLoop().Run();

    EXPECT_TRUE(d.data_received().find("user/secret") != std::string::npos);

    // Make sure we sent the cookie in the restarted transaction.
    EXPECT_TRUE(d.data_received().find("Cookie: got_challenged=true")
        != std::string::npos);
  }

  // Same test as above, except this time the restart is initiated earlier
  // (without user intervention since identity is embedded in the URL).
  {
    TestNetworkDelegate network_delegate;  // Must outlive URLRequest.
    TestURLRequestContext context(true);
    context.set_network_delegate(&network_delegate);
    context.Init();

    TestDelegate d;

    GURL::Replacements replacements;
    replacements.SetUsernameStr("user2");
    replacements.SetPasswordStr("secret");
    GURL url_with_identity = url_requiring_auth.ReplaceComponents(replacements);

    scoped_ptr<URLRequest> r(
        context.CreateRequest(url_with_identity, DEFAULT_PRIORITY, &d));
    r->Start();

    base::RunLoop().Run();

    EXPECT_TRUE(d.data_received().find("user2/secret") != std::string::npos);

    // Make sure we sent the cookie in the restarted transaction.
    EXPECT_TRUE(d.data_received().find("Cookie: got_challenged=true")
        != std::string::npos);
  }
}

// Tests that load timing works as expected with auth and the cache.
TEST_F(URLRequestTestHTTP, BasicAuthLoadTiming) {
  ASSERT_TRUE(test_server_.Start());

  // populate the cache
  {
    TestDelegate d;
    d.set_credentials(AuthCredentials(kUser, kSecret));

    scoped_ptr<URLRequest> r(default_context_.CreateRequest(
        test_server_.GetURL("auth-basic"), DEFAULT_PRIORITY, &d));
    r->Start();

    base::RunLoop().Run();

    EXPECT_TRUE(d.data_received().find("user/secret") != std::string::npos);

    LoadTimingInfo load_timing_info_before_auth;
    EXPECT_TRUE(default_network_delegate_.GetLoadTimingInfoBeforeAuth(
        &load_timing_info_before_auth));
    TestLoadTimingNotReused(load_timing_info_before_auth,
                            CONNECT_TIMING_HAS_DNS_TIMES);

    LoadTimingInfo load_timing_info;
    r->GetLoadTimingInfo(&load_timing_info);
    // The test server does not support keep alive sockets, so the second
    // request with auth should use a new socket.
    TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
    EXPECT_NE(load_timing_info_before_auth.socket_log_id,
              load_timing_info.socket_log_id);
    EXPECT_LE(load_timing_info_before_auth.receive_headers_end,
              load_timing_info.connect_timing.connect_start);
  }

  // Repeat request with end-to-end validation.  Since auth-basic results in a
  // cachable page, we expect this test to result in a 304.  In which case, the
  // response should be fetched from the cache.
  {
    TestDelegate d;
    d.set_credentials(AuthCredentials(kUser, kSecret));

    scoped_ptr<URLRequest> r(default_context_.CreateRequest(
        test_server_.GetURL("auth-basic"), DEFAULT_PRIORITY, &d));
    r->SetLoadFlags(LOAD_VALIDATE_CACHE);
    r->Start();

    base::RunLoop().Run();

    EXPECT_TRUE(d.data_received().find("user/secret") != std::string::npos);

    // Should be the same cached document.
    EXPECT_TRUE(r->was_cached());

    // Since there was a request that went over the wire, the load timing
    // information should include connection times.
    LoadTimingInfo load_timing_info;
    r->GetLoadTimingInfo(&load_timing_info);
    TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
  }
}

// In this test, we do a POST which the server will 302 redirect.
// The subsequent transaction should use GET, and should not send the
// Content-Type header.
// http://code.google.com/p/chromium/issues/detail?id=843
TEST_F(URLRequestTestHTTP, Post302RedirectGet) {
  ASSERT_TRUE(test_server_.Start());

  const char kData[] = "hello world";

  TestDelegate d;
  scoped_ptr<URLRequest> req(default_context_.CreateRequest(
      test_server_.GetURL("files/redirect-to-echoall"), DEFAULT_PRIORITY, &d));
  req->set_method("POST");
  req->set_upload(CreateSimpleUploadData(kData));

  // Set headers (some of which are specific to the POST).
  HttpRequestHeaders headers;
  headers.AddHeadersFromString(
    "Content-Type: multipart/form-data; "
    "boundary=----WebKitFormBoundaryAADeAA+NAAWMAAwZ\r\n"
    "Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,"
    "text/plain;q=0.8,image/png,*/*;q=0.5\r\n"
    "Accept-Language: en-US,en\r\n"
    "Accept-Charset: ISO-8859-1,*,utf-8\r\n"
    "Content-Length: 11\r\n"
    "Origin: http://localhost:1337/");
  req->SetExtraRequestHeaders(headers);
  req->Start();
  base::RunLoop().Run();

  std::string mime_type;
  req->GetMimeType(&mime_type);
  EXPECT_EQ("text/html", mime_type);

  const std::string& data = d.data_received();

  // Check that the post-specific headers were stripped:
  EXPECT_FALSE(ContainsString(data, "Content-Length:"));
  EXPECT_FALSE(ContainsString(data, "Content-Type:"));
  EXPECT_FALSE(ContainsString(data, "Origin:"));

  // These extra request headers should not have been stripped.
  EXPECT_TRUE(ContainsString(data, "Accept:"));
  EXPECT_TRUE(ContainsString(data, "Accept-Language:"));
  EXPECT_TRUE(ContainsString(data, "Accept-Charset:"));
}

// The following tests check that we handle mutating the request for HTTP
// redirects as expected.
// See https://crbug.com/56373, https://crbug.com/102130, and
// https://crbug.com/465517.

TEST_F(URLRequestTestHTTP, Redirect301Tests) {
  ASSERT_TRUE(test_server_.Start());

  const GURL url = test_server_.GetURL("files/redirect301-to-echo");
  const GURL https_redirect_url =
      test_server_.GetURL("files/redirect301-to-https");

  HTTPRedirectMethodTest(url, "POST", "GET", true);
  HTTPRedirectMethodTest(url, "PUT", "PUT", true);
  HTTPRedirectMethodTest(url, "HEAD", "HEAD", false);

  HTTPRedirectOriginHeaderTest(url, "GET", "GET", url.GetOrigin().spec());
  HTTPRedirectOriginHeaderTest(https_redirect_url, "GET", "GET", "null");
  HTTPRedirectOriginHeaderTest(url, "POST", "GET", std::string());
  HTTPRedirectOriginHeaderTest(https_redirect_url, "POST", "GET",
                               std::string());
}

TEST_F(URLRequestTestHTTP, Redirect302Tests) {
  ASSERT_TRUE(test_server_.Start());

  const GURL url = test_server_.GetURL("files/redirect302-to-echo");
  const GURL https_redirect_url =
      test_server_.GetURL("files/redirect302-to-https");

  HTTPRedirectMethodTest(url, "POST", "GET", true);
  HTTPRedirectMethodTest(url, "PUT", "PUT", true);
  HTTPRedirectMethodTest(url, "HEAD", "HEAD", false);

  HTTPRedirectOriginHeaderTest(url, "GET", "GET", url.GetOrigin().spec());
  HTTPRedirectOriginHeaderTest(https_redirect_url, "GET", "GET", "null");
  HTTPRedirectOriginHeaderTest(url, "POST", "GET", std::string());
  HTTPRedirectOriginHeaderTest(https_redirect_url, "POST", "GET",
                               std::string());
}

TEST_F(URLRequestTestHTTP, Redirect303Tests) {
  ASSERT_TRUE(test_server_.Start());

  const GURL url = test_server_.GetURL("files/redirect303-to-echo");
  const GURL https_redirect_url =
      test_server_.GetURL("files/redirect303-to-https");

  HTTPRedirectMethodTest(url, "POST", "GET", true);
  HTTPRedirectMethodTest(url, "PUT", "GET", true);
  HTTPRedirectMethodTest(url, "HEAD", "HEAD", false);

  HTTPRedirectOriginHeaderTest(url, "GET", "GET", url.GetOrigin().spec());
  HTTPRedirectOriginHeaderTest(https_redirect_url, "GET", "GET", "null");
  HTTPRedirectOriginHeaderTest(url, "POST", "GET", std::string());
  HTTPRedirectOriginHeaderTest(https_redirect_url, "POST", "GET",
                               std::string());
}

TEST_F(URLRequestTestHTTP, Redirect307Tests) {
  ASSERT_TRUE(test_server_.Start());

  const GURL url = test_server_.GetURL("files/redirect307-to-echo");
  const GURL https_redirect_url =
      test_server_.GetURL("files/redirect307-to-https");

  HTTPRedirectMethodTest(url, "POST", "POST", true);
  HTTPRedirectMethodTest(url, "PUT", "PUT", true);
  HTTPRedirectMethodTest(url, "HEAD", "HEAD", false);

  HTTPRedirectOriginHeaderTest(url, "GET", "GET", url.GetOrigin().spec());
  HTTPRedirectOriginHeaderTest(https_redirect_url, "GET", "GET", "null");
  HTTPRedirectOriginHeaderTest(url, "POST", "POST", url.GetOrigin().spec());
  HTTPRedirectOriginHeaderTest(https_redirect_url, "POST", "POST", "null");
}

TEST_F(URLRequestTestHTTP, Redirect308Tests) {
  ASSERT_TRUE(test_server_.Start());

  const GURL url = test_server_.GetURL("files/redirect308-to-echo");
  const GURL https_redirect_url =
      test_server_.GetURL("files/redirect308-to-https");

  HTTPRedirectMethodTest(url, "POST", "POST", true);
  HTTPRedirectMethodTest(url, "PUT", "PUT", true);
  HTTPRedirectMethodTest(url, "HEAD", "HEAD", false);

  HTTPRedirectOriginHeaderTest(url, "GET", "GET", url.GetOrigin().spec());
  HTTPRedirectOriginHeaderTest(https_redirect_url, "GET", "GET", "null");
  HTTPRedirectOriginHeaderTest(url, "POST", "POST", url.GetOrigin().spec());
  HTTPRedirectOriginHeaderTest(https_redirect_url, "POST", "POST", "null");
}

// Make sure that 308 responses without bodies are not treated as redirects.
// Certain legacy apis that pre-date the response code expect this behavior
// (Like Google Drive).
TEST_F(URLRequestTestHTTP, NoRedirectOn308WithoutLocationHeader) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  const GURL url = test_server_.GetURL("files/308-without-location-header");

  scoped_ptr<URLRequest> request(
      default_context_.CreateRequest(url, DEFAULT_PRIORITY, &d));

  request->Start();
  base::RunLoop().Run();
  EXPECT_EQ(URLRequestStatus::SUCCESS, request->status().status());
  EXPECT_EQ(OK, request->status().error());
  EXPECT_EQ(0, d.received_redirect_count());
  EXPECT_EQ(308, request->response_headers()->response_code());
  EXPECT_EQ("This is not a redirect.", d.data_received());
}

TEST_F(URLRequestTestHTTP, Redirect302PreserveReferenceFragment) {
  ASSERT_TRUE(test_server_.Start());

  GURL original_url(test_server_.GetURL("files/redirect302-to-echo#fragment"));
  GURL expected_url(test_server_.GetURL("echo#fragment"));

  TestDelegate d;
  {
    scoped_ptr<URLRequest> r(
        default_context_.CreateRequest(original_url, DEFAULT_PRIORITY, &d));

    r->Start();
    base::RunLoop().Run();

    EXPECT_EQ(2U, r->url_chain().size());
    EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
    EXPECT_EQ(OK, r->status().error());
    EXPECT_EQ(original_url, r->original_url());
    EXPECT_EQ(expected_url, r->url());
  }
}

TEST_F(URLRequestTestHTTP, RedirectPreserveFirstPartyURL) {
  ASSERT_TRUE(test_server_.Start());

  GURL url(test_server_.GetURL("files/redirect302-to-echo"));
  GURL first_party_url("http://example.com");

  TestDelegate d;
  {
    scoped_ptr<URLRequest> r(
        default_context_.CreateRequest(url, DEFAULT_PRIORITY, &d));
    r->set_first_party_for_cookies(first_party_url);

    r->Start();
    base::RunLoop().Run();

    EXPECT_EQ(2U, r->url_chain().size());
    EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
    EXPECT_EQ(OK, r->status().error());
    EXPECT_EQ(first_party_url, r->first_party_for_cookies());
  }
}

TEST_F(URLRequestTestHTTP, RedirectUpdateFirstPartyURL) {
  ASSERT_TRUE(test_server_.Start());

  GURL url(test_server_.GetURL("files/redirect302-to-echo"));
  GURL original_first_party_url("http://example.com");
  GURL expected_first_party_url(test_server_.GetURL("echo"));

  TestDelegate d;
  {
    scoped_ptr<URLRequest> r(
        default_context_.CreateRequest(url, DEFAULT_PRIORITY, &d));
    r->set_first_party_for_cookies(original_first_party_url);
    r->set_first_party_url_policy(
        URLRequest::UPDATE_FIRST_PARTY_URL_ON_REDIRECT);

    r->Start();
    base::RunLoop().Run();

    EXPECT_EQ(2U, r->url_chain().size());
    EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
    EXPECT_EQ(OK, r->status().error());
    EXPECT_EQ(expected_first_party_url, r->first_party_for_cookies());
  }
}

TEST_F(URLRequestTestHTTP, InterceptPost302RedirectGet) {
  ASSERT_TRUE(test_server_.Start());

  const char kData[] = "hello world";

  TestDelegate d;
  scoped_ptr<URLRequest> req(default_context_.CreateRequest(
      test_server_.GetURL("empty.html"), DEFAULT_PRIORITY, &d));
  req->set_method("POST");
  req->set_upload(CreateSimpleUploadData(kData));
  HttpRequestHeaders headers;
  headers.SetHeader(HttpRequestHeaders::kContentLength,
                    base::SizeTToString(arraysize(kData) - 1));
  req->SetExtraRequestHeaders(headers);

  URLRequestRedirectJob* job = new URLRequestRedirectJob(
      req.get(), &default_network_delegate_, test_server_.GetURL("echo"),
      URLRequestRedirectJob::REDIRECT_302_FOUND, "Very Good Reason");
  AddTestInterceptor()->set_main_intercept_job(job);

  req->Start();
  base::RunLoop().Run();
  EXPECT_EQ("GET", req->method());
}

TEST_F(URLRequestTestHTTP, InterceptPost307RedirectPost) {
  ASSERT_TRUE(test_server_.Start());

  const char kData[] = "hello world";

  TestDelegate d;
  scoped_ptr<URLRequest> req(default_context_.CreateRequest(
      test_server_.GetURL("empty.html"), DEFAULT_PRIORITY, &d));
  req->set_method("POST");
  req->set_upload(CreateSimpleUploadData(kData));
  HttpRequestHeaders headers;
  headers.SetHeader(HttpRequestHeaders::kContentLength,
                    base::SizeTToString(arraysize(kData) - 1));
  req->SetExtraRequestHeaders(headers);

  URLRequestRedirectJob* job = new URLRequestRedirectJob(
      req.get(), &default_network_delegate_, test_server_.GetURL("echo"),
      URLRequestRedirectJob::REDIRECT_307_TEMPORARY_REDIRECT,
      "Very Good Reason");
  AddTestInterceptor()->set_main_intercept_job(job);

  req->Start();
  base::RunLoop().Run();
  EXPECT_EQ("POST", req->method());
  EXPECT_EQ(kData, d.data_received());
}

// Check that default A-L header is sent.
TEST_F(URLRequestTestHTTP, DefaultAcceptLanguage) {
  ASSERT_TRUE(test_server_.Start());

  StaticHttpUserAgentSettings settings("en", std::string());
  TestNetworkDelegate network_delegate;  // Must outlive URLRequests.
  TestURLRequestContext context(true);
  context.set_network_delegate(&network_delegate);
  context.set_http_user_agent_settings(&settings);
  context.Init();

  TestDelegate d;
  scoped_ptr<URLRequest> req(context.CreateRequest(
      test_server_.GetURL("echoheader?Accept-Language"), DEFAULT_PRIORITY, &d));
  req->Start();
  base::RunLoop().Run();
  EXPECT_EQ("en", d.data_received());
}

// Check that an empty A-L header is not sent. http://crbug.com/77365.
TEST_F(URLRequestTestHTTP, EmptyAcceptLanguage) {
  ASSERT_TRUE(test_server_.Start());

  std::string empty_string;  // Avoid most vexing parse on line below.
  StaticHttpUserAgentSettings settings(empty_string, empty_string);
  TestNetworkDelegate network_delegate;  // Must outlive URLRequests.
  TestURLRequestContext context(true);
  context.set_network_delegate(&network_delegate);
  context.Init();
  // We override the language after initialization because empty entries
  // get overridden by Init().
  context.set_http_user_agent_settings(&settings);

  TestDelegate d;
  scoped_ptr<URLRequest> req(context.CreateRequest(
      test_server_.GetURL("echoheader?Accept-Language"), DEFAULT_PRIORITY, &d));
  req->Start();
  base::RunLoop().Run();
  EXPECT_EQ("None", d.data_received());
}

// Check that if request overrides the A-L header, the default is not appended.
// See http://crbug.com/20894
TEST_F(URLRequestTestHTTP, OverrideAcceptLanguage) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  scoped_ptr<URLRequest> req(default_context_.CreateRequest(
      test_server_.GetURL("echoheader?Accept-Language"), DEFAULT_PRIORITY, &d));
  HttpRequestHeaders headers;
  headers.SetHeader(HttpRequestHeaders::kAcceptLanguage, "ru");
  req->SetExtraRequestHeaders(headers);
  req->Start();
  base::RunLoop().Run();
  EXPECT_EQ(std::string("ru"), d.data_received());
}

// Check that default A-E header is sent.
TEST_F(URLRequestTestHTTP, DefaultAcceptEncoding) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  scoped_ptr<URLRequest> req(default_context_.CreateRequest(
      test_server_.GetURL("echoheader?Accept-Encoding"), DEFAULT_PRIORITY, &d));
  HttpRequestHeaders headers;
  req->SetExtraRequestHeaders(headers);
  req->Start();
  base::RunLoop().Run();
  EXPECT_TRUE(ContainsString(d.data_received(), "gzip"));
}

// Check that if request overrides the A-E header, the default is not appended.
// See http://crbug.com/47381
TEST_F(URLRequestTestHTTP, OverrideAcceptEncoding) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  scoped_ptr<URLRequest> req(default_context_.CreateRequest(
      test_server_.GetURL("echoheader?Accept-Encoding"), DEFAULT_PRIORITY, &d));
  HttpRequestHeaders headers;
  headers.SetHeader(HttpRequestHeaders::kAcceptEncoding, "identity");
  req->SetExtraRequestHeaders(headers);
  req->Start();
  base::RunLoop().Run();
  EXPECT_FALSE(ContainsString(d.data_received(), "gzip"));
  EXPECT_TRUE(ContainsString(d.data_received(), "identity"));
}

// Check that setting the A-C header sends the proper header.
TEST_F(URLRequestTestHTTP, SetAcceptCharset) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  scoped_ptr<URLRequest> req(default_context_.CreateRequest(
      test_server_.GetURL("echoheader?Accept-Charset"), DEFAULT_PRIORITY, &d));
  HttpRequestHeaders headers;
  headers.SetHeader(HttpRequestHeaders::kAcceptCharset, "koi-8r");
  req->SetExtraRequestHeaders(headers);
  req->Start();
  base::RunLoop().Run();
  EXPECT_EQ(std::string("koi-8r"), d.data_received());
}

// Check that default User-Agent header is sent.
TEST_F(URLRequestTestHTTP, DefaultUserAgent) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  scoped_ptr<URLRequest> req(default_context_.CreateRequest(
      test_server_.GetURL("echoheader?User-Agent"), DEFAULT_PRIORITY, &d));
  req->Start();
  base::RunLoop().Run();
  EXPECT_EQ(default_context_.http_user_agent_settings()->GetUserAgent(),
            d.data_received());
}

// Check that if request overrides the User-Agent header,
// the default is not appended.
TEST_F(URLRequestTestHTTP, OverrideUserAgent) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  scoped_ptr<URLRequest> req(default_context_.CreateRequest(
      test_server_.GetURL("echoheader?User-Agent"), DEFAULT_PRIORITY, &d));
  HttpRequestHeaders headers;
  headers.SetHeader(HttpRequestHeaders::kUserAgent, "Lynx (textmode)");
  req->SetExtraRequestHeaders(headers);
  req->Start();
  base::RunLoop().Run();
  EXPECT_EQ(std::string("Lynx (textmode)"), d.data_received());
}

// Check that a NULL HttpUserAgentSettings causes the corresponding empty
// User-Agent header to be sent but does not send the Accept-Language and
// Accept-Charset headers.
TEST_F(URLRequestTestHTTP, EmptyHttpUserAgentSettings) {
  ASSERT_TRUE(test_server_.Start());

  TestNetworkDelegate network_delegate;  // Must outlive URLRequests.
  TestURLRequestContext context(true);
  context.set_network_delegate(&network_delegate);
  context.Init();
  // We override the HttpUserAgentSettings after initialization because empty
  // entries get overridden by Init().
  context.set_http_user_agent_settings(NULL);

  struct {
    const char* request;
    const char* expected_response;
  } tests[] = { { "echoheader?Accept-Language", "None" },
                { "echoheader?Accept-Charset", "None" },
                { "echoheader?User-Agent", "" } };

  for (size_t i = 0; i < arraysize(tests); i++) {
    TestDelegate d;
    scoped_ptr<URLRequest> req(context.CreateRequest(
        test_server_.GetURL(tests[i].request), DEFAULT_PRIORITY, &d));
    req->Start();
    base::RunLoop().Run();
    EXPECT_EQ(tests[i].expected_response, d.data_received())
        << " Request = \"" << tests[i].request << "\"";
  }
}

// Make sure that URLRequest passes on its priority updates to
// newly-created jobs after the first one.
TEST_F(URLRequestTestHTTP, SetSubsequentJobPriority) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  scoped_ptr<URLRequest> req(default_context_.CreateRequest(
      test_server_.GetURL("empty.html"), DEFAULT_PRIORITY, &d));
  EXPECT_EQ(DEFAULT_PRIORITY, req->priority());

  scoped_refptr<URLRequestRedirectJob> redirect_job =
      new URLRequestRedirectJob(
          req.get(), &default_network_delegate_, test_server_.GetURL("echo"),
          URLRequestRedirectJob::REDIRECT_302_FOUND, "Very Good Reason");
  AddTestInterceptor()->set_main_intercept_job(redirect_job.get());

  req->SetPriority(LOW);
  req->Start();
  EXPECT_TRUE(req->is_pending());

  scoped_refptr<URLRequestTestJob> job =
      new URLRequestTestJob(req.get(), &default_network_delegate_);
  AddTestInterceptor()->set_main_intercept_job(job.get());

  // Should trigger |job| to be started.
  base::RunLoop().Run();
  EXPECT_EQ(LOW, job->priority());
}

// Check that creating a network request while entering/exiting suspend mode
// fails as it should.  This is the only case where an HttpTransactionFactory
// does not return an HttpTransaction.
TEST_F(URLRequestTestHTTP, NetworkSuspendTest) {
  // Create a new HttpNetworkLayer that thinks it's suspended.
  HttpNetworkSession::Params params;
  params.host_resolver = default_context_.host_resolver();
  params.cert_verifier = default_context_.cert_verifier();
  params.transport_security_state = default_context_.transport_security_state();
  params.proxy_service = default_context_.proxy_service();
  params.ssl_config_service = default_context_.ssl_config_service();
  params.http_auth_handler_factory =
      default_context_.http_auth_handler_factory();
  params.network_delegate = &default_network_delegate_;
  params.http_server_properties = default_context_.http_server_properties();
  scoped_ptr<HttpNetworkLayer> network_layer(
      new HttpNetworkLayer(new HttpNetworkSession(params)));
  network_layer->OnSuspend();

  HttpCache http_cache(network_layer.release(), default_context_.net_log(),
                       HttpCache::DefaultBackend::InMemory(0));

  TestURLRequestContext context(true);
  context.set_http_transaction_factory(&http_cache);
  context.Init();

  TestDelegate d;
  scoped_ptr<URLRequest> req(
      context.CreateRequest(GURL("http://127.0.0.1/"), DEFAULT_PRIORITY, &d));
  req->Start();
  base::RunLoop().Run();

  EXPECT_TRUE(d.request_failed());
  EXPECT_EQ(URLRequestStatus::FAILED, req->status().status());
  EXPECT_EQ(ERR_NETWORK_IO_SUSPENDED, req->status().error());
}

// Check that creating a network request while entering/exiting suspend mode
// fails as it should in the case there is no cache.  This is the only case
// where an HttpTransactionFactory does not return an HttpTransaction.
TEST_F(URLRequestTestHTTP, NetworkSuspendTestNoCache) {
  // Create a new HttpNetworkLayer that thinks it's suspended.
  HttpNetworkSession::Params params;
  params.host_resolver = default_context_.host_resolver();
  params.cert_verifier = default_context_.cert_verifier();
  params.transport_security_state = default_context_.transport_security_state();
  params.proxy_service = default_context_.proxy_service();
  params.ssl_config_service = default_context_.ssl_config_service();
  params.http_auth_handler_factory =
      default_context_.http_auth_handler_factory();
  params.network_delegate = &default_network_delegate_;
  params.http_server_properties = default_context_.http_server_properties();
  HttpNetworkLayer network_layer(new HttpNetworkSession(params));
  network_layer.OnSuspend();

  TestURLRequestContext context(true);
  context.set_http_transaction_factory(&network_layer);
  context.Init();

  TestDelegate d;
  scoped_ptr<URLRequest> req(
      context.CreateRequest(GURL("http://127.0.0.1/"), DEFAULT_PRIORITY, &d));
  req->Start();
  base::RunLoop().Run();

  EXPECT_TRUE(d.request_failed());
  EXPECT_EQ(URLRequestStatus::FAILED, req->status().status());
  EXPECT_EQ(ERR_NETWORK_IO_SUSPENDED, req->status().error());
}

TEST_F(URLRequestTestHTTP, NetworkAccessedSetOnNetworkRequest) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  GURL test_url(test_server_.GetURL(std::string()));
  scoped_ptr<URLRequest> req(
      default_context_.CreateRequest(test_url, DEFAULT_PRIORITY, &d));

  req->Start();
  base::RunLoop().Run();

  EXPECT_TRUE(req->response_info().network_accessed);
}

TEST_F(URLRequestTestHTTP, NetworkAccessedClearOnCachedResponse) {
  ASSERT_TRUE(test_server_.Start());

  // Populate the cache.
  TestDelegate d;
  scoped_ptr<URLRequest> req(default_context_.CreateRequest(
      test_server_.GetURL("cachetime"), DEFAULT_PRIORITY, &d));
  req->Start();
  base::RunLoop().Run();

  EXPECT_EQ(URLRequestStatus::SUCCESS, req->status().status());
  EXPECT_TRUE(req->response_info().network_accessed);
  EXPECT_FALSE(req->response_info().was_cached);

  req = default_context_.CreateRequest(test_server_.GetURL("cachetime"),
                                       DEFAULT_PRIORITY, &d);
  req->Start();
  base::RunLoop().Run();

  EXPECT_EQ(URLRequestStatus::SUCCESS, req->status().status());
  EXPECT_FALSE(req->response_info().network_accessed);
  EXPECT_TRUE(req->response_info().was_cached);
}

TEST_F(URLRequestTestHTTP, NetworkAccessedClearOnLoadOnlyFromCache) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  GURL test_url(test_server_.GetURL(std::string()));
  scoped_ptr<URLRequest> req(
      default_context_.CreateRequest(test_url, DEFAULT_PRIORITY, &d));
  req->SetLoadFlags(LOAD_ONLY_FROM_CACHE);

  req->Start();
  base::RunLoop().Run();

  EXPECT_FALSE(req->response_info().network_accessed);
}

class URLRequestInterceptorTestHTTP : public URLRequestTestHTTP {
 public:
  // TODO(bengr): Merge this with the URLRequestInterceptorHTTPTest fixture,
  // ideally remove the dependency on URLRequestTestJob, and maybe move these
  // tests into the factory tests.
  URLRequestInterceptorTestHTTP() : URLRequestTestHTTP(), interceptor_(NULL) {
  }

  void SetUpFactory() override {
    interceptor_ = new MockURLRequestInterceptor();
    job_factory_.reset(new URLRequestInterceptingJobFactory(
        job_factory_.Pass(), make_scoped_ptr(interceptor_)));
  }

  MockURLRequestInterceptor* interceptor() const {
    return interceptor_;
  }

 private:
  MockURLRequestInterceptor* interceptor_;
};

TEST_F(URLRequestInterceptorTestHTTP,
       NetworkDelegateNotificationOnRedirectIntercept) {
  interceptor()->set_intercept_redirect(true);
  interceptor()->set_redirect_headers(MockURLRequestInterceptor::ok_headers());
  interceptor()->set_redirect_data(MockURLRequestInterceptor::ok_data());

  ASSERT_TRUE(test_server()->Start());

  TestDelegate d;
  scoped_ptr<URLRequest> req(default_context().CreateRequest(
      test_server()->GetURL("files/redirect-test.html"), DEFAULT_PRIORITY, &d));
  req->Start();
  base::RunLoop().Run();

  EXPECT_TRUE(interceptor()->did_intercept_redirect());
  // Check we got one good response
  EXPECT_TRUE(req->status().is_success());
  if (req->status().is_success())
    EXPECT_EQ(200, req->response_headers()->response_code());

  EXPECT_EQ(MockURLRequestInterceptor::ok_data(), d.data_received());
  EXPECT_EQ(1, d.response_started_count());
  EXPECT_EQ(0, d.received_redirect_count());

  EXPECT_EQ(1, default_network_delegate()->created_requests());
  EXPECT_EQ(1, default_network_delegate()->before_send_headers_count());
  EXPECT_EQ(1, default_network_delegate()->headers_received_count());
}

TEST_F(URLRequestInterceptorTestHTTP,
       NetworkDelegateNotificationOnErrorIntercept) {
  // Intercept that error and respond with an OK response.
  interceptor()->set_intercept_final_response(true);
  interceptor()->set_final_headers(MockURLRequestInterceptor::ok_headers());
  interceptor()->set_final_data(MockURLRequestInterceptor::ok_data());
  default_network_delegate()->set_can_be_intercepted_on_error(true);

  ASSERT_TRUE(test_server()->Start());

  TestDelegate d;
  scoped_ptr<URLRequest> req(default_context().CreateRequest(
      test_server()->GetURL("files/two-content-lengths.html"), DEFAULT_PRIORITY,
      &d));
  req->set_method("GET");
  req->Start();
  base::RunLoop().Run();

  EXPECT_TRUE(interceptor()->did_intercept_final());

  // Check we received one good response.
  EXPECT_TRUE(req->status().is_success());
  if (req->status().is_success())
    EXPECT_EQ(200, req->response_headers()->response_code());
  EXPECT_EQ(MockURLRequestInterceptor::ok_data(), d.data_received());
  EXPECT_EQ(1, d.response_started_count());
  EXPECT_EQ(0, d.received_redirect_count());

  EXPECT_EQ(1, default_network_delegate()->created_requests());
  EXPECT_EQ(1, default_network_delegate()->before_send_headers_count());
  EXPECT_EQ(0, default_network_delegate()->headers_received_count());
}

TEST_F(URLRequestInterceptorTestHTTP,
       NetworkDelegateNotificationOnResponseIntercept) {
  // Intercept that error and respond with an OK response.
  interceptor()->set_intercept_final_response(true);

  // Intercept with a real URLRequestHttpJob.
  interceptor()->set_use_url_request_http_job(true);

  ASSERT_TRUE(test_server()->Start());

  TestDelegate d;
  scoped_ptr<URLRequest> req(default_context().CreateRequest(
      test_server()->GetURL("files/simple.html"), DEFAULT_PRIORITY, &d));
  req->set_method("GET");
  req->Start();
  base::RunLoop().Run();

  EXPECT_TRUE(interceptor()->did_intercept_final());

  // Check we received one good response.
  EXPECT_TRUE(req->status().is_success());
  if (req->status().is_success())
    EXPECT_EQ(200, req->response_headers()->response_code());
  EXPECT_EQ("hello", d.data_received());
  EXPECT_EQ(1, d.response_started_count());
  EXPECT_EQ(0, d.received_redirect_count());

  EXPECT_EQ(1, default_network_delegate()->created_requests());
  EXPECT_EQ(2, default_network_delegate()->before_send_headers_count());
  EXPECT_EQ(2, default_network_delegate()->headers_received_count());
}

class URLRequestTestReferrerPolicy : public URLRequestTest {
 public:
  URLRequestTestReferrerPolicy() {}

  void InstantiateSameOriginServers(SpawnedTestServer::Type origin_type) {
    origin_server_.reset(new SpawnedTestServer(
        origin_type, SpawnedTestServer::kLocalhost,
        origin_type == SpawnedTestServer::TYPE_HTTPS
            ? base::FilePath(FILE_PATH_LITERAL("net/data/ssl"))
            : base::FilePath(kTestFilePath)));
    ASSERT_TRUE(origin_server_->Start());
  }

  void InstantiateCrossOriginServers(SpawnedTestServer::Type origin_type,
                                     SpawnedTestServer::Type destination_type) {
    origin_server_.reset(new SpawnedTestServer(
        origin_type, SpawnedTestServer::kLocalhost,
        origin_type == SpawnedTestServer::TYPE_HTTPS
            ? base::FilePath(FILE_PATH_LITERAL("net/data/ssl"))
            : base::FilePath(kTestFilePath)));
    ASSERT_TRUE(origin_server_->Start());

    destination_server_.reset(new SpawnedTestServer(
        destination_type, SpawnedTestServer::kLocalhost,
        destination_type == SpawnedTestServer::TYPE_HTTPS
            ? base::FilePath(FILE_PATH_LITERAL("net/data/ssl"))
            : base::FilePath(kTestFilePath)));
    ASSERT_TRUE(destination_server_->Start());
  }

  void VerifyReferrerAfterRedirect(URLRequest::ReferrerPolicy policy,
                                   const GURL& referrer,
                                   const GURL& expected) {
    // Create and execute the request: we'll only have a |destination_server_|
    // if the origins are meant to be distinct. Otherwise, we'll use the
    // |origin_server_| for both endpoints.
    GURL destination_url =
        destination_server_ ? destination_server_->GetURL("echoheader?Referer")
                            : origin_server_->GetURL("echoheader?Referer");
    GURL origin_url =
        origin_server_->GetURL("server-redirect?" + destination_url.spec());

    TestDelegate d;
    scoped_ptr<URLRequest> req(
        default_context_.CreateRequest(origin_url, DEFAULT_PRIORITY, &d));
    req->set_referrer_policy(policy);
    req->SetReferrer(referrer.spec());
    req->Start();
    base::RunLoop().Run();

    EXPECT_EQ(1, d.response_started_count());
    EXPECT_EQ(1, d.received_redirect_count());
    EXPECT_EQ(destination_url, req->url());
    EXPECT_TRUE(req->status().is_success());
    EXPECT_EQ(200, req->response_headers()->response_code());

    EXPECT_EQ(expected.spec(), req->referrer());
    if (expected.is_empty())
      EXPECT_EQ("None", d.data_received());
    else
      EXPECT_EQ(expected.spec(), d.data_received());
  }

  SpawnedTestServer* origin_server() const { return origin_server_.get(); }

 private:
  scoped_ptr<SpawnedTestServer> origin_server_;
  scoped_ptr<SpawnedTestServer> destination_server_;
};

TEST_F(URLRequestTestReferrerPolicy, HTTPToSameOriginHTTP) {
  InstantiateSameOriginServers(SpawnedTestServer::TYPE_HTTP);

  VerifyReferrerAfterRedirect(
      URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
      origin_server()->GetURL("path/to/file.html"),
      origin_server()->GetURL("path/to/file.html"));

  VerifyReferrerAfterRedirect(
      URLRequest::REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN,
      origin_server()->GetURL("path/to/file.html"),
      origin_server()->GetURL("path/to/file.html"));

  VerifyReferrerAfterRedirect(
      URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN,
      origin_server()->GetURL("path/to/file.html"),
      origin_server()->GetURL("path/to/file.html"));

  VerifyReferrerAfterRedirect(URLRequest::NEVER_CLEAR_REFERRER,
                              origin_server()->GetURL("path/to/file.html"),
                              origin_server()->GetURL("path/to/file.html"));
}

// Can't spin up more than one SpawnedTestServer on Android.
#if defined(OS_ANDROID)
#define MAYBE_HTTPToCrossOriginHTTP DISABLED_HTTPToCrosOriginHTTP
#else
#define MAYBE_HTTPToCrossOriginHTTP HTTPToCrossOriginHTTP
#endif
TEST_F(URLRequestTestReferrerPolicy, MAYBE_HTTPToCrossOriginHTTP) {
  InstantiateCrossOriginServers(SpawnedTestServer::TYPE_HTTP,
                                SpawnedTestServer::TYPE_HTTP);

  VerifyReferrerAfterRedirect(
      URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
      origin_server()->GetURL("path/to/file.html"),
      origin_server()->GetURL("path/to/file.html"));

  VerifyReferrerAfterRedirect(
      URLRequest::REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN,
      origin_server()->GetURL("path/to/file.html"),
      origin_server()->GetURL(std::string()));

  VerifyReferrerAfterRedirect(
      URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN,
      origin_server()->GetURL("path/to/file.html"),
      origin_server()->GetURL(std::string()));

  VerifyReferrerAfterRedirect(URLRequest::NEVER_CLEAR_REFERRER,
                              origin_server()->GetURL("path/to/file.html"),
                              origin_server()->GetURL("path/to/file.html"));
}

TEST_F(URLRequestTestReferrerPolicy, HTTPSToSameOriginHTTPS) {
  InstantiateSameOriginServers(SpawnedTestServer::TYPE_HTTPS);

  VerifyReferrerAfterRedirect(
      URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
      origin_server()->GetURL("path/to/file.html"),
      origin_server()->GetURL("path/to/file.html"));

  VerifyReferrerAfterRedirect(
      URLRequest::REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN,
      origin_server()->GetURL("path/to/file.html"),
      origin_server()->GetURL("path/to/file.html"));

  VerifyReferrerAfterRedirect(
      URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN,
      origin_server()->GetURL("path/to/file.html"),
      origin_server()->GetURL("path/to/file.html"));

  VerifyReferrerAfterRedirect(URLRequest::NEVER_CLEAR_REFERRER,
                              origin_server()->GetURL("path/to/file.html"),
                              origin_server()->GetURL("path/to/file.html"));
}

// Can't spin up more than one SpawnedTestServer on Android.
#if defined(OS_ANDROID)
#define MAYBE_HTTPSToCrossOriginHTTPS DISABLED_HTTPSToCrosOriginHTTPS
#else
#define MAYBE_HTTPSToCrossOriginHTTPS HTTPSToCrossOriginHTTPS
#endif
TEST_F(URLRequestTestReferrerPolicy, MAYBE_HTTPSToCrossOriginHTTPS) {
  InstantiateCrossOriginServers(SpawnedTestServer::TYPE_HTTPS,
                                SpawnedTestServer::TYPE_HTTPS);

  VerifyReferrerAfterRedirect(
      URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
      origin_server()->GetURL("path/to/file.html"),
      origin_server()->GetURL("path/to/file.html"));

  VerifyReferrerAfterRedirect(
      URLRequest::REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN,
      origin_server()->GetURL("path/to/file.html"),
      origin_server()->GetURL(std::string()));

  VerifyReferrerAfterRedirect(
      URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN,
      origin_server()->GetURL("path/to/file.html"),
      origin_server()->GetURL(std::string()));

  VerifyReferrerAfterRedirect(URLRequest::NEVER_CLEAR_REFERRER,
                              origin_server()->GetURL("path/to/file.html"),
                              origin_server()->GetURL("path/to/file.html"));
}

// Can't spin up more than one SpawnedTestServer on Android.
#if defined(OS_ANDROID)
#define MAYBE_HTTPToHTTPS DISABLED_HTTPToHTTPS
#else
#define MAYBE_HTTPToHTTPS HTTPToHTTPS
#endif
TEST_F(URLRequestTestReferrerPolicy, MAYBE_HTTPToHTTPS) {
  InstantiateCrossOriginServers(SpawnedTestServer::TYPE_HTTP,
                                SpawnedTestServer::TYPE_HTTPS);

  VerifyReferrerAfterRedirect(
      URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
      origin_server()->GetURL("path/to/file.html"),
      origin_server()->GetURL("path/to/file.html"));

  VerifyReferrerAfterRedirect(
      URLRequest::REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN,
      origin_server()->GetURL("path/to/file.html"),
      origin_server()->GetURL(std::string()));

  VerifyReferrerAfterRedirect(
      URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN,
      origin_server()->GetURL("path/to/file.html"),
      origin_server()->GetURL(std::string()));

  VerifyReferrerAfterRedirect(URLRequest::NEVER_CLEAR_REFERRER,
                              origin_server()->GetURL("path/to/file.html"),
                              origin_server()->GetURL("path/to/file.html"));
}

// Can't spin up more than one SpawnedTestServer on Android.
#if defined(OS_ANDROID)
#define MAYBE_HTTPSToHTTP DISABLED_HTTPSToHTTP
#else
#define MAYBE_HTTPSToHTTP HTTPSToHTTP
#endif
TEST_F(URLRequestTestReferrerPolicy, MAYBE_HTTPSToHTTP) {
  InstantiateCrossOriginServers(SpawnedTestServer::TYPE_HTTPS,
                                SpawnedTestServer::TYPE_HTTP);

  VerifyReferrerAfterRedirect(
      URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
      origin_server()->GetURL("path/to/file.html"), GURL());

  VerifyReferrerAfterRedirect(
      URLRequest::REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN,
      origin_server()->GetURL("path/to/file.html"), GURL());

  VerifyReferrerAfterRedirect(
      URLRequest::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN,
      origin_server()->GetURL("path/to/file.html"),
      origin_server()->GetURL(std::string()));

  VerifyReferrerAfterRedirect(URLRequest::NEVER_CLEAR_REFERRER,
                              origin_server()->GetURL("path/to/file.html"),
                              origin_server()->GetURL("path/to/file.html"));
}

class HTTPSRequestTest : public testing::Test {
 public:
  HTTPSRequestTest() : default_context_(true) {
    default_context_.set_network_delegate(&default_network_delegate_);
    default_context_.Init();
  }
  ~HTTPSRequestTest() override {}

 protected:
  TestNetworkDelegate default_network_delegate_;  // Must outlive URLRequest.
  TestURLRequestContext default_context_;
};

TEST_F(HTTPSRequestTest, HTTPSGetTest) {
  SpawnedTestServer test_server(
      SpawnedTestServer::TYPE_HTTPS,
      SpawnedTestServer::kLocalhost,
      base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
  ASSERT_TRUE(test_server.Start());

  TestDelegate d;
  {
    scoped_ptr<URLRequest> r(default_context_.CreateRequest(
        test_server.GetURL(std::string()), DEFAULT_PRIORITY, &d));
    r->Start();
    EXPECT_TRUE(r->is_pending());

    base::RunLoop().Run();

    EXPECT_EQ(1, d.response_started_count());
    EXPECT_FALSE(d.received_data_before_response());
    EXPECT_NE(0, d.bytes_received());
    CheckSSLInfo(r->ssl_info());
    EXPECT_EQ(test_server.host_port_pair().host(),
              r->GetSocketAddress().host());
    EXPECT_EQ(test_server.host_port_pair().port(),
              r->GetSocketAddress().port());
  }
}

TEST_F(HTTPSRequestTest, HTTPSMismatchedTest) {
  SpawnedTestServer::SSLOptions ssl_options(
      SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME);
  SpawnedTestServer test_server(
      SpawnedTestServer::TYPE_HTTPS,
      ssl_options,
      base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
  ASSERT_TRUE(test_server.Start());

  bool err_allowed = true;
  for (int i = 0; i < 2 ; i++, err_allowed = !err_allowed) {
    TestDelegate d;
    {
      d.set_allow_certificate_errors(err_allowed);
      scoped_ptr<URLRequest> r(default_context_.CreateRequest(
          test_server.GetURL(std::string()), DEFAULT_PRIORITY, &d));

      r->Start();
      EXPECT_TRUE(r->is_pending());

      base::RunLoop().Run();

      EXPECT_EQ(1, d.response_started_count());
      EXPECT_FALSE(d.received_data_before_response());
      EXPECT_TRUE(d.have_certificate_errors());
      if (err_allowed) {
        EXPECT_NE(0, d.bytes_received());
        CheckSSLInfo(r->ssl_info());
      } else {
        EXPECT_EQ(0, d.bytes_received());
      }
    }
  }
}

TEST_F(HTTPSRequestTest, HTTPSExpiredTest) {
  SpawnedTestServer::SSLOptions ssl_options(
      SpawnedTestServer::SSLOptions::CERT_EXPIRED);
  SpawnedTestServer test_server(
      SpawnedTestServer::TYPE_HTTPS,
      ssl_options,
      base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
  ASSERT_TRUE(test_server.Start());

  // Iterate from false to true, just so that we do the opposite of the
  // previous test in order to increase test coverage.
  bool err_allowed = false;
  for (int i = 0; i < 2 ; i++, err_allowed = !err_allowed) {
    TestDelegate d;
    {
      d.set_allow_certificate_errors(err_allowed);
      scoped_ptr<URLRequest> r(default_context_.CreateRequest(
          test_server.GetURL(std::string()), DEFAULT_PRIORITY, &d));

      r->Start();
      EXPECT_TRUE(r->is_pending());

      base::RunLoop().Run();

      EXPECT_EQ(1, d.response_started_count());
      EXPECT_FALSE(d.received_data_before_response());
      EXPECT_TRUE(d.have_certificate_errors());
      if (err_allowed) {
        EXPECT_NE(0, d.bytes_received());
        CheckSSLInfo(r->ssl_info());
      } else {
        EXPECT_EQ(0, d.bytes_received());
      }
    }
  }
}

// Tests that servers which require a deprecated cipher suite still work.
TEST_F(HTTPSRequestTest, CipherFallbackTest) {
  TestNetLog net_log;
  default_context_.set_net_log(&net_log);

  SpawnedTestServer::SSLOptions ssl_options;
  ssl_options.bulk_ciphers = SpawnedTestServer::SSLOptions::BULK_CIPHER_RC4;
  SpawnedTestServer test_server(
      SpawnedTestServer::TYPE_HTTPS, ssl_options,
      base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
  ASSERT_TRUE(test_server.Start());

  TestDelegate d;
  scoped_ptr<URLRequest> r(default_context_.CreateRequest(
      test_server.GetURL(std::string()), DEFAULT_PRIORITY, &d));
  r->Start();
  EXPECT_TRUE(r->is_pending());

  base::RunLoop().Run();

  EXPECT_EQ(1, d.response_started_count());
  EXPECT_FALSE(d.received_data_before_response());
  EXPECT_NE(0, d.bytes_received());
  CheckSSLInfo(r->ssl_info());
  EXPECT_EQ(test_server.host_port_pair().host(), r->GetSocketAddress().host());
  EXPECT_EQ(test_server.host_port_pair().port(), r->GetSocketAddress().port());

  // No version downgrade should have been necessary.
  EXPECT_FALSE(r->ssl_info().connection_status &
               SSL_CONNECTION_VERSION_FALLBACK);
  EXPECT_EQ(SSL_CONNECTION_VERSION_TLS1_2,
            SSLConnectionStatusToVersion(r->ssl_info().connection_status));

  TestNetLogEntry::List entries;
  net_log.GetEntries(&entries);
  ExpectLogContainsSomewhere(entries, 0, NetLog::TYPE_SSL_CIPHER_FALLBACK,
                             NetLog::PHASE_NONE);
}

// This tests that a load of www.google.com with a certificate error sets
// the |certificate_errors_are_fatal| flag correctly. This flag will cause
// the interstitial to be fatal.
TEST_F(HTTPSRequestTest, HTTPSPreloadedHSTSTest) {
  SpawnedTestServer::SSLOptions ssl_options(
      SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME);
  SpawnedTestServer test_server(
      SpawnedTestServer::TYPE_HTTPS,
      ssl_options,
      base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
  ASSERT_TRUE(test_server.Start());

  // We require that the URL be www.google.com in order to pick up the
  // preloaded HSTS entries in the TransportSecurityState. This means that we
  // have to use a MockHostResolver in order to direct www.google.com to the
  // testserver. By default, MockHostResolver maps all hosts to 127.0.0.1.

  MockHostResolver host_resolver;
  TestNetworkDelegate network_delegate;  // Must outlive URLRequest.
  TestURLRequestContext context(true);
  context.set_network_delegate(&network_delegate);
  context.set_host_resolver(&host_resolver);
  TransportSecurityState transport_security_state;
  context.set_transport_security_state(&transport_security_state);
  context.Init();

  TestDelegate d;
  scoped_ptr<URLRequest> r(context.CreateRequest(
      GURL(base::StringPrintf("https://www.google.com:%d",
                              test_server.host_port_pair().port())),
      DEFAULT_PRIORITY, &d));

  r->Start();
  EXPECT_TRUE(r->is_pending());

  base::RunLoop().Run();

  EXPECT_EQ(1, d.response_started_count());
  EXPECT_FALSE(d.received_data_before_response());
  EXPECT_TRUE(d.have_certificate_errors());
  EXPECT_TRUE(d.certificate_errors_are_fatal());
}

// This tests that cached HTTPS page loads do not cause any updates to the
// TransportSecurityState.
TEST_F(HTTPSRequestTest, HTTPSErrorsNoClobberTSSTest) {
  // The actual problem -- CERT_MISMATCHED_NAME in this case -- doesn't
  // matter. It just has to be any error.
  SpawnedTestServer::SSLOptions ssl_options(
      SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME);
  SpawnedTestServer test_server(
      SpawnedTestServer::TYPE_HTTPS,
      ssl_options,
      base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
  ASSERT_TRUE(test_server.Start());

  // We require that the URL be www.google.com in order to pick up the static
  // and dynamic STS and PKP entries in the TransportSecurityState. This means
  // that we have to use a MockHostResolver in order to direct www.google.com to
  // the testserver. By default, MockHostResolver maps all hosts to 127.0.0.1.

  MockHostResolver host_resolver;
  TestNetworkDelegate network_delegate;  // Must outlive URLRequest.
  TestURLRequestContext context(true);
  context.set_network_delegate(&network_delegate);
  context.set_host_resolver(&host_resolver);
  TransportSecurityState transport_security_state;

  TransportSecurityState::STSState static_sts_state;
  TransportSecurityState::PKPState static_pkp_state;
  EXPECT_TRUE(transport_security_state.GetStaticDomainState(
      "www.google.com", &static_sts_state, &static_pkp_state));
  context.set_transport_security_state(&transport_security_state);
  context.Init();

  TransportSecurityState::STSState dynamic_sts_state;
  TransportSecurityState::PKPState dynamic_pkp_state;
  EXPECT_FALSE(transport_security_state.GetDynamicSTSState("www.google.com",
                                                           &dynamic_sts_state));
  EXPECT_FALSE(transport_security_state.GetDynamicPKPState("www.google.com",
                                                           &dynamic_pkp_state));

  TestDelegate d;
  scoped_ptr<URLRequest> r(context.CreateRequest(
      GURL(base::StringPrintf("https://www.google.com:%d",
                              test_server.host_port_pair().port())),
      DEFAULT_PRIORITY, &d));

  r->Start();
  EXPECT_TRUE(r->is_pending());

  base::RunLoop().Run();

  EXPECT_EQ(1, d.response_started_count());
  EXPECT_FALSE(d.received_data_before_response());
  EXPECT_TRUE(d.have_certificate_errors());
  EXPECT_TRUE(d.certificate_errors_are_fatal());

  // Get a fresh copy of the states, and check that they haven't changed.
  TransportSecurityState::STSState new_static_sts_state;
  TransportSecurityState::PKPState new_static_pkp_state;
  EXPECT_TRUE(transport_security_state.GetStaticDomainState(
      "www.google.com", &new_static_sts_state, &new_static_pkp_state));
  TransportSecurityState::STSState new_dynamic_sts_state;
  TransportSecurityState::PKPState new_dynamic_pkp_state;
  EXPECT_FALSE(transport_security_state.GetDynamicSTSState(
      "www.google.com", &new_dynamic_sts_state));
  EXPECT_FALSE(transport_security_state.GetDynamicPKPState(
      "www.google.com", &new_dynamic_pkp_state));

  EXPECT_EQ(new_static_sts_state.upgrade_mode, static_sts_state.upgrade_mode);
  EXPECT_EQ(new_static_sts_state.include_subdomains,
            static_sts_state.include_subdomains);
  EXPECT_EQ(new_static_pkp_state.include_subdomains,
            static_pkp_state.include_subdomains);
  EXPECT_TRUE(FingerprintsEqual(new_static_pkp_state.spki_hashes,
                                static_pkp_state.spki_hashes));
  EXPECT_TRUE(FingerprintsEqual(new_static_pkp_state.bad_spki_hashes,
                                static_pkp_state.bad_spki_hashes));
}

// Make sure HSTS preserves a POST request's method and body.
TEST_F(HTTPSRequestTest, HSTSPreservesPosts) {
  static const char kData[] = "hello world";

  SpawnedTestServer::SSLOptions ssl_options(
      SpawnedTestServer::SSLOptions::CERT_OK);
  SpawnedTestServer test_server(
      SpawnedTestServer::TYPE_HTTPS,
      ssl_options,
      base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
  ASSERT_TRUE(test_server.Start());


  // Per spec, TransportSecurityState expects a domain name, rather than an IP
  // address, so a MockHostResolver is needed to redirect www.somewhere.com to
  // the SpawnedTestServer.  By default, MockHostResolver maps all hosts
  // to 127.0.0.1.
  MockHostResolver host_resolver;

  // Force https for www.somewhere.com.
  TransportSecurityState transport_security_state;
  base::Time expiry = base::Time::Now() + base::TimeDelta::FromDays(1000);
  bool include_subdomains = false;
  transport_security_state.AddHSTS("www.somewhere.com", expiry,
                                   include_subdomains);

  TestNetworkDelegate network_delegate;  // Must outlive URLRequest.

  TestURLRequestContext context(true);
  context.set_host_resolver(&host_resolver);
  context.set_transport_security_state(&transport_security_state);
  context.set_network_delegate(&network_delegate);
  context.Init();

  TestDelegate d;
  // Navigating to https://www.somewhere.com instead of https://127.0.0.1 will
  // cause a certificate error.  Ignore the error.
  d.set_allow_certificate_errors(true);

  scoped_ptr<URLRequest> req(context.CreateRequest(
      GURL(base::StringPrintf("http://www.somewhere.com:%d/echo",
                              test_server.host_port_pair().port())),
      DEFAULT_PRIORITY, &d));
  req->set_method("POST");
  req->set_upload(CreateSimpleUploadData(kData));

  req->Start();
  base::RunLoop().Run();

  EXPECT_EQ("https", req->url().scheme());
  EXPECT_EQ("POST", req->method());
  EXPECT_EQ(kData, d.data_received());

  LoadTimingInfo load_timing_info;
  network_delegate.GetLoadTimingInfoBeforeRedirect(&load_timing_info);
  // LoadTimingInfo of HSTS redirects is similar to that of network cache hits
  TestLoadTimingCacheHitNoNetwork(load_timing_info);
}

// Make sure that the CORS headers are added to cross-origin HSTS redirects.
TEST_F(HTTPSRequestTest, HSTSCrossOriginAddHeaders) {
  static const char kOriginHeaderValue[] = "http://www.example.com";

  SpawnedTestServer::SSLOptions ssl_options(
      SpawnedTestServer::SSLOptions::CERT_OK);
  SpawnedTestServer test_server(
      SpawnedTestServer::TYPE_HTTPS,
      ssl_options,
      base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
  ASSERT_TRUE(test_server.Start());

  // Per spec, TransportSecurityState expects a domain name, rather than an IP
  // address, so a MockHostResolver is needed to redirect example.net to the
  // SpawnedTestServer. MockHostResolver maps all hosts to 127.0.0.1 by default.
  MockHostResolver host_resolver;

  TransportSecurityState transport_security_state;
  base::Time expiry = base::Time::Now() + base::TimeDelta::FromDays(1);
  bool include_subdomains = false;
  transport_security_state.AddHSTS("example.net", expiry, include_subdomains);

  TestNetworkDelegate network_delegate;  // Must outlive URLRequest.

  MockCertVerifier cert_verifier;
  cert_verifier.set_default_result(OK);

  TestURLRequestContext context(true);
  context.set_host_resolver(&host_resolver);
  context.set_transport_security_state(&transport_security_state);
  context.set_network_delegate(&network_delegate);
  context.set_cert_verifier(&cert_verifier);
  context.Init();

  GURL hsts_http_url(base::StringPrintf("http://example.net:%d/somehstssite",
                                        test_server.host_port_pair().port()));
  url::Replacements<char> replacements;
  const char kNewScheme[] = "https";
  replacements.SetScheme(kNewScheme, url::Component(0, strlen(kNewScheme)));
  GURL hsts_https_url = hsts_http_url.ReplaceComponents(replacements);

  TestDelegate d;
  // Quit on redirect to allow response header inspection upon redirect.
  d.set_quit_on_redirect(true);

  scoped_ptr<URLRequest> req(
      context.CreateRequest(hsts_http_url, DEFAULT_PRIORITY, &d));
  // Set Origin header to simulate a cross-origin request.
  HttpRequestHeaders request_headers;
  request_headers.SetHeader("Origin", kOriginHeaderValue);
  req->SetExtraRequestHeaders(request_headers);

  req->Start();
  base::RunLoop().Run();

  EXPECT_EQ(1, d.received_redirect_count());

  const HttpResponseHeaders* headers = req->response_headers();
  std::string redirect_location;
  EXPECT_TRUE(headers->EnumerateHeader(NULL, "Location", &redirect_location));
  EXPECT_EQ(hsts_https_url.spec(), redirect_location);

  std::string received_cors_header;
  EXPECT_TRUE(headers->EnumerateHeader(NULL, "Access-Control-Allow-Origin",
                                       &received_cors_header));
  EXPECT_EQ(kOriginHeaderValue, received_cors_header);
}

// This just tests the behaviour of GetHSTSRedirect(). End-to-end tests of HSTS
// are performed in net/websockets/websocket_end_to_end_test.cc.
TEST(WebSocketURLRequestTest, HSTSApplied) {
  TestNetworkDelegate network_delegate;
  TransportSecurityState transport_security_state;
  base::Time expiry = base::Time::Now() + base::TimeDelta::FromDays(1);
  bool include_subdomains = false;
  transport_security_state.AddHSTS("example.net", expiry, include_subdomains);
  TestURLRequestContext context(true);
  context.set_transport_security_state(&transport_security_state);
  context.set_network_delegate(&network_delegate);
  context.Init();
  GURL ws_url("ws://example.net/echo");
  TestDelegate delegate;
  scoped_ptr<URLRequest> request(
      context.CreateRequest(ws_url, DEFAULT_PRIORITY, &delegate));
  EXPECT_TRUE(request->GetHSTSRedirect(&ws_url));
  EXPECT_TRUE(ws_url.SchemeIs("wss"));
}

namespace {

class SSLClientAuthTestDelegate : public TestDelegate {
 public:
  SSLClientAuthTestDelegate() : on_certificate_requested_count_(0) {
  }
  void OnCertificateRequested(URLRequest* request,
                              SSLCertRequestInfo* cert_request_info) override {
    on_certificate_requested_count_++;
    base::MessageLoop::current()->Quit();
  }
  int on_certificate_requested_count() {
    return on_certificate_requested_count_;
  }
 private:
  int on_certificate_requested_count_;
};

}  // namespace

// TODO(davidben): Test the rest of the code. Specifically,
// - Filtering which certificates to select.
// - Sending a certificate back.
// - Getting a certificate request in an SSL renegotiation sending the
//   HTTP request.
TEST_F(HTTPSRequestTest, ClientAuthTest) {
  SpawnedTestServer::SSLOptions ssl_options;
  ssl_options.request_client_certificate = true;
  SpawnedTestServer test_server(
      SpawnedTestServer::TYPE_HTTPS,
      ssl_options,
      base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
  ASSERT_TRUE(test_server.Start());

  SSLClientAuthTestDelegate d;
  {
    scoped_ptr<URLRequest> r(default_context_.CreateRequest(
        test_server.GetURL(std::string()), DEFAULT_PRIORITY, &d));

    r->Start();
    EXPECT_TRUE(r->is_pending());

    base::RunLoop().Run();

    EXPECT_EQ(1, d.on_certificate_requested_count());
    EXPECT_FALSE(d.received_data_before_response());
    EXPECT_EQ(0, d.bytes_received());

    // Send no certificate.
    // TODO(davidben): Get temporary client cert import (with keys) working on
    // all platforms so we can test sending a cert as well.
    r->ContinueWithCertificate(NULL);

    base::RunLoop().Run();

    EXPECT_EQ(1, d.response_started_count());
    EXPECT_FALSE(d.received_data_before_response());
    EXPECT_NE(0, d.bytes_received());
  }
}

TEST_F(HTTPSRequestTest, ResumeTest) {
  // Test that we attempt a session resume when making two connections to the
  // same host.
  SpawnedTestServer::SSLOptions ssl_options;
  ssl_options.record_resume = true;
  SpawnedTestServer test_server(
      SpawnedTestServer::TYPE_HTTPS,
      ssl_options,
      base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
  ASSERT_TRUE(test_server.Start());

  SSLClientSocket::ClearSessionCache();

  {
    TestDelegate d;
    scoped_ptr<URLRequest> r(default_context_.CreateRequest(
        test_server.GetURL("ssl-session-cache"), DEFAULT_PRIORITY, &d));

    r->Start();
    EXPECT_TRUE(r->is_pending());

    base::RunLoop().Run();

    EXPECT_EQ(1, d.response_started_count());
  }

  reinterpret_cast<HttpCache*>(default_context_.http_transaction_factory())->
    CloseAllConnections();

  {
    TestDelegate d;
    scoped_ptr<URLRequest> r(default_context_.CreateRequest(
        test_server.GetURL("ssl-session-cache"), DEFAULT_PRIORITY, &d));

    r->Start();
    EXPECT_TRUE(r->is_pending());

    base::RunLoop().Run();

    // The response will look like;
    //   insert abc
    //   lookup abc
    //   insert xyz
    //
    // With a newline at the end which makes the split think that there are
    // four lines.

    EXPECT_EQ(1, d.response_started_count());
    std::vector<std::string> lines = base::SplitString(
        d.data_received(), "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
    ASSERT_EQ(4u, lines.size()) << d.data_received();

    std::string session_id;

    for (size_t i = 0; i < 2; i++) {
      std::vector<std::string> parts = base::SplitString(
          lines[i], "\t", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
      ASSERT_EQ(2u, parts.size());
      if (i == 0) {
        EXPECT_EQ("insert", parts[0]);
        session_id = parts[1];
      } else {
        EXPECT_EQ("lookup", parts[0]);
        EXPECT_EQ(session_id, parts[1]);
      }
    }
  }
}

// AssertTwoDistinctSessionsInserted checks that |session_info|, which must be
// the result of fetching "ssl-session-cache" from the test server, indicates
// that exactly two different sessions were inserted, with no lookups etc.
static void AssertTwoDistinctSessionsInserted(const string& session_info) {
  std::vector<std::string> lines = base::SplitString(
      session_info, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
  ASSERT_EQ(3u, lines.size()) << session_info;

  std::string session_id;
  for (size_t i = 0; i < 2; i++) {
    std::vector<std::string> parts = base::SplitString(
        lines[i], "\t", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
    ASSERT_EQ(2u, parts.size());
    EXPECT_EQ("insert", parts[0]);
    if (i == 0) {
      session_id = parts[1];
    } else {
      EXPECT_NE(session_id, parts[1]);
    }
  }
}

TEST_F(HTTPSRequestTest, SSLSessionCacheShardTest) {
  // Test that sessions aren't resumed when the value of ssl_session_cache_shard
  // differs.
  SpawnedTestServer::SSLOptions ssl_options;
  ssl_options.record_resume = true;
  SpawnedTestServer test_server(
      SpawnedTestServer::TYPE_HTTPS,
      ssl_options,
      base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
  ASSERT_TRUE(test_server.Start());

  SSLClientSocket::ClearSessionCache();

  {
    TestDelegate d;
    scoped_ptr<URLRequest> r(default_context_.CreateRequest(
        test_server.GetURL("ssl-session-cache"), DEFAULT_PRIORITY, &d));

    r->Start();
    EXPECT_TRUE(r->is_pending());

    base::RunLoop().Run();

    EXPECT_EQ(1, d.response_started_count());
  }

  // Now create a new HttpCache with a different ssl_session_cache_shard value.
  HttpNetworkSession::Params params;
  params.host_resolver = default_context_.host_resolver();
  params.cert_verifier = default_context_.cert_verifier();
  params.transport_security_state = default_context_.transport_security_state();
  params.proxy_service = default_context_.proxy_service();
  params.ssl_config_service = default_context_.ssl_config_service();
  params.http_auth_handler_factory =
      default_context_.http_auth_handler_factory();
  params.network_delegate = &default_network_delegate_;
  params.http_server_properties = default_context_.http_server_properties();
  params.ssl_session_cache_shard = "alternate";

  scoped_ptr<HttpCache> cache(new HttpCache(
      new HttpNetworkSession(params),
      HttpCache::DefaultBackend::InMemory(0)));

  default_context_.set_http_transaction_factory(cache.get());

  {
    TestDelegate d;
    scoped_ptr<URLRequest> r(default_context_.CreateRequest(
        test_server.GetURL("ssl-session-cache"), DEFAULT_PRIORITY, &d));

    r->Start();
    EXPECT_TRUE(r->is_pending());

    base::RunLoop().Run();

    // The response will look like;
    //   insert abc
    //   insert xyz
    //
    // With a newline at the end which makes the split think that there are
    // three lines.

    EXPECT_EQ(1, d.response_started_count());
    AssertTwoDistinctSessionsInserted(d.data_received());
  }
}

#if defined(OS_WIN)

namespace {

bool IsECDSACipherSuite(uint16_t cipher_suite) {
  const char* key_exchange;
  const char* cipher;
  const char* mac;
  bool is_aead;
  SSLCipherSuiteToStrings(&key_exchange, &cipher, &mac, &is_aead, cipher_suite);
  return std::string(key_exchange).find("ECDSA") != std::string::npos;
}

}  // namespace

// Test that ECDSA is disabled on Windows XP, where ECDSA certificates cannot be
// verified.
TEST_F(HTTPSRequestTest, DisableECDSAOnXP) {
  if (base::win::GetVersion() >= base::win::VERSION_VISTA) {
    LOG(INFO) << "Skipping test on this version.";
    return;
  }

  SpawnedTestServer test_server(
      SpawnedTestServer::TYPE_HTTPS,
      SpawnedTestServer::kLocalhost,
      base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
  ASSERT_TRUE(test_server.Start());

  TestDelegate d;
  scoped_ptr<URLRequest> r(default_context_.CreateRequest(
      test_server.GetURL("client-cipher-list"), DEFAULT_PRIORITY, &d));
  r->Start();
  EXPECT_TRUE(r->is_pending());

  base::RunLoop().Run();

  EXPECT_EQ(1, d.response_started_count());
  std::vector<std::string> lines = base::SplitString(
      d.data_received(), "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);

  for (size_t i = 0; i < lines.size(); i++) {
    int cipher_suite;
    ASSERT_TRUE(base::StringToInt(lines[i], &cipher_suite));
    EXPECT_FALSE(IsECDSACipherSuite(cipher_suite))
        << "ClientHello advertised " << cipher_suite;
  }
}

#endif  // OS_WIN

class TestSSLConfigService : public SSLConfigService {
 public:
  TestSSLConfigService(bool ev_enabled,
                       bool online_rev_checking,
                       bool rev_checking_required_local_anchors)
      : ev_enabled_(ev_enabled),
        online_rev_checking_(online_rev_checking),
        rev_checking_required_local_anchors_(
            rev_checking_required_local_anchors),
        min_version_(kDefaultSSLVersionMin),
        fallback_min_version_(kDefaultSSLVersionFallbackMin) {}

  void set_min_version(uint16 version) {
    min_version_ = version;
  }

  void set_fallback_min_version(uint16 version) {
    fallback_min_version_ = version;
  }

  // SSLConfigService:
  void GetSSLConfig(SSLConfig* config) override {
    *config = SSLConfig();
    config->rev_checking_enabled = online_rev_checking_;
    config->verify_ev_cert = ev_enabled_;
    config->rev_checking_required_local_anchors =
        rev_checking_required_local_anchors_;
    if (fallback_min_version_) {
      config->version_fallback_min = fallback_min_version_;
    }
    if (min_version_) {
      config->version_min = min_version_;
    }
  }

 protected:
  ~TestSSLConfigService() override {}

 private:
  const bool ev_enabled_;
  const bool online_rev_checking_;
  const bool rev_checking_required_local_anchors_;
  uint16 min_version_;
  uint16 fallback_min_version_;
};

class FallbackTestURLRequestContext : public TestURLRequestContext {
 public:
  explicit FallbackTestURLRequestContext(bool delay_initialization)
      : TestURLRequestContext(delay_initialization) {}

  void set_fallback_min_version(uint16 version) {
    TestSSLConfigService *ssl_config_service =
        new TestSSLConfigService(true /* check for EV */,
                                 false /* online revocation checking */,
                                 false /* require rev. checking for local
                                          anchors */);
    ssl_config_service->set_fallback_min_version(version);
    set_ssl_config_service(ssl_config_service);
  }
};

class HTTPSFallbackTest : public testing::Test {
 public:
  HTTPSFallbackTest() : context_(true) {}
  ~HTTPSFallbackTest() override {}

 protected:
  void DoFallbackTest(const SpawnedTestServer::SSLOptions& ssl_options) {
    DCHECK(!request_);
    context_.Init();
    delegate_.set_allow_certificate_errors(true);

    SpawnedTestServer test_server(
        SpawnedTestServer::TYPE_HTTPS,
        ssl_options,
        base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
    ASSERT_TRUE(test_server.Start());

    request_ = context_.CreateRequest(test_server.GetURL(std::string()),
                                      DEFAULT_PRIORITY, &delegate_);
    request_->Start();

    base::RunLoop().Run();
  }

  void set_fallback_min_version(uint16 version) {
    context_.set_fallback_min_version(version);
  }

  void ExpectConnection(int version) {
    EXPECT_EQ(1, delegate_.response_started_count());
    EXPECT_NE(0, delegate_.bytes_received());
    EXPECT_EQ(version, SSLConnectionStatusToVersion(
        request_->ssl_info().connection_status));
    EXPECT_TRUE(request_->ssl_info().connection_status &
                SSL_CONNECTION_VERSION_FALLBACK);
  }

  void ExpectFailure(int error) {
    EXPECT_EQ(1, delegate_.response_started_count());
    EXPECT_FALSE(request_->status().is_success());
    EXPECT_EQ(URLRequestStatus::FAILED, request_->status().status());
    EXPECT_EQ(error, request_->status().error());
  }

 private:
  TestDelegate delegate_;
  FallbackTestURLRequestContext context_;
  scoped_ptr<URLRequest> request_;
};

// Tests the TLS 1.0 fallback doesn't happen.
TEST_F(HTTPSFallbackTest, TLSv1NoFallback) {
  SpawnedTestServer::SSLOptions ssl_options(
      SpawnedTestServer::SSLOptions::CERT_OK);
  ssl_options.tls_intolerant =
      SpawnedTestServer::SSLOptions::TLS_INTOLERANT_TLS1_1;

  ASSERT_NO_FATAL_FAILURE(DoFallbackTest(ssl_options));
  ExpectFailure(ERR_SSL_FALLBACK_BEYOND_MINIMUM_VERSION);
}

// Tests the TLS 1.1 fallback.
TEST_F(HTTPSFallbackTest, TLSv1_1Fallback) {
  SpawnedTestServer::SSLOptions ssl_options(
      SpawnedTestServer::SSLOptions::CERT_OK);
  ssl_options.tls_intolerant =
      SpawnedTestServer::SSLOptions::TLS_INTOLERANT_TLS1_2;

  ASSERT_NO_FATAL_FAILURE(DoFallbackTest(ssl_options));
  ExpectConnection(SSL_CONNECTION_VERSION_TLS1_1);
}

// Tests that the TLS 1.1 fallback triggers on closed connections.
TEST_F(HTTPSFallbackTest, TLSv1_1FallbackClosed) {
  SpawnedTestServer::SSLOptions ssl_options(
      SpawnedTestServer::SSLOptions::CERT_OK);
  ssl_options.tls_intolerant =
      SpawnedTestServer::SSLOptions::TLS_INTOLERANT_TLS1_2;
  ssl_options.tls_intolerance_type =
      SpawnedTestServer::SSLOptions::TLS_INTOLERANCE_CLOSE;

  ASSERT_NO_FATAL_FAILURE(DoFallbackTest(ssl_options));
  ExpectConnection(SSL_CONNECTION_VERSION_TLS1_1);
}

// This test is disabled on Android because the remote test server doesn't cause
// a TCP reset.
#if !defined(OS_ANDROID)
// Tests fallback to TLS 1.1 on connection reset.
TEST_F(HTTPSFallbackTest, TLSv1_1FallbackReset) {
  SpawnedTestServer::SSLOptions ssl_options(
      SpawnedTestServer::SSLOptions::CERT_OK);
  ssl_options.tls_intolerant =
      SpawnedTestServer::SSLOptions::TLS_INTOLERANT_TLS1_2;
  ssl_options.tls_intolerance_type =
      SpawnedTestServer::SSLOptions::TLS_INTOLERANCE_RESET;

  ASSERT_NO_FATAL_FAILURE(DoFallbackTest(ssl_options));
  ExpectConnection(SSL_CONNECTION_VERSION_TLS1_1);
}
#endif  // !OS_ANDROID

// Tests that we don't fallback on handshake failure with servers that implement
// TLS_FALLBACK_SCSV. Also ensure that the original error code is reported.
TEST_F(HTTPSFallbackTest, FallbackSCSV) {
  SpawnedTestServer::SSLOptions ssl_options(
      SpawnedTestServer::SSLOptions::CERT_OK);
  // Configure HTTPS server to be intolerant of TLS >= 1.1 in order to trigger
  // a version fallback.
  ssl_options.tls_intolerant =
      SpawnedTestServer::SSLOptions::TLS_INTOLERANT_TLS1_1;
  // Have the server process TLS_FALLBACK_SCSV so that version fallback
  // connections are rejected.
  ssl_options.fallback_scsv_enabled = true;

  ASSERT_NO_FATAL_FAILURE(DoFallbackTest(ssl_options));

  // ERR_SSL_VERSION_OR_CIPHER_MISMATCH is how the server simulates version
  // intolerance. If the fallback SCSV is processed when the original error
  // that caused the fallback should be returned, which should be
  // ERR_SSL_VERSION_OR_CIPHER_MISMATCH.
  ExpectFailure(ERR_SSL_VERSION_OR_CIPHER_MISMATCH);
}

// Tests that we don't fallback on connection closed with servers that implement
// TLS_FALLBACK_SCSV. Also ensure that the original error code is reported.
TEST_F(HTTPSFallbackTest, FallbackSCSVClosed) {
  SpawnedTestServer::SSLOptions ssl_options(
      SpawnedTestServer::SSLOptions::CERT_OK);
  // Configure HTTPS server to be intolerant of TLS >= 1.1 in order to trigger
  // a version fallback.
  ssl_options.tls_intolerant =
      SpawnedTestServer::SSLOptions::TLS_INTOLERANT_TLS1_1;
  ssl_options.tls_intolerance_type =
      SpawnedTestServer::SSLOptions::TLS_INTOLERANCE_CLOSE;
  // Have the server process TLS_FALLBACK_SCSV so that version fallback
  // connections are rejected.
  ssl_options.fallback_scsv_enabled = true;

  ASSERT_NO_FATAL_FAILURE(DoFallbackTest(ssl_options));

  // The original error should be replayed on rejected fallback.
  ExpectFailure(ERR_CONNECTION_CLOSED);
}

// Test that fallback probe connections don't cause sessions to be cached.
TEST_F(HTTPSRequestTest, FallbackProbeNoCache) {
  SpawnedTestServer::SSLOptions ssl_options(
      SpawnedTestServer::SSLOptions::CERT_OK);
  ssl_options.tls_intolerant =
      SpawnedTestServer::SSLOptions::TLS_INTOLERANT_TLS1_1;
  ssl_options.tls_intolerance_type =
      SpawnedTestServer::SSLOptions::TLS_INTOLERANCE_CLOSE;
  ssl_options.record_resume = true;

  SpawnedTestServer test_server(
      SpawnedTestServer::TYPE_HTTPS,
      ssl_options,
      base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
  ASSERT_TRUE(test_server.Start());

  SSLClientSocket::ClearSessionCache();

  // Make a connection that does a probe fallback to TLSv1 but fails because
  // TLSv1 fallback is disabled. We don't wish a session for this connection to
  // be inserted locally.
  {
    TestDelegate delegate;
    FallbackTestURLRequestContext context(true);

    context.set_fallback_min_version(SSL_PROTOCOL_VERSION_TLS1_2);
    context.Init();
    scoped_ptr<URLRequest> request(context.CreateRequest(
        test_server.GetURL(std::string()), DEFAULT_PRIORITY, &delegate));
    request->Start();

    base::RunLoop().Run();

    EXPECT_EQ(1, delegate.response_started_count());
    EXPECT_FALSE(request->status().is_success());
    EXPECT_EQ(URLRequestStatus::FAILED, request->status().status());
    EXPECT_EQ(ERR_SSL_FALLBACK_BEYOND_MINIMUM_VERSION,
              request->status().error());
  }

  // Now allow TLSv1 fallback connections and request the session cache log.
  {
    TestDelegate delegate;
    FallbackTestURLRequestContext context(true);
    context.set_fallback_min_version(SSL_PROTOCOL_VERSION_TLS1);

    context.Init();
    scoped_ptr<URLRequest> request(context.CreateRequest(
        test_server.GetURL("ssl-session-cache"), DEFAULT_PRIORITY, &delegate));
    request->Start();

    base::RunLoop().Run();

    EXPECT_EQ(1, delegate.response_started_count());
    EXPECT_NE(0, delegate.bytes_received());
    EXPECT_EQ(
        SSL_CONNECTION_VERSION_TLS1,
        SSLConnectionStatusToVersion(request->ssl_info().connection_status));
    EXPECT_TRUE(request->ssl_info().connection_status &
                SSL_CONNECTION_VERSION_FALLBACK);

    std::vector<std::string> lines;
    // If no sessions were cached then the server should have seen two sessions
    // inserted with no lookups.
    AssertTwoDistinctSessionsInserted(delegate.data_received());
  }
}

class HTTPSSessionTest : public testing::Test {
 public:
  HTTPSSessionTest() : default_context_(true) {
    cert_verifier_.set_default_result(OK);

    default_context_.set_network_delegate(&default_network_delegate_);
    default_context_.set_cert_verifier(&cert_verifier_);
    default_context_.Init();
  }
  ~HTTPSSessionTest() override {}

 protected:
  MockCertVerifier cert_verifier_;
  TestNetworkDelegate default_network_delegate_;  // Must outlive URLRequest.
  TestURLRequestContext default_context_;
};

// Tests that session resumption is not attempted if an invalid certificate
// is presented.
TEST_F(HTTPSSessionTest, DontResumeSessionsForInvalidCertificates) {
  SpawnedTestServer::SSLOptions ssl_options;
  ssl_options.record_resume = true;
  SpawnedTestServer test_server(
      SpawnedTestServer::TYPE_HTTPS,
      ssl_options,
      base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
  ASSERT_TRUE(test_server.Start());

  SSLClientSocket::ClearSessionCache();

  // Simulate the certificate being expired and attempt a connection.
  cert_verifier_.set_default_result(ERR_CERT_DATE_INVALID);
  {
    TestDelegate d;
    scoped_ptr<URLRequest> r(default_context_.CreateRequest(
        test_server.GetURL("ssl-session-cache"), DEFAULT_PRIORITY, &d));

    r->Start();
    EXPECT_TRUE(r->is_pending());

    base::RunLoop().Run();

    EXPECT_EQ(1, d.response_started_count());
  }

  reinterpret_cast<HttpCache*>(default_context_.http_transaction_factory())->
    CloseAllConnections();

  // Now change the certificate to be acceptable (so that the response is
  // loaded), and ensure that no session id is presented to the peer.
  cert_verifier_.set_default_result(OK);
  {
    TestDelegate d;
    scoped_ptr<URLRequest> r(default_context_.CreateRequest(
        test_server.GetURL("ssl-session-cache"), DEFAULT_PRIORITY, &d));

    r->Start();
    EXPECT_TRUE(r->is_pending());

    base::RunLoop().Run();

    // The response will look like;
    //   insert abc
    //   insert xyz
    //
    // With a newline at the end which makes the split think that there are
    // three lines.
    //
    // If a session was presented (eg: a bug), then the response would look
    // like;
    //   insert abc
    //   lookup abc
    //   insert xyz

    EXPECT_EQ(1, d.response_started_count());
    AssertTwoDistinctSessionsInserted(d.data_received());
  }
}

// This the fingerprint of the "Testing CA" certificate used by the testserver.
// See net/data/ssl/certificates/ocsp-test-root.pem.
static const SHA1HashValue kOCSPTestCertFingerprint =
  { { 0xf1, 0xad, 0xf6, 0xce, 0x42, 0xac, 0xe7, 0xb4, 0xf4, 0x24,
      0xdb, 0x1a, 0xf7, 0xa0, 0x9f, 0x09, 0xa1, 0xea, 0xf1, 0x5c } };

// This is the SHA256, SPKI hash of the "Testing CA" certificate used by the
// testserver.
static const SHA256HashValue kOCSPTestCertSPKI = { {
  0xee, 0xe6, 0x51, 0x2d, 0x4c, 0xfa, 0xf7, 0x3e,
  0x6c, 0xd8, 0xca, 0x67, 0xed, 0xb5, 0x5d, 0x49,
  0x76, 0xe1, 0x52, 0xa7, 0x6e, 0x0e, 0xa0, 0x74,
  0x09, 0x75, 0xe6, 0x23, 0x24, 0xbd, 0x1b, 0x28,
} };

// This is the policy OID contained in the certificates that testserver
// generates.
static const char kOCSPTestCertPolicy[] = "1.3.6.1.4.1.11129.2.4.1";

class HTTPSOCSPTest : public HTTPSRequestTest {
 public:
  HTTPSOCSPTest()
      : context_(true),
        ev_test_policy_(
            new ScopedTestEVPolicy(EVRootCAMetadata::GetInstance(),
                                   kOCSPTestCertFingerprint,
                                   kOCSPTestCertPolicy)) {
  }

  void SetUp() override {
    SetupContext(&context_);
    context_.Init();

    scoped_refptr<X509Certificate> root_cert =
        ImportCertFromFile(GetTestCertsDirectory(), "ocsp-test-root.pem");
    CHECK_NE(static_cast<X509Certificate*>(NULL), root_cert.get());
    test_root_.reset(new ScopedTestRoot(root_cert.get()));

#if defined(USE_NSS_CERTS) || defined(OS_IOS)
    SetURLRequestContextForNSSHttpIO(&context_);
    EnsureNSSHttpIOInit();
#endif
  }

  void DoConnection(const SpawnedTestServer::SSLOptions& ssl_options,
                    CertStatus* out_cert_status) {
    // We always overwrite out_cert_status.
    *out_cert_status = 0;
    SpawnedTestServer test_server(
        SpawnedTestServer::TYPE_HTTPS,
        ssl_options,
        base::FilePath(FILE_PATH_LITERAL("net/data/ssl")));
    ASSERT_TRUE(test_server.Start());

    TestDelegate d;
    d.set_allow_certificate_errors(true);
    scoped_ptr<URLRequest> r(context_.CreateRequest(
        test_server.GetURL(std::string()), DEFAULT_PRIORITY, &d));
    r->Start();

    base::RunLoop().Run();

    EXPECT_EQ(1, d.response_started_count());
    *out_cert_status = r->ssl_info().cert_status;
  }

  ~HTTPSOCSPTest() override {
#if defined(USE_NSS_CERTS) || defined(OS_IOS)
    ShutdownNSSHttpIO();
#endif
  }

 protected:
  // SetupContext configures the URLRequestContext that will be used for making
  // connetions to testserver. This can be overridden in test subclasses for
  // different behaviour.
  virtual void SetupContext(URLRequestContext* context) {
    context->set_ssl_config_service(
        new TestSSLConfigService(true /* check for EV */,
                                 true /* online revocation checking */,
                                 false /* require rev. checking for local
                                          anchors */));
  }

  scoped_ptr<ScopedTestRoot> test_root_;
  TestURLRequestContext context_;
  scoped_ptr<ScopedTestEVPolicy> ev_test_policy_;
};

static CertStatus ExpectedCertStatusForFailedOnlineRevocationCheck() {
#if defined(OS_WIN)
  // Windows can return CERT_STATUS_UNABLE_TO_CHECK_REVOCATION but we don't
  // have that ability on other platforms.
  return CERT_STATUS_UNABLE_TO_CHECK_REVOCATION;
#else
  return 0;
#endif
}

// SystemSupportsHardFailRevocationChecking returns true iff the current
// operating system supports revocation checking and can distinguish between
// situations where a given certificate lacks any revocation information (eg:
// no CRLDistributionPoints and no OCSP Responder AuthorityInfoAccess) and when
// revocation information cannot be obtained (eg: the CRL was unreachable).
// If it does not, then tests which rely on 'hard fail' behaviour should be
// skipped.
static bool SystemSupportsHardFailRevocationChecking() {
#if defined(OS_WIN) || defined(USE_NSS_CERTS) || defined(OS_IOS)
  return true;
#else
  return false;
#endif
}

// SystemUsesChromiumEVMetadata returns true iff the current operating system
// uses Chromium's EV metadata (i.e. EVRootCAMetadata). If it does not, then
// several tests are effected because our testing EV certificate won't be
// recognised as EV.
static bool SystemUsesChromiumEVMetadata() {
#if defined(USE_OPENSSL_CERTS) && !defined(OS_ANDROID)
  // http://crbug.com/117478 - OpenSSL does not support EV validation.
  return false;
#elif (defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_ANDROID)
  // On OS X and Android, we use the system to tell us whether a certificate is
  // EV or not and the system won't recognise our testing root.
  return false;
#else
  return true;
#endif
}

static bool SystemSupportsOCSP() {
#if defined(USE_OPENSSL_CERTS)
  // http://crbug.com/117478 - OpenSSL does not support OCSP.
  return false;
#elif defined(OS_WIN)
  return base::win::GetVersion() >= base::win::VERSION_VISTA;
#elif defined(OS_ANDROID)
  // TODO(jnd): http://crbug.com/117478 - EV verification is not yet supported.
  return false;
#else
  return true;
#endif
}

static bool SystemSupportsOCSPStapling() {
#if defined(USE_NSS_CERTS) || defined(OS_IOS)
  return true;
#elif defined(OS_WIN)
  return base::win::GetVersion() >= base::win::VERSION_VISTA;
#else
  return false;
#endif
}

TEST_F(HTTPSOCSPTest, Valid) {
  if (!SystemSupportsOCSP()) {
    LOG(WARNING) << "Skipping test because system doesn't support OCSP";
    return;
  }

  SpawnedTestServer::SSLOptions ssl_options(
      SpawnedTestServer::SSLOptions::CERT_AUTO);
  ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_OK;

  CertStatus cert_status;
  DoConnection(ssl_options, &cert_status);

  EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS);

  EXPECT_EQ(SystemUsesChromiumEVMetadata(),
            static_cast<bool>(cert_status & CERT_STATUS_IS_EV));

  EXPECT_TRUE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
}

TEST_F(HTTPSOCSPTest, Revoked) {
  if (!SystemSupportsOCSP()) {
    LOG(WARNING) << "Skipping test because system doesn't support OCSP";
    return;
  }

  SpawnedTestServer::SSLOptions ssl_options(
      SpawnedTestServer::SSLOptions::CERT_AUTO);
  ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_REVOKED;

  CertStatus cert_status;
  DoConnection(ssl_options, &cert_status);

#if !(defined(OS_MACOSX) && !defined(OS_IOS))
  // Doesn't pass on OS X yet for reasons that need to be investigated.
  EXPECT_EQ(CERT_STATUS_REVOKED, cert_status & CERT_STATUS_ALL_ERRORS);
#endif
  EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV);
  EXPECT_TRUE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
}

TEST_F(HTTPSOCSPTest, Invalid) {
  if (!SystemSupportsOCSP()) {
    LOG(WARNING) << "Skipping test because system doesn't support OCSP";
    return;
  }

  SpawnedTestServer::SSLOptions ssl_options(
      SpawnedTestServer::SSLOptions::CERT_AUTO);
  ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_INVALID;

  CertStatus cert_status;
  DoConnection(ssl_options, &cert_status);

  EXPECT_EQ(ExpectedCertStatusForFailedOnlineRevocationCheck(),
            cert_status & CERT_STATUS_ALL_ERRORS);

  // Without a positive OCSP response, we shouldn't show the EV status.
  EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV);
  EXPECT_TRUE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
}

TEST_F(HTTPSOCSPTest, ValidStapled) {
  if (!SystemSupportsOCSPStapling()) {
    LOG(WARNING)
        << "Skipping test because system doesn't support OCSP stapling";
    return;
  }

  SpawnedTestServer::SSLOptions ssl_options(
      SpawnedTestServer::SSLOptions::CERT_AUTO);
  ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_OK;
  ssl_options.staple_ocsp_response = true;
  ssl_options.ocsp_server_unavailable = true;

  CertStatus cert_status;
  DoConnection(ssl_options, &cert_status);

  EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS);

  EXPECT_EQ(SystemUsesChromiumEVMetadata(),
            static_cast<bool>(cert_status & CERT_STATUS_IS_EV));

  EXPECT_TRUE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
}

// Disabled on NSS ports. See https://crbug.com/431716.
#if defined(USE_NSS_CERTS)
#define MAYBE_RevokedStapled DISABLED_RevokedStapled
#else
#define MAYBE_RevokedStapled RevokedStapled
#endif
TEST_F(HTTPSOCSPTest, MAYBE_RevokedStapled) {
  if (!SystemSupportsOCSPStapling()) {
    LOG(WARNING)
        << "Skipping test because system doesn't support OCSP stapling";
    return;
  }

  SpawnedTestServer::SSLOptions ssl_options(
      SpawnedTestServer::SSLOptions::CERT_AUTO);
  ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_REVOKED;
  ssl_options.staple_ocsp_response = true;
  ssl_options.ocsp_server_unavailable = true;

  CertStatus cert_status;
  DoConnection(ssl_options, &cert_status);

  EXPECT_EQ(CERT_STATUS_REVOKED, cert_status & CERT_STATUS_ALL_ERRORS);
  EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV);
  EXPECT_TRUE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
}

class HTTPSHardFailTest : public HTTPSOCSPTest {
 protected:
  void SetupContext(URLRequestContext* context) override {
    context->set_ssl_config_service(
        new TestSSLConfigService(false /* check for EV */,
                                 false /* online revocation checking */,
                                 true /* require rev. checking for local
                                         anchors */));
  }
};

TEST_F(HTTPSHardFailTest, FailsOnOCSPInvalid) {
  if (!SystemSupportsOCSP()) {
    LOG(WARNING) << "Skipping test because system doesn't support OCSP";
    return;
  }

  if (!SystemSupportsHardFailRevocationChecking()) {
    LOG(WARNING) << "Skipping test because system doesn't support hard fail "
                 << "revocation checking";
    return;
  }

  SpawnedTestServer::SSLOptions ssl_options(
      SpawnedTestServer::SSLOptions::CERT_AUTO);
  ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_INVALID;

  CertStatus cert_status;
  DoConnection(ssl_options, &cert_status);

  EXPECT_EQ(CERT_STATUS_REVOKED,
            cert_status & CERT_STATUS_REVOKED);

  // Without a positive OCSP response, we shouldn't show the EV status.
  EXPECT_TRUE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
}

class HTTPSEVCRLSetTest : public HTTPSOCSPTest {
 protected:
  void SetupContext(URLRequestContext* context) override {
    context->set_ssl_config_service(
        new TestSSLConfigService(true /* check for EV */,
                                 false /* online revocation checking */,
                                 false /* require rev. checking for local
                                          anchors */));
  }
};

TEST_F(HTTPSEVCRLSetTest, MissingCRLSetAndInvalidOCSP) {
  if (!SystemSupportsOCSP()) {
    LOG(WARNING) << "Skipping test because system doesn't support OCSP";
    return;
  }

  SpawnedTestServer::SSLOptions ssl_options(
      SpawnedTestServer::SSLOptions::CERT_AUTO);
  ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_INVALID;
  SSLConfigService::SetCRLSet(scoped_refptr<CRLSet>());

  CertStatus cert_status;
  DoConnection(ssl_options, &cert_status);

  EXPECT_EQ(ExpectedCertStatusForFailedOnlineRevocationCheck(),
            cert_status & CERT_STATUS_ALL_ERRORS);

  EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV);
  EXPECT_EQ(SystemUsesChromiumEVMetadata(),
            static_cast<bool>(cert_status & CERT_STATUS_REV_CHECKING_ENABLED));
}

TEST_F(HTTPSEVCRLSetTest, MissingCRLSetAndRevokedOCSP) {
  if (!SystemSupportsOCSP()) {
    LOG(WARNING) << "Skipping test because system doesn't support OCSP";
    return;
  }

  SpawnedTestServer::SSLOptions ssl_options(
      SpawnedTestServer::SSLOptions::CERT_AUTO);
  ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_REVOKED;
  SSLConfigService::SetCRLSet(scoped_refptr<CRLSet>());

  CertStatus cert_status;
  DoConnection(ssl_options, &cert_status);

  // Currently only works for Windows. When using NSS or OS X, it's not
  // possible to determine whether the check failed because of actual
  // revocation or because there was an OCSP failure.
#if defined(OS_WIN)
  EXPECT_EQ(CERT_STATUS_REVOKED, cert_status & CERT_STATUS_ALL_ERRORS);
#else
  EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS);
#endif

  EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV);
  EXPECT_EQ(SystemUsesChromiumEVMetadata(),
            static_cast<bool>(cert_status & CERT_STATUS_REV_CHECKING_ENABLED));
}

TEST_F(HTTPSEVCRLSetTest, MissingCRLSetAndGoodOCSP) {
  if (!SystemSupportsOCSP()) {
    LOG(WARNING) << "Skipping test because system doesn't support OCSP";
    return;
  }

  SpawnedTestServer::SSLOptions ssl_options(
      SpawnedTestServer::SSLOptions::CERT_AUTO);
  ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_OK;
  SSLConfigService::SetCRLSet(scoped_refptr<CRLSet>());

  CertStatus cert_status;
  DoConnection(ssl_options, &cert_status);

  EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS);

  EXPECT_EQ(SystemUsesChromiumEVMetadata(),
            static_cast<bool>(cert_status & CERT_STATUS_IS_EV));
  EXPECT_EQ(SystemUsesChromiumEVMetadata(),
            static_cast<bool>(cert_status & CERT_STATUS_REV_CHECKING_ENABLED));
}

TEST_F(HTTPSEVCRLSetTest, ExpiredCRLSet) {
  if (!SystemSupportsOCSP()) {
    LOG(WARNING) << "Skipping test because system doesn't support OCSP";
    return;
  }

  SpawnedTestServer::SSLOptions ssl_options(
      SpawnedTestServer::SSLOptions::CERT_AUTO);
  ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_INVALID;
  SSLConfigService::SetCRLSet(
      scoped_refptr<CRLSet>(CRLSet::ExpiredCRLSetForTesting()));

  CertStatus cert_status;
  DoConnection(ssl_options, &cert_status);

  EXPECT_EQ(ExpectedCertStatusForFailedOnlineRevocationCheck(),
            cert_status & CERT_STATUS_ALL_ERRORS);

  EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV);
  EXPECT_EQ(SystemUsesChromiumEVMetadata(),
            static_cast<bool>(cert_status & CERT_STATUS_REV_CHECKING_ENABLED));
}

TEST_F(HTTPSEVCRLSetTest, FreshCRLSetCovered) {
  if (!SystemSupportsOCSP()) {
    LOG(WARNING) << "Skipping test because system doesn't support OCSP";
    return;
  }

  SpawnedTestServer::SSLOptions ssl_options(
      SpawnedTestServer::SSLOptions::CERT_AUTO);
  ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_INVALID;
  SSLConfigService::SetCRLSet(
      scoped_refptr<CRLSet>(CRLSet::ForTesting(
          false, &kOCSPTestCertSPKI, "")));

  CertStatus cert_status;
  DoConnection(ssl_options, &cert_status);

  // With a fresh CRLSet that covers the issuing certificate, we shouldn't do a
  // revocation check for EV.
  EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS);
  EXPECT_EQ(SystemUsesChromiumEVMetadata(),
            static_cast<bool>(cert_status & CERT_STATUS_IS_EV));
  EXPECT_FALSE(
      static_cast<bool>(cert_status & CERT_STATUS_REV_CHECKING_ENABLED));
}

TEST_F(HTTPSEVCRLSetTest, FreshCRLSetNotCovered) {
  if (!SystemSupportsOCSP()) {
    LOG(WARNING) << "Skipping test because system doesn't support OCSP";
    return;
  }

  SpawnedTestServer::SSLOptions ssl_options(
      SpawnedTestServer::SSLOptions::CERT_AUTO);
  ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_INVALID;
  SSLConfigService::SetCRLSet(
      scoped_refptr<CRLSet>(CRLSet::EmptyCRLSetForTesting()));

  CertStatus cert_status = 0;
  DoConnection(ssl_options, &cert_status);

  // Even with a fresh CRLSet, we should still do online revocation checks when
  // the certificate chain isn't covered by the CRLSet, which it isn't in this
  // test.
  EXPECT_EQ(ExpectedCertStatusForFailedOnlineRevocationCheck(),
            cert_status & CERT_STATUS_ALL_ERRORS);

  EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV);
  EXPECT_EQ(SystemUsesChromiumEVMetadata(),
            static_cast<bool>(cert_status & CERT_STATUS_REV_CHECKING_ENABLED));
}

TEST_F(HTTPSEVCRLSetTest, ExpiredCRLSetAndRevokedNonEVCert) {
  // Test that when EV verification is requested, but online revocation
  // checking is disabled, and the leaf certificate is not in fact EV, that
  // no revocation checking actually happens.
  if (!SystemSupportsOCSP()) {
    LOG(WARNING) << "Skipping test because system doesn't support OCSP";
    return;
  }

  // Unmark the certificate's OID as EV, which should disable revocation
  // checking (as per the user preference)
  ev_test_policy_.reset();

  SpawnedTestServer::SSLOptions ssl_options(
      SpawnedTestServer::SSLOptions::CERT_AUTO);
  ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_REVOKED;
  SSLConfigService::SetCRLSet(
      scoped_refptr<CRLSet>(CRLSet::ExpiredCRLSetForTesting()));

  CertStatus cert_status;
  DoConnection(ssl_options, &cert_status);

  EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS);

  EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV);
  EXPECT_FALSE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
}

class HTTPSCRLSetTest : public HTTPSOCSPTest {
 protected:
  void SetupContext(URLRequestContext* context) override {
    context->set_ssl_config_service(
        new TestSSLConfigService(false /* check for EV */,
                                 false /* online revocation checking */,
                                 false /* require rev. checking for local
                                          anchors */));
  }
};

TEST_F(HTTPSCRLSetTest, ExpiredCRLSet) {
  SpawnedTestServer::SSLOptions ssl_options(
      SpawnedTestServer::SSLOptions::CERT_AUTO);
  ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_INVALID;
  SSLConfigService::SetCRLSet(
      scoped_refptr<CRLSet>(CRLSet::ExpiredCRLSetForTesting()));

  CertStatus cert_status;
  DoConnection(ssl_options, &cert_status);

  // If we're not trying EV verification then, even if the CRLSet has expired,
  // we don't fall back to online revocation checks.
  EXPECT_EQ(0u, cert_status & CERT_STATUS_ALL_ERRORS);
  EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV);
  EXPECT_FALSE(cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
}

TEST_F(HTTPSCRLSetTest, CRLSetRevoked) {
#if defined(OS_ANDROID)
  LOG(WARNING) << "Skipping test because system doesn't support CRLSets";
  return;
#endif

  SpawnedTestServer::SSLOptions ssl_options(
      SpawnedTestServer::SSLOptions::CERT_AUTO);
  ssl_options.ocsp_status = SpawnedTestServer::SSLOptions::OCSP_OK;
  ssl_options.cert_serial = 10;
  SSLConfigService::SetCRLSet(
      scoped_refptr<CRLSet>(CRLSet::ForTesting(
          false, &kOCSPTestCertSPKI, "\x0a")));

  CertStatus cert_status = 0;
  DoConnection(ssl_options, &cert_status);

  // If the certificate is recorded as revoked in the CRLSet, that should be
  // reflected without online revocation checking.
  EXPECT_EQ(CERT_STATUS_REVOKED, cert_status & CERT_STATUS_ALL_ERRORS);
  EXPECT_FALSE(cert_status & CERT_STATUS_IS_EV);
  EXPECT_FALSE(
      static_cast<bool>(cert_status & CERT_STATUS_REV_CHECKING_ENABLED));
}
#endif  // !defined(OS_IOS)

#if !defined(DISABLE_FTP_SUPPORT) && !defined(OS_ANDROID)
// These tests aren't passing on Android.  Either the RemoteTestServer isn't
// starting up successfully, or it can't access the test files.
// TODO(mmenke):  Fix this.  See http://crbug.com/495220
class URLRequestTestFTP : public URLRequestTest {
 public:
  URLRequestTestFTP()
      : ftp_transaction_factory_(&host_resolver_),
        test_server_(SpawnedTestServer::TYPE_FTP,
                     SpawnedTestServer::kLocalhost,
                     base::FilePath(kTestFilePath)) {
    // Can't use |default_context_|'s HostResolver to set up the
    // FTPTransactionFactory because it hasn't been created yet.
    default_context_.set_host_resolver(&host_resolver_);
  }

  // URLRequestTest interface:
  void SetUpFactory() override {
    // Add FTP support to the default URLRequestContext.
    job_factory_impl_->SetProtocolHandler(
        "ftp",
        make_scoped_ptr(new FtpProtocolHandler(&ftp_transaction_factory_)));
  }

  std::string GetTestFileContents() {
    base::FilePath path;
    EXPECT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &path));
    path = path.Append(kTestFilePath);
    path = path.AppendASCII(kFtpTestFile);
    std::string contents;
    EXPECT_TRUE(base::ReadFileToString(path, &contents));
    return contents;
  }

 protected:
  MockHostResolver host_resolver_;
  FtpNetworkLayer ftp_transaction_factory_;

  SpawnedTestServer test_server_;
};

// Make sure an FTP request using an unsafe ports fails.
TEST_F(URLRequestTestFTP, UnsafePort) {
  GURL url("ftp://127.0.0.1:7");

  TestDelegate d;
  {
    scoped_ptr<URLRequest> r(
        default_context_.CreateRequest(url, DEFAULT_PRIORITY, &d));
    r->Start();
    EXPECT_TRUE(r->is_pending());

    base::RunLoop().Run();

    EXPECT_FALSE(r->is_pending());
    EXPECT_EQ(URLRequestStatus::FAILED, r->status().status());
    EXPECT_EQ(ERR_UNSAFE_PORT, r->status().error());
  }
}

TEST_F(URLRequestTestFTP, FTPDirectoryListing) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  {
    scoped_ptr<URLRequest> r(default_context_.CreateRequest(
        test_server_.GetURL("/"), DEFAULT_PRIORITY, &d));
    r->Start();
    EXPECT_TRUE(r->is_pending());

    base::RunLoop().Run();

    EXPECT_FALSE(r->is_pending());
    EXPECT_EQ(1, d.response_started_count());
    EXPECT_FALSE(d.received_data_before_response());
    EXPECT_LT(0, d.bytes_received());
    EXPECT_EQ(test_server_.host_port_pair().host(),
              r->GetSocketAddress().host());
    EXPECT_EQ(test_server_.host_port_pair().port(),
              r->GetSocketAddress().port());
  }
}

TEST_F(URLRequestTestFTP, FTPGetTestAnonymous) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  {
    scoped_ptr<URLRequest> r(default_context_.CreateRequest(
        test_server_.GetURL(kFtpTestFile), DEFAULT_PRIORITY, &d));
    r->Start();
    EXPECT_TRUE(r->is_pending());

    base::RunLoop().Run();

    EXPECT_FALSE(r->is_pending());
    EXPECT_EQ(1, d.response_started_count());
    EXPECT_FALSE(d.received_data_before_response());
    EXPECT_EQ(GetTestFileContents(), d.data_received());
    EXPECT_EQ(test_server_.host_port_pair().host(),
              r->GetSocketAddress().host());
    EXPECT_EQ(test_server_.host_port_pair().port(),
              r->GetSocketAddress().port());
  }
}

TEST_F(URLRequestTestFTP, FTPGetTest) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  {
    scoped_ptr<URLRequest> r(
        default_context_.CreateRequest(test_server_.GetURLWithUserAndPassword(
                                           kFtpTestFile, "chrome", "chrome"),
                                       DEFAULT_PRIORITY, &d));
    r->Start();
    EXPECT_TRUE(r->is_pending());

    base::RunLoop().Run();

    EXPECT_FALSE(r->is_pending());
    EXPECT_EQ(1, d.response_started_count());
    EXPECT_FALSE(d.received_data_before_response());
    EXPECT_EQ(GetTestFileContents(), d.data_received());
    EXPECT_EQ(test_server_.host_port_pair().host(),
              r->GetSocketAddress().host());
    EXPECT_EQ(test_server_.host_port_pair().port(),
              r->GetSocketAddress().port());

    LoadTimingInfo load_timing_info;
    r->GetLoadTimingInfo(&load_timing_info);
    TestLoadTimingNoHttpResponse(load_timing_info);
  }
}

TEST_F(URLRequestTestFTP, FTPCheckWrongPassword) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  {
    scoped_ptr<URLRequest> r(default_context_.CreateRequest(
        test_server_.GetURLWithUserAndPassword(kFtpTestFile, "chrome",
                                               "wrong_password"),
        DEFAULT_PRIORITY, &d));
    r->Start();
    EXPECT_TRUE(r->is_pending());

    base::RunLoop().Run();

    EXPECT_FALSE(r->is_pending());
    EXPECT_EQ(1, d.response_started_count());
    EXPECT_FALSE(d.received_data_before_response());
    EXPECT_EQ(d.bytes_received(), 0);
  }
}

TEST_F(URLRequestTestFTP, FTPCheckWrongPasswordRestart) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  // Set correct login credentials. The delegate will be asked for them when
  // the initial login with wrong credentials will fail.
  d.set_credentials(AuthCredentials(kChrome, kChrome));
  {
    scoped_ptr<URLRequest> r(default_context_.CreateRequest(
        test_server_.GetURLWithUserAndPassword(kFtpTestFile, "chrome",
                                               "wrong_password"),
        DEFAULT_PRIORITY, &d));
    r->Start();
    EXPECT_TRUE(r->is_pending());

    base::RunLoop().Run();

    EXPECT_FALSE(r->is_pending());
    EXPECT_EQ(1, d.response_started_count());
    EXPECT_FALSE(d.received_data_before_response());
    EXPECT_EQ(GetTestFileContents(), d.data_received());
  }
}

TEST_F(URLRequestTestFTP, FTPCheckWrongUser) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  {
    scoped_ptr<URLRequest> r(default_context_.CreateRequest(
        test_server_.GetURLWithUserAndPassword(kFtpTestFile, "wrong_user",
                                               "chrome"),
        DEFAULT_PRIORITY, &d));
    r->Start();
    EXPECT_TRUE(r->is_pending());

    base::RunLoop().Run();

    EXPECT_FALSE(r->is_pending());
    EXPECT_EQ(1, d.response_started_count());
    EXPECT_FALSE(d.received_data_before_response());
    EXPECT_EQ(0, d.bytes_received());
  }
}

TEST_F(URLRequestTestFTP, FTPCheckWrongUserRestart) {
  ASSERT_TRUE(test_server_.Start());

  TestDelegate d;
  // Set correct login credentials. The delegate will be asked for them when
  // the initial login with wrong credentials will fail.
  d.set_credentials(AuthCredentials(kChrome, kChrome));
  {
    scoped_ptr<URLRequest> r(default_context_.CreateRequest(
        test_server_.GetURLWithUserAndPassword(kFtpTestFile, "wrong_user",
                                               "chrome"),
        DEFAULT_PRIORITY, &d));
    r->Start();
    EXPECT_TRUE(r->is_pending());

    base::RunLoop().Run();

    EXPECT_FALSE(r->is_pending());
    EXPECT_EQ(1, d.response_started_count());
    EXPECT_FALSE(d.received_data_before_response());
    EXPECT_EQ(GetTestFileContents(), d.data_received());
  }
}

TEST_F(URLRequestTestFTP, FTPCacheURLCredentials) {
  ASSERT_TRUE(test_server_.Start());

  scoped_ptr<TestDelegate> d(new TestDelegate);
  {
    // Pass correct login identity in the URL.
    scoped_ptr<URLRequest> r(
        default_context_.CreateRequest(test_server_.GetURLWithUserAndPassword(
                                           kFtpTestFile, "chrome", "chrome"),
                                       DEFAULT_PRIORITY, d.get()));
    r->Start();
    EXPECT_TRUE(r->is_pending());

    base::RunLoop().Run();

    EXPECT_FALSE(r->is_pending());
    EXPECT_EQ(1, d->response_started_count());
    EXPECT_FALSE(d->received_data_before_response());
    EXPECT_EQ(GetTestFileContents(), d->data_received());
  }

  d.reset(new TestDelegate);
  {
    // This request should use cached identity from previous request.
    scoped_ptr<URLRequest> r(default_context_.CreateRequest(
        test_server_.GetURL(kFtpTestFile), DEFAULT_PRIORITY, d.get()));
    r->Start();
    EXPECT_TRUE(r->is_pending());

    base::RunLoop().Run();

    EXPECT_FALSE(r->is_pending());
    EXPECT_EQ(1, d->response_started_count());
    EXPECT_FALSE(d->received_data_before_response());
    EXPECT_EQ(GetTestFileContents(), d->data_received());
  }
}

TEST_F(URLRequestTestFTP, FTPCacheLoginBoxCredentials) {
  ASSERT_TRUE(test_server_.Start());

  scoped_ptr<TestDelegate> d(new TestDelegate);
  // Set correct login credentials. The delegate will be asked for them when
  // the initial login with wrong credentials will fail.
  d->set_credentials(AuthCredentials(kChrome, kChrome));
  {
    scoped_ptr<URLRequest> r(default_context_.CreateRequest(
        test_server_.GetURLWithUserAndPassword(kFtpTestFile, "chrome",
                                               "wrong_password"),
        DEFAULT_PRIORITY, d.get()));
    r->Start();
    EXPECT_TRUE(r->is_pending());

    base::RunLoop().Run();

    EXPECT_FALSE(r->is_pending());
    EXPECT_EQ(1, d->response_started_count());
    EXPECT_FALSE(d->received_data_before_response());
    EXPECT_EQ(GetTestFileContents(), d->data_received());
  }

  // Use a new delegate without explicit credentials. The cached ones should be
  // used.
  d.reset(new TestDelegate);
  {
    // Don't pass wrong credentials in the URL, they would override valid cached
    // ones.
    scoped_ptr<URLRequest> r(default_context_.CreateRequest(
        test_server_.GetURL(kFtpTestFile), DEFAULT_PRIORITY, d.get()));
    r->Start();
    EXPECT_TRUE(r->is_pending());

    base::RunLoop().Run();

    EXPECT_FALSE(r->is_pending());
    EXPECT_EQ(1, d->response_started_count());
    EXPECT_FALSE(d->received_data_before_response());
    EXPECT_EQ(GetTestFileContents(), d->data_received());
  }
}
#endif  // !defined(DISABLE_FTP_SUPPORT)

TEST_F(URLRequestTest, NetworkAccessedClearBeforeNetworkStart) {
  TestDelegate d;
  scoped_ptr<URLRequest> req(default_context_.CreateRequest(
      GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d));
  d.set_quit_on_network_start(true);

  EXPECT_FALSE(req->response_info().network_accessed);

  req->Start();
  base::RunLoop().Run();

  EXPECT_EQ(1, d.received_before_network_start_count());
  EXPECT_EQ(0, d.response_started_count());
  EXPECT_FALSE(req->response_info().network_accessed);

  req->ResumeNetworkStart();
  base::RunLoop().Run();
}

TEST_F(URLRequestTest, NetworkAccessedClearOnDataRequest) {
  TestDelegate d;
  scoped_ptr<URLRequest> req(
      default_context_.CreateRequest(GURL("data:,"), DEFAULT_PRIORITY, &d));

  EXPECT_FALSE(req->response_info().network_accessed);

  req->Start();
  base::RunLoop().Run();

  EXPECT_EQ(1, default_network_delegate_.completed_requests());
  EXPECT_FALSE(req->response_info().network_accessed);
}

TEST_F(URLRequestTest, NetworkAccessedSetOnHostResolutionFailure) {
  MockHostResolver host_resolver;
  TestNetworkDelegate network_delegate;  // Must outlive URLRequest.
  TestURLRequestContext context(true);
  context.set_network_delegate(&network_delegate);
  context.set_host_resolver(&host_resolver);
  host_resolver.rules()->AddSimulatedFailure("*");
  context.Init();

  TestDelegate d;
  scoped_ptr<URLRequest> req(context.CreateRequest(
      GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d));

  EXPECT_FALSE(req->response_info().network_accessed);

  req->Start();
  base::RunLoop().Run();
  EXPECT_TRUE(req->response_info().network_accessed);
}

// Test that URLRequest is canceled correctly and with detached request
// URLRequestRedirectJob does not crash in StartAsync.
// See http://crbug.com/508900
TEST_F(URLRequestTest, URLRequestRedirectJobDetachRequestNoCrash) {
  TestDelegate d;
  scoped_ptr<URLRequest> req(default_context_.CreateRequest(
      GURL("http://not-a-real-domain/"), DEFAULT_PRIORITY, &d));

  URLRequestRedirectJob* job = new URLRequestRedirectJob(
      req.get(), &default_network_delegate_,
      GURL("http://this-should-never-be-navigated-to/"),
      URLRequestRedirectJob::REDIRECT_307_TEMPORARY_REDIRECT, "Jumbo shrimp");
  AddTestInterceptor()->set_main_intercept_job(job);

  req->Start();
  req->Cancel();
  job->DetachRequest();
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(URLRequestStatus::CANCELED, req->status().status());
  EXPECT_EQ(0, d.received_redirect_count());
}

}  // namespace net
