// Copyright 2014 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 "components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor.h"

#include <string>
#include <utility>
#include <vector>

#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
#include "base/run_loop.h"
#include "base/test/histogram_tester.h"
#include "base/test/scoped_task_environment.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_server.h"
#include "components/data_reduction_proxy/proto/client_config.pb.h"
#include "components/prefs/pref_service.h"
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
#include "net/base/proxy_server.h"
#include "net/base/request_priority.h"
#include "net/http/http_response_headers.h"
#include "net/log/test_net_log.h"
#include "net/socket/socket_test_util.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context_storage.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.h"
#include "net/url_request/url_request_job_factory.h"
#include "net/url_request/url_request_job_factory_impl.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"

using net::MockRead;

namespace data_reduction_proxy {

namespace {

class CountingURLRequestInterceptor : public net::URLRequestInterceptor {
 public:
  CountingURLRequestInterceptor()
      : request_count_(0), redirect_count_(0), response_count_(0) {
  }

  // URLRequestInterceptor implementation:
  net::URLRequestJob* MaybeInterceptRequest(
      net::URLRequest* request,
      net::NetworkDelegate* network_delegate) const override {
    request_count_++;
    return nullptr;
  }

  net::URLRequestJob* MaybeInterceptRedirect(
      net::URLRequest* request,
      net::NetworkDelegate* network_delegate,
      const GURL& location) const override {
    redirect_count_++;
    return nullptr;
  }

  net::URLRequestJob* MaybeInterceptResponse(
      net::URLRequest* request,
      net::NetworkDelegate* network_delegate) const override {
    response_count_++;
    return nullptr;
  }

  int request_count() const {
    return request_count_;
  }

  int redirect_count() const {
    return redirect_count_;
  }

  int response_count() const {
    return response_count_;
  }

 private:
  mutable int request_count_;
  mutable int redirect_count_;
  mutable int response_count_;
};

class TestURLRequestContextWithDataReductionProxy
    : public net::TestURLRequestContext {
 public:
  TestURLRequestContextWithDataReductionProxy(const net::ProxyServer& origin,
                                              net::NetworkDelegate* delegate)
      : net::TestURLRequestContext(true) {
    context_storage_.set_proxy_resolution_service(
        net::ProxyResolutionService::CreateFixed(origin.ToURI(),
                                                 TRAFFIC_ANNOTATION_FOR_TESTS));
    set_network_delegate(delegate);
  }

  ~TestURLRequestContextWithDataReductionProxy() override {}
};

class DataReductionProxyInterceptorTest : public testing::Test {
 public:
  DataReductionProxyInterceptorTest()
      : scoped_task_environment_(
            base::test::ScopedTaskEnvironment::MainThreadType::IO) {
    test_context_ =
        DataReductionProxyTestContext::Builder()
            .Build();
    default_context_.reset(new TestURLRequestContextWithDataReductionProxy(
        test_context_->config()
            ->test_params()
            ->proxies_for_http()
            .front()
            .proxy_server(),
        &default_network_delegate_));
    default_context_->set_network_delegate(&default_network_delegate_);
    default_context_->set_net_log(test_context_->net_log());
    test_context_->config()->test_params()->UseNonSecureProxiesForHttp();
  }

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

  void Init(std::unique_ptr<net::URLRequestJobFactory> factory) {
    job_factory_ = std::move(factory);
    default_context_->set_job_factory(job_factory_.get());
    default_context_->Init();
  }

 protected:
  base::test::ScopedTaskEnvironment scoped_task_environment_;

  std::unique_ptr<DataReductionProxyTestContext> test_context_;
  net::TestNetworkDelegate default_network_delegate_;
  std::unique_ptr<net::URLRequestJobFactory> job_factory_;
  std::unique_ptr<net::TestURLRequestContext> default_context_;
};

// Disabled on Mac due to flakiness. See crbug.com/601562.
#if defined(OS_MACOSX)
#define MAYBE_TestJobFactoryChaining DISABLED_TestJobFactoryChaining
#else
#define MAYBE_TestJobFactoryChaining TestJobFactoryChaining
#endif
TEST_F(DataReductionProxyInterceptorTest, MAYBE_TestJobFactoryChaining) {
  // Verifies that job factories can be chained.
  std::unique_ptr<net::URLRequestJobFactory> impl(
      new net::URLRequestJobFactoryImpl());

  CountingURLRequestInterceptor* interceptor2 =
      new CountingURLRequestInterceptor();
  std::unique_ptr<net::URLRequestJobFactory> factory2(
      new net::URLRequestInterceptingJobFactory(
          std::move(impl), base::WrapUnique(interceptor2)));

  CountingURLRequestInterceptor* interceptor1 =
      new CountingURLRequestInterceptor();
  std::unique_ptr<net::URLRequestJobFactory> factory1(
      new net::URLRequestInterceptingJobFactory(
          std::move(factory2), base::WrapUnique(interceptor1)));

  Init(std::move(factory1));

  net::TestDelegate d;
  std::unique_ptr<net::URLRequest> req(default_context_->CreateRequest(
      GURL("http://foo.test"), net::DEFAULT_PRIORITY, &d,
      TRAFFIC_ANNOTATION_FOR_TESTS));

  req->Start();
  base::RunLoop().Run();
  EXPECT_EQ(1, interceptor1->request_count());
  EXPECT_EQ(0, interceptor1->redirect_count());
  EXPECT_EQ(1, interceptor1->response_count());
  EXPECT_EQ(1, interceptor2->request_count());
  EXPECT_EQ(0, interceptor2->redirect_count());
  EXPECT_EQ(1, interceptor2->response_count());
}

class DataReductionProxyInterceptorWithServerTest : public testing::Test {
 public:
  DataReductionProxyInterceptorWithServerTest()
      : scoped_task_environment_(
            base::test::ScopedTaskEnvironment::MainThreadType::IO),
        context_(true) {
    context_.set_network_delegate(&network_delegate_);
    context_.set_net_log(&net_log_);
  }

  ~DataReductionProxyInterceptorWithServerTest() override {
    test_context_->io_data()->ShutdownOnUIThread();
    // URLRequestJobs may post clean-up tasks on destruction.
    test_context_->RunUntilIdle();
  }

  void SetUp() override {
    base::FilePath root_path, proxy_file_path, direct_file_path;
    base::PathService::Get(base::DIR_SOURCE_ROOT, &root_path);
    proxy_file_path = root_path.AppendASCII(
        "components/test/data/data_reduction_proxy/proxy");
    direct_file_path = root_path.AppendASCII(
        "components/test/data/data_reduction_proxy/direct");
    proxy_.ServeFilesFromDirectory(proxy_file_path);
    direct_.ServeFilesFromDirectory(direct_file_path);
    ASSERT_TRUE(proxy_.Start());
    ASSERT_TRUE(direct_.Start());

    test_context_ = DataReductionProxyTestContext::Builder()
                        .WithURLRequestContext(&context_)
                        .Build();
    std::string spec;
    base::TrimString(proxy_.GetURL("/").spec(), "/", &spec);
    net::ProxyServer origin =
        net::ProxyServer::FromURI(spec, net::ProxyServer::SCHEME_HTTP);
    std::vector<DataReductionProxyServer> proxies_for_http;
    proxies_for_http.push_back(
        DataReductionProxyServer(origin, ProxyServer::UNSPECIFIED_TYPE));
    test_context_->config()->test_params()->SetProxiesForHttp(proxies_for_http);
    std::string proxy_name = origin.ToURI();
    proxy_resolution_service_ =
        net::ProxyResolutionService::CreateFixedFromPacResult(
            "PROXY " + proxy_name + "; DIRECT", TRAFFIC_ANNOTATION_FOR_TESTS);

    context_.set_proxy_resolution_service(proxy_resolution_service_.get());

    std::unique_ptr<net::URLRequestJobFactoryImpl> job_factory_impl(
        new net::URLRequestJobFactoryImpl());
    job_factory_.reset(new net::URLRequestInterceptingJobFactory(
        std::move(job_factory_impl),
        test_context_->io_data()->CreateInterceptor()));
    context_.set_job_factory(job_factory_.get());
    context_.Init();
  }

  const net::TestURLRequestContext& context() {
    return context_;
  }

  const net::EmbeddedTestServer& direct() { return direct_; }

 protected:
  base::test::ScopedTaskEnvironment scoped_task_environment_;

 private:
  net::TestNetLog net_log_;
  net::TestNetworkDelegate network_delegate_;
  net::TestURLRequestContext context_;
  net::EmbeddedTestServer proxy_;
  net::EmbeddedTestServer direct_;
  std::unique_ptr<net::ProxyResolutionService> proxy_resolution_service_;
  std::unique_ptr<net::URLRequestJobFactory> job_factory_;
  std::unique_ptr<DataReductionProxyTestContext> test_context_;
};

TEST_F(DataReductionProxyInterceptorWithServerTest, TestBypass) {
  // Tests the mechanics of proxy bypass work with a "real" server. For tests
  // that cover every imaginable response that could trigger a bypass, see:
  // DataReductionProxyProtocolTest.
  net::TestDelegate delegate;
  std::unique_ptr<net::URLRequest> request(context().CreateRequest(
      direct().GetURL("/block10.html"), net::DEFAULT_PRIORITY, &delegate,
      TRAFFIC_ANNOTATION_FOR_TESTS));
  request->Start();
  EXPECT_TRUE(request->is_pending());
  base::RunLoop().Run();

  EXPECT_EQ(net::OK, delegate.request_status());
  EXPECT_EQ("hello", delegate.data_received());
}

TEST_F(DataReductionProxyInterceptorWithServerTest, TestNoBypass) {
  net::TestDelegate delegate;
  std::unique_ptr<net::URLRequest> request(context().CreateRequest(
      direct().GetURL("/noblock.html"), net::DEFAULT_PRIORITY, &delegate,
      TRAFFIC_ANNOTATION_FOR_TESTS));
  request->Start();
  EXPECT_TRUE(request->is_pending());
  base::RunLoop().Run();

  EXPECT_EQ(net::OK, delegate.request_status());
  EXPECT_EQ("hello", delegate.data_received());
}

class DataReductionProxyInterceptorEndToEndTest : public testing::Test {
 public:
  DataReductionProxyInterceptorEndToEndTest()
      : scoped_task_environment_(
            base::test::ScopedTaskEnvironment::MainThreadType::IO),
        context_(true),
        context_storage_(&context_) {}

  ~DataReductionProxyInterceptorEndToEndTest() override {}

  void SetUp() override {
    drp_test_context_ =
        DataReductionProxyTestContext::Builder()
            .WithURLRequestContext(&context_)
            .WithMockClientSocketFactory(&mock_socket_factory_)
            .Build();
    drp_test_context_->config()->test_params()->UseNonSecureProxiesForHttp();
    drp_test_context_->AttachToURLRequestContext(&context_storage_);
    context_.set_client_socket_factory(&mock_socket_factory_);
    proxy_delegate_ = drp_test_context_->io_data()->CreateProxyDelegate();
    context_.set_proxy_delegate(proxy_delegate_.get());
    context_.Init();
    drp_test_context_->DisableWarmupURLFetch();
    drp_test_context_->EnableDataReductionProxyWithSecureProxyCheckSuccess();

    // Three proxies should be available for use: primary, fallback, and direct.
    const net::ProxyConfig& proxy_config =
        drp_test_context_->configurator()->GetProxyConfig();
    EXPECT_EQ(3U, proxy_config.proxy_rules().proxies_for_http.size());
  }

  // Creates a URLRequest using the test's TestURLRequestContext and executes
  // it. Returns the created URLRequest.
  std::unique_ptr<net::URLRequest> CreateAndExecuteRequest(const GURL& url) {
    std::unique_ptr<net::URLRequest> request(context_.CreateRequest(
        url, net::IDLE, &delegate_, TRAFFIC_ANNOTATION_FOR_TESTS));
    request->Start();
    drp_test_context_->RunUntilIdle();
    return request;
  }

  const net::TestDelegate& delegate() const { return delegate_; }

  net::MockClientSocketFactory* mock_socket_factory() {
    return &mock_socket_factory_;
  }

  TestDataReductionProxyConfig* config() const {
    return drp_test_context_->config();
  }

  net::ProxyServer origin() const {
    return config()->test_params()->proxies_for_http().front().proxy_server();
  }

 protected:
  base::test::ScopedTaskEnvironment scoped_task_environment_;

 private:
  net::TestDelegate delegate_;
  net::MockClientSocketFactory mock_socket_factory_;
  net::TestURLRequestContext context_;
  net::URLRequestContextStorage context_storage_;
  std::unique_ptr<net::ProxyDelegate> proxy_delegate_;
  std::unique_ptr<DataReductionProxyTestContext> drp_test_context_;
};

const std::string kBody = "response body";

TEST_F(DataReductionProxyInterceptorEndToEndTest, ResponseWithoutRetry) {
  // The response comes through the proxy and should not be retried.
  MockRead mock_reads[] = {
      MockRead("HTTP/1.1 200 OK\r\nVia: 1.1 Chrome-Compression-Proxy\r\n\r\n"),
      MockRead(kBody.c_str()),
      MockRead(net::SYNCHRONOUS, net::OK),
  };
  net::StaticSocketDataProvider socket_data_provider(
      mock_reads, base::span<net::MockWrite>());
  mock_socket_factory()->AddSocketDataProvider(&socket_data_provider);

  std::unique_ptr<net::URLRequest> request =
      CreateAndExecuteRequest(GURL("http://foo.com"));

  EXPECT_EQ(net::OK, delegate().request_status());
  EXPECT_EQ(200, request->GetResponseCode());
  EXPECT_EQ(kBody, delegate().data_received());
  EXPECT_EQ(origin(), request->proxy_server());
}

TEST_F(DataReductionProxyInterceptorEndToEndTest, RedirectWithoutRetry) {
  // The redirect comes through the proxy and should not be retried.
  MockRead redirect_mock_reads[] = {
      MockRead("HTTP/1.1 302 Found\r\n"
               "Via: 1.1 Chrome-Compression-Proxy\r\n"
               "Location: http://bar.com/\r\n\r\n"),
      MockRead(""),
      MockRead(net::SYNCHRONOUS, net::OK),
  };
  net::StaticSocketDataProvider redirect_socket_data_provider(
      redirect_mock_reads, base::span<net::MockWrite>());
  mock_socket_factory()->AddSocketDataProvider(&redirect_socket_data_provider);

  // The response after the redirect comes through proxy and should not be
  // retried.
  MockRead response_mock_reads[] = {
      MockRead("HTTP/1.1 200 OK\r\nVia: 1.1 Chrome-Compression-Proxy\r\n\r\n"),
      MockRead(kBody.c_str()),
      MockRead(net::SYNCHRONOUS, net::OK),
  };
  net::StaticSocketDataProvider response_socket_data_provider(
      response_mock_reads, base::span<net::MockWrite>());
  mock_socket_factory()->AddSocketDataProvider(&response_socket_data_provider);

  std::unique_ptr<net::URLRequest> request =
      CreateAndExecuteRequest(GURL("http://foo.com"));

  EXPECT_EQ(net::OK, delegate().request_status());
  EXPECT_EQ(200, request->GetResponseCode());
  EXPECT_EQ(kBody, delegate().data_received());
  EXPECT_EQ(origin(), request->proxy_server());
  // The redirect should have been processed and followed normally.
  EXPECT_EQ(1, delegate().received_redirect_count());
}

// Test that data reduction proxy is byppassed if there is a URL redirect cycle.
TEST_F(DataReductionProxyInterceptorEndToEndTest, URLRedirectCycle) {
  base::HistogramTester histogram_tester;
  MockRead redirect_mock_reads_1[] = {
      MockRead("HTTP/1.1 302 Found\r\n"
               "Via: 1.1 Chrome-Compression-Proxy\r\n"
               "Location: http://bar.com/\r\n\r\n"),
      MockRead(""), MockRead(net::SYNCHRONOUS, net::OK),
  };
  net::StaticSocketDataProvider redirect_socket_data_provider_1(
      redirect_mock_reads_1, base::span<net::MockWrite>());
  mock_socket_factory()->AddSocketDataProvider(
      &redirect_socket_data_provider_1);

  MockRead redirect_mock_reads_2[] = {
      MockRead("HTTP/1.1 302 Found\r\n"
               "Via: 1.1 Chrome-Compression-Proxy\r\n"
               "Location: http://foo.com/\r\n\r\n"),
      MockRead(""), MockRead(net::SYNCHRONOUS, net::OK),
  };
  net::StaticSocketDataProvider redirect_socket_data_provider_2(
      redirect_mock_reads_2, base::span<net::MockWrite>());
  mock_socket_factory()->AddSocketDataProvider(
      &redirect_socket_data_provider_2);

  // Redirect cycle.
  MockRead redirect_mock_reads_3[] = {
      MockRead("HTTP/1.1 302 Found\r\n"
               "Via: 1.1 Chrome-Compression-Proxy\r\n"
               "Location: http://bar.com/\r\n\r\n"),
      MockRead(""), MockRead(net::SYNCHRONOUS, net::OK),
  };
  net::StaticSocketDataProvider redirect_socket_data_provider_3(
      redirect_mock_reads_3, base::span<net::MockWrite>());
  mock_socket_factory()->AddSocketDataProvider(
      &redirect_socket_data_provider_3);

  // Data reduction proxy should be bypassed.
  MockRead redirect_mock_reads_4[] = {
      MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead(kBody.c_str()),
      MockRead(net::SYNCHRONOUS, net::OK),
  };
  net::StaticSocketDataProvider redirect_socket_data_provider_4(
      redirect_mock_reads_4, base::span<net::MockWrite>());
  mock_socket_factory()->AddSocketDataProvider(
      &redirect_socket_data_provider_4);

  std::unique_ptr<net::URLRequest> request =
      CreateAndExecuteRequest(GURL("http://foo.com"));

  EXPECT_EQ(net::OK, delegate().request_status());
  EXPECT_EQ(200, request->GetResponseCode());
  EXPECT_EQ(kBody, delegate().data_received());
  EXPECT_TRUE(request->proxy_server().is_direct());
  histogram_tester.ExpectTotalCount(
      "DataReductionProxy.BypassedBytes.URLRedirectCycle", 1);
}

TEST_F(DataReductionProxyInterceptorEndToEndTest, ResponseWithBypassAndRetry) {
  // The first try gives a bypass.
  MockRead initial_mock_reads[] = {
      MockRead("HTTP/1.1 502 Bad Gateway\r\n"
               "Via: 1.1 Chrome-Compression-Proxy\r\n"
               "Chrome-Proxy: block-once\r\n\r\n"),
      MockRead(""),
      MockRead(net::SYNCHRONOUS, net::OK),
  };
  net::StaticSocketDataProvider initial_socket_data_provider(
      initial_mock_reads, base::span<net::MockWrite>());
  mock_socket_factory()->AddSocketDataProvider(&initial_socket_data_provider);

  // The retry after the bypass is successful.
  MockRead retry_mock_reads[] = {
      MockRead("HTTP/1.1 200 OK\r\n\r\n"),
      MockRead(kBody.c_str()),
      MockRead(net::SYNCHRONOUS, net::OK),
  };
  net::StaticSocketDataProvider retry_socket_data_provider(
      retry_mock_reads, base::span<net::MockWrite>());
  mock_socket_factory()->AddSocketDataProvider(&retry_socket_data_provider);

  std::unique_ptr<net::URLRequest> request =
      CreateAndExecuteRequest(GURL("http://foo.com"));

  EXPECT_EQ(net::OK, delegate().request_status());
  EXPECT_EQ(200, request->GetResponseCode());
  EXPECT_EQ(kBody, delegate().data_received());
  EXPECT_TRUE(request->proxy_server().is_direct());
  // The bypassed response should have been intercepted before the response was
  // processed, so only the final response after the retry should have been
  // processed.
  EXPECT_EQ(1, delegate().response_started_count());
}

TEST_F(DataReductionProxyInterceptorEndToEndTest, RedirectWithBypassAndRetry) {
  MockRead mock_reads_array[][3] = {
      // First, get a redirect without a via header, which should be retried
      // using the fallback proxy.
      {
          MockRead("HTTP/1.1 302 Found\r\n"
                   "Location: http://bar.com/\r\n\r\n"),
          MockRead(""),
          MockRead(net::SYNCHRONOUS, net::OK),
      },
      // Same as before, but through the fallback proxy. Now both proxies are
      // bypassed, and the request should be retried over direct.
      {
          MockRead("HTTP/1.1 302 Found\r\n"
                   "Location: http://baz.com/\r\n\r\n"),
          MockRead(""),
          MockRead(net::SYNCHRONOUS, net::OK),
      },
      // Finally, a successful response is received.
      {
          MockRead("HTTP/1.1 200 OK\r\n\r\n"),
          MockRead(kBody.c_str()),
          MockRead(net::SYNCHRONOUS, net::OK),
      },
  };
  std::vector<std::unique_ptr<net::SocketDataProvider>> socket_data_providers;
  for (MockRead* mock_reads : mock_reads_array) {
    socket_data_providers.push_back(
        std::make_unique<net::StaticSocketDataProvider>(
            base::make_span(mock_reads, 3), base::span<net::MockWrite>()));
    mock_socket_factory()->AddSocketDataProvider(
        socket_data_providers.back().get());
  }

  std::unique_ptr<net::URLRequest> request =
      CreateAndExecuteRequest(GURL("http://foo.com"));

  EXPECT_EQ(net::OK, delegate().request_status());
  EXPECT_EQ(200, request->GetResponseCode());
  EXPECT_EQ(kBody, delegate().data_received());
  EXPECT_TRUE(request->proxy_server().is_direct());

  // Each of the redirects should have been intercepted before being followed.
  EXPECT_EQ(0, delegate().received_redirect_count());
  EXPECT_EQ(std::vector<GURL>(1, GURL("http://foo.com")), request->url_chain());
}

TEST_F(DataReductionProxyInterceptorEndToEndTest, RedirectChainToHttps) {
  // First, a redirect is successfully received through the Data Reduction
  // Proxy. HSTS is forced for play.google.com and prebaked into Chrome, so
  // http://play.google.com will automatically be redirected to
  // https://play.google.com. See net/http/transport_security_state_static.json.
  MockRead first_redirect_reads[] = {
      MockRead(
          "HTTP/1.1 302 Found\r\n"
          "Location: http://play.google.com\r\n"
          "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n"),
      MockRead(""),
      MockRead(net::SYNCHRONOUS, net::OK),
  };
  net::StaticSocketDataProvider first_redirect_socket(
      first_redirect_reads, base::span<net::MockWrite>());
  mock_socket_factory()->AddSocketDataProvider(&first_redirect_socket);

  // Receive the response for https://play.google.com.
  MockRead https_response_reads[] = {
      MockRead("HTTP/1.1 200 OK\r\n\r\n"),
      MockRead(kBody.c_str()),
      MockRead(net::SYNCHRONOUS, net::OK),
  };
  net::StaticSocketDataProvider https_response_socket(
      https_response_reads, base::span<net::MockWrite>());
  mock_socket_factory()->AddSocketDataProvider(&https_response_socket);
  net::SSLSocketDataProvider https_response_ssl_socket(net::SYNCHRONOUS,
                                                       net::OK);
  mock_socket_factory()->AddSSLSocketDataProvider(&https_response_ssl_socket);

  std::unique_ptr<net::URLRequest> request =
      CreateAndExecuteRequest(GURL("http://music.google.com"));
  request->SetLoadFlags(net::LOAD_DISABLE_CACHE |
                        net::LOAD_DO_NOT_SEND_COOKIES |
                        net::LOAD_DO_NOT_SAVE_COOKIES);
  EXPECT_FALSE(delegate().request_failed());
  EXPECT_EQ(kBody, delegate().data_received());

  std::vector<GURL> expected_url_chain;
  expected_url_chain.push_back(GURL("http://music.google.com"));
  expected_url_chain.push_back(GURL("http://play.google.com"));
  expected_url_chain.push_back(GURL("https://play.google.com"));
  EXPECT_EQ(expected_url_chain, request->url_chain());
}

}  // namespace

}  // namespace data_reduction_proxy
