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

#include "net/proxy_resolution/pac_file_fetcher_impl.h"

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

#include "base/compiler_specific.h"
#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/sequenced_task_runner.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/scoped_task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
#include "net/base/filename_util.h"
#include "net/base/load_flags.h"
#include "net/base/network_delegate_impl.h"
#include "net/base/test_completion_callback.h"
#include "net/cert/ct_policy_enforcer.h"
#include "net/cert/mock_cert_verifier.h"
#include "net/cert/multi_log_ct_verifier.h"
#include "net/disk_cache/disk_cache.h"
#include "net/dns/mock_host_resolver.h"
#include "net/http/http_cache.h"
#include "net/http/http_network_session.h"
#include "net/http/http_server_properties_impl.h"
#include "net/http/http_transaction_factory.h"
#include "net/http/transport_security_state.h"
#include "net/net_buildflags.h"
#include "net/socket/client_socket_pool_manager.h"
#include "net/socket/transport_client_socket_pool.h"
#include "net/ssl/ssl_config_service_defaults.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/simple_connection_listener.h"
#include "net/test/gtest_util.h"
#include "net/test/test_with_scoped_task_environment.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/url_request_context_storage.h"
#include "net/url_request/url_request_file_job.h"
#include "net/url_request/url_request_job_factory_impl.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"

#if !BUILDFLAG(DISABLE_FILE_SUPPORT)
#include "net/url_request/file_protocol_handler.h"
#endif

using net::test::IsError;
using net::test::IsOk;

using base::ASCIIToUTF16;

// TODO(eroman):
//   - Test canceling an outstanding request.
//   - Test deleting PacFileFetcher while a request is in progress.

namespace net {

namespace {

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

struct FetchResult {
  int code;
  base::string16 text;
};

// A non-mock URL request which can access http:// and file:// urls, in the case
// the tests were built with file support.
class RequestContext : public URLRequestContext {
 public:
  RequestContext() : storage_(this) {
    ProxyConfig no_proxy;
    storage_.set_host_resolver(std::make_unique<MockHostResolver>());
    storage_.set_cert_verifier(std::make_unique<MockCertVerifier>());
    storage_.set_transport_security_state(
        std::make_unique<TransportSecurityState>());
    storage_.set_cert_transparency_verifier(
        std::make_unique<MultiLogCTVerifier>());
    storage_.set_ct_policy_enforcer(
        std::make_unique<DefaultCTPolicyEnforcer>());
    storage_.set_proxy_resolution_service(ProxyResolutionService::CreateFixed(
        ProxyConfigWithAnnotation(no_proxy, TRAFFIC_ANNOTATION_FOR_TESTS)));
    storage_.set_ssl_config_service(
        std::make_unique<SSLConfigServiceDefaults>());
    storage_.set_http_server_properties(
        std::make_unique<HttpServerPropertiesImpl>());

    HttpNetworkSession::Context session_context;
    session_context.host_resolver = host_resolver();
    session_context.cert_verifier = cert_verifier();
    session_context.transport_security_state = transport_security_state();
    session_context.cert_transparency_verifier = cert_transparency_verifier();
    session_context.ct_policy_enforcer = ct_policy_enforcer();
    session_context.proxy_resolution_service = proxy_resolution_service();
    session_context.ssl_config_service = ssl_config_service();
    session_context.http_server_properties = http_server_properties();
    storage_.set_http_network_session(std::make_unique<HttpNetworkSession>(
        HttpNetworkSession::Params(), session_context));
#ifdef HTTP_CACHE_DISABLED_FOR_STARBOARD
    storage_.set_http_transaction_factory(
        std::make_unique<HttpNetworkLayer>(storage_.http_network_session()));
#else
    storage_.set_http_transaction_factory(std::make_unique<HttpCache>(
        storage_.http_network_session(), HttpCache::DefaultBackend::InMemory(0),
        false));
#endif
    std::unique_ptr<URLRequestJobFactoryImpl> job_factory =
        std::make_unique<URLRequestJobFactoryImpl>();
#if !BUILDFLAG(DISABLE_FILE_SUPPORT)
    job_factory->SetProtocolHandler("file",
                                    std::make_unique<FileProtocolHandler>(
                                        base::ThreadTaskRunnerHandle::Get()));
#endif
    storage_.set_job_factory(std::move(job_factory));
  }

  ~RequestContext() override { AssertNoURLRequests(); }

 private:
  URLRequestContextStorage storage_;
};

// Get a file:// url relative to net/data/proxy/pac_file_fetcher_unittest.
GURL GetTestFileUrl(const std::string& relpath) {
#if BUILDFLAG(DISABLE_FILE_SUPPORT)
  LOG(WARNING)
      << "Built a file:// URL to test data, however file support is disabled.";
#endif  // BUILDFLAG(DISABLE_FILE_SUPPORT)
  base::FilePath path;
  base::PathService::Get(base::DIR_TEST_DATA, &path);
  path = path.AppendASCII("net");
  path = path.AppendASCII("data");
  path = path.AppendASCII("pac_file_fetcher_unittest");
  GURL base_url = FilePathToFileURL(path);
  return GURL(base_url.spec() + "/" + relpath);
}

// Really simple NetworkDelegate so we can allow local file access on ChromeOS
// without introducing layering violations.  Also causes a test failure if a
// request is seen that doesn't set a load flag to bypass revocation checking.

class BasicNetworkDelegate : public NetworkDelegateImpl {
 public:
  BasicNetworkDelegate() = default;
  ~BasicNetworkDelegate() override = default;

 private:
  int OnBeforeURLRequest(URLRequest* request,
                         CompletionOnceCallback callback,
                         GURL* new_url) override {
    EXPECT_TRUE(request->load_flags() & LOAD_DISABLE_CERT_NETWORK_FETCHES);
    return OK;
  }

  int OnBeforeStartTransaction(URLRequest* request,
                               CompletionOnceCallback callback,
                               HttpRequestHeaders* headers) override {
    return OK;
  }

  void OnStartTransaction(URLRequest* request,
                          const HttpRequestHeaders& headers) override {}

  int OnHeadersReceived(
      URLRequest* request,
      CompletionOnceCallback callback,
      const HttpResponseHeaders* original_response_headers,
      scoped_refptr<HttpResponseHeaders>* override_response_headers,
      GURL* allowed_unsafe_redirect_url) override {
    return OK;
  }

  void OnBeforeRedirect(URLRequest* request,
                        const GURL& new_location) override {}

  void OnResponseStarted(URLRequest* request, int net_error) override {}

  void OnCompleted(URLRequest* request, bool started, int net_error) override {}

  void OnURLRequestDestroyed(URLRequest* request) override {}

  void OnPACScriptError(int line_number, const base::string16& error) override {
  }

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

  bool OnCanGetCookies(const URLRequest& request,
                       const CookieList& cookie_list,
                       bool allowed_from_caller) override {
    return allowed_from_caller;
  }

  bool OnCanSetCookie(const URLRequest& request,
                      const net::CanonicalCookie& cookie,
                      CookieOptions* options,
                      bool allowed_from_caller) override {
    return allowed_from_caller;
  }

  bool OnCanAccessFile(const URLRequest& request,
                       const base::FilePath& original_path,
                       const base::FilePath& absolute_path) const override {
    return true;
  }

  DISALLOW_COPY_AND_ASSIGN(BasicNetworkDelegate);
};

class PacFileFetcherImplTest : public PlatformTest,
                               public WithScopedTaskEnvironment {
 public:
  PacFileFetcherImplTest() {
    test_server_.AddDefaultHandlers(base::FilePath(kDocRoot));
    context_.set_network_delegate(&network_delegate_);
  }

 protected:
  EmbeddedTestServer test_server_;
  BasicNetworkDelegate network_delegate_;
  RequestContext context_;
};

// Try fetching a non-existent PAC file via file://.
TEST_F(PacFileFetcherImplTest, FileUrlDoesNotExist) {
  auto pac_fetcher = PacFileFetcherImpl::CreateWithFileUrlSupport(&context_);

  base::string16 text;
  TestCompletionCallback callback;
  int result =
      pac_fetcher->Fetch(GetTestFileUrl("does-not-exist"), &text,
                         callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);

  EXPECT_THAT(result, IsError(ERR_IO_PENDING));
  EXPECT_TRUE(text.empty());

#if !BUILDFLAG(DISABLE_FILE_SUPPORT)
  EXPECT_THAT(callback.WaitForResult(), IsError(ERR_FILE_NOT_FOUND));
#else
  EXPECT_THAT(callback.WaitForResult(), IsError(ERR_UNKNOWN_URL_SCHEME));
#endif  // !BUILDFLAG(DISABLE_FILE_SUPPORT)
}

TEST_F(PacFileFetcherImplTest, FileUrlExists) {
  auto pac_fetcher = PacFileFetcherImpl::CreateWithFileUrlSupport(&context_);

  base::string16 text;
  TestCompletionCallback callback;
  int result =
      pac_fetcher->Fetch(GetTestFileUrl("pac.txt"), &text, callback.callback(),
                         TRAFFIC_ANNOTATION_FOR_TESTS);

  EXPECT_THAT(result, IsError(ERR_IO_PENDING));

#if !BUILDFLAG(DISABLE_FILE_SUPPORT)
  EXPECT_THAT(callback.WaitForResult(), IsOk());
  EXPECT_EQ(ASCIIToUTF16("-pac.txt-\n"), text);
#else
  EXPECT_THAT(callback.WaitForResult(), IsError(ERR_UNKNOWN_URL_SCHEME));
#endif  // !BUILDFLAG(DISABLE_FILE_SUPPORT)
}

TEST_F(PacFileFetcherImplTest, FileUrlNotAllowed) {
  auto pac_fetcher = PacFileFetcherImpl::Create(&context_);

  // Fetch a file that exists, however the PacFileFetcherImpl does not allow use
  // of file://.
  base::string16 text;
  TestCompletionCallback callback;
  int result =
      pac_fetcher->Fetch(GetTestFileUrl("pac.txt"), &text, callback.callback(),
                         TRAFFIC_ANNOTATION_FOR_TESTS);
  EXPECT_THAT(result, IsError(ERR_DISALLOWED_URL_SCHEME));
}

// Even if the fetcher allows file://, a server-side redirect from http -->
// file:// should not work.
//
// It is currently disallowed lower in the stack and results in an
// ERR_UNSAFE_REDIRECT.
TEST_F(PacFileFetcherImplTest, RedirectToFileUrl) {
  ASSERT_TRUE(test_server_.Start());

  auto pac_fetcher = PacFileFetcherImpl::CreateWithFileUrlSupport(&context_);

  GURL url(test_server_.GetURL("/redirect-to-file"));

  base::string16 text;
  TestCompletionCallback callback;
  int result = pac_fetcher->Fetch(url, &text, callback.callback(),
                                  TRAFFIC_ANNOTATION_FOR_TESTS);
  EXPECT_THAT(result, IsError(ERR_IO_PENDING));
  EXPECT_THAT(callback.WaitForResult(), IsError(ERR_UNSAFE_REDIRECT));
}

// Note that all mime types are allowed for PAC file, to be consistent
// with other browsers.
TEST_F(PacFileFetcherImplTest, HttpMimeType) {
  ASSERT_TRUE(test_server_.Start());

  auto pac_fetcher = PacFileFetcherImpl::Create(&context_);

  {  // Fetch a PAC with mime type "text/plain"
    GURL url(test_server_.GetURL("/pac.txt"));
    base::string16 text;
    TestCompletionCallback callback;
    int result = pac_fetcher->Fetch(url, &text, callback.callback(),
                                    TRAFFIC_ANNOTATION_FOR_TESTS);
    EXPECT_THAT(result, IsError(ERR_IO_PENDING));
    EXPECT_THAT(callback.WaitForResult(), IsOk());
    EXPECT_EQ(ASCIIToUTF16("-pac.txt-\n"), text);
  }
  {  // Fetch a PAC with mime type "text/html"
    GURL url(test_server_.GetURL("/pac.html"));
    base::string16 text;
    TestCompletionCallback callback;
    int result = pac_fetcher->Fetch(url, &text, callback.callback(),
                                    TRAFFIC_ANNOTATION_FOR_TESTS);
    EXPECT_THAT(result, IsError(ERR_IO_PENDING));
    EXPECT_THAT(callback.WaitForResult(), IsOk());
    EXPECT_EQ(ASCIIToUTF16("-pac.html-\n"), text);
  }
  {  // Fetch a PAC with mime type "application/x-ns-proxy-autoconfig"
    GURL url(test_server_.GetURL("/pac.nsproxy"));
    base::string16 text;
    TestCompletionCallback callback;
    int result = pac_fetcher->Fetch(url, &text, callback.callback(),
                                    TRAFFIC_ANNOTATION_FOR_TESTS);
    EXPECT_THAT(result, IsError(ERR_IO_PENDING));
    EXPECT_THAT(callback.WaitForResult(), IsOk());
    EXPECT_EQ(ASCIIToUTF16("-pac.nsproxy-\n"), text);
  }
}

TEST_F(PacFileFetcherImplTest, HttpStatusCode) {
  ASSERT_TRUE(test_server_.Start());

  auto pac_fetcher = PacFileFetcherImpl::Create(&context_);

  {  // Fetch a PAC which gives a 500 -- FAIL
    GURL url(test_server_.GetURL("/500.pac"));
    base::string16 text;
    TestCompletionCallback callback;
    int result = pac_fetcher->Fetch(url, &text, callback.callback(),
                                    TRAFFIC_ANNOTATION_FOR_TESTS);
    EXPECT_THAT(result, IsError(ERR_IO_PENDING));
    EXPECT_THAT(callback.WaitForResult(), IsError(ERR_PAC_STATUS_NOT_OK));
    EXPECT_TRUE(text.empty());
  }
  {  // Fetch a PAC which gives a 404 -- FAIL
    GURL url(test_server_.GetURL("/404.pac"));
    base::string16 text;
    TestCompletionCallback callback;
    int result = pac_fetcher->Fetch(url, &text, callback.callback(),
                                    TRAFFIC_ANNOTATION_FOR_TESTS);
    EXPECT_THAT(result, IsError(ERR_IO_PENDING));
    EXPECT_THAT(callback.WaitForResult(), IsError(ERR_PAC_STATUS_NOT_OK));
    EXPECT_TRUE(text.empty());
  }
}

TEST_F(PacFileFetcherImplTest, ContentDisposition) {
  ASSERT_TRUE(test_server_.Start());

  auto pac_fetcher = PacFileFetcherImpl::Create(&context_);

  // Fetch PAC scripts via HTTP with a Content-Disposition header -- should
  // have no effect.
  GURL url(test_server_.GetURL("/downloadable.pac"));
  base::string16 text;
  TestCompletionCallback callback;
  int result = pac_fetcher->Fetch(url, &text, callback.callback(),
                                  TRAFFIC_ANNOTATION_FOR_TESTS);
  EXPECT_THAT(result, IsError(ERR_IO_PENDING));
  EXPECT_THAT(callback.WaitForResult(), IsOk());
  EXPECT_EQ(ASCIIToUTF16("-downloadable.pac-\n"), text);
}

// Verifies that PAC scripts are not being cached.
TEST_F(PacFileFetcherImplTest, NoCache) {
  ASSERT_TRUE(test_server_.Start());

  auto pac_fetcher = PacFileFetcherImpl::Create(&context_);

  // Fetch a PAC script whose HTTP headers make it cacheable for 1 hour.
  GURL url(test_server_.GetURL("/cacheable_1hr.pac"));
  {
    base::string16 text;
    TestCompletionCallback callback;
    int result = pac_fetcher->Fetch(url, &text, callback.callback(),
                                    TRAFFIC_ANNOTATION_FOR_TESTS);
    EXPECT_THAT(result, IsError(ERR_IO_PENDING));
    EXPECT_THAT(callback.WaitForResult(), IsOk());
    EXPECT_EQ(ASCIIToUTF16("-cacheable_1hr.pac-\n"), text);
  }

  // Kill the HTTP server.
  ASSERT_TRUE(test_server_.ShutdownAndWaitUntilComplete());

  // Try to fetch the file again. Since the server is not running anymore, the
  // call should fail, thus indicating that the file was not fetched from the
  // local cache.
  {
    base::string16 text;
    TestCompletionCallback callback;
    int result = pac_fetcher->Fetch(url, &text, callback.callback(),
                                    TRAFFIC_ANNOTATION_FOR_TESTS);
    EXPECT_THAT(result, IsError(ERR_IO_PENDING));

    // Expect any error. The exact error varies by platform.
    EXPECT_NE(OK, callback.WaitForResult());
  }
}

TEST_F(PacFileFetcherImplTest, TooLarge) {
  ASSERT_TRUE(test_server_.Start());

  auto pac_fetcher = PacFileFetcherImpl::CreateWithFileUrlSupport(&context_);

  // Set the maximum response size to 50 bytes.
  int prev_size = pac_fetcher->SetSizeConstraint(50);

  // These two URLs are the same file, but are http:// vs file://
  GURL urls[] = {
    test_server_.GetURL("/large-pac.nsproxy"),
#if !BUILDFLAG(DISABLE_FILE_SUPPORT)
    GetTestFileUrl("large-pac.nsproxy")
#endif
  };

  // Try fetching URLs that are 101 bytes large. We should abort the request
  // after 50 bytes have been read, and fail with a too large error.
  for (size_t i = 0; i < arraysize(urls); ++i) {
    const GURL& url = urls[i];
    base::string16 text;
    TestCompletionCallback callback;
    int result = pac_fetcher->Fetch(url, &text, callback.callback(),
                                    TRAFFIC_ANNOTATION_FOR_TESTS);
    EXPECT_THAT(result, IsError(ERR_IO_PENDING));
    EXPECT_THAT(callback.WaitForResult(), IsError(ERR_FILE_TOO_BIG));
    EXPECT_TRUE(text.empty());
  }

  // Restore the original size bound.
  pac_fetcher->SetSizeConstraint(prev_size);

  {  // Make sure we can still fetch regular URLs.
    GURL url(test_server_.GetURL("/pac.nsproxy"));
    base::string16 text;
    TestCompletionCallback callback;
    int result = pac_fetcher->Fetch(url, &text, callback.callback(),
                                    TRAFFIC_ANNOTATION_FOR_TESTS);
    EXPECT_THAT(result, IsError(ERR_IO_PENDING));
    EXPECT_THAT(callback.WaitForResult(), IsOk());
    EXPECT_EQ(ASCIIToUTF16("-pac.nsproxy-\n"), text);
  }
}

// The PacFileFetcher should be able to handle responses with an empty body.
TEST_F(PacFileFetcherImplTest, Empty) {
  ASSERT_TRUE(test_server_.Start());

  auto pac_fetcher = PacFileFetcherImpl::Create(&context_);

  GURL url(test_server_.GetURL("/empty"));
  base::string16 text;
  TestCompletionCallback callback;
  int result = pac_fetcher->Fetch(url, &text, callback.callback(),
                                  TRAFFIC_ANNOTATION_FOR_TESTS);
  EXPECT_THAT(result, IsError(ERR_IO_PENDING));
  EXPECT_THAT(callback.WaitForResult(), IsOk());
  EXPECT_EQ(0u, text.size());
}

TEST_F(PacFileFetcherImplTest, Hang) {
  ASSERT_TRUE(test_server_.Start());

  auto pac_fetcher = PacFileFetcherImpl::Create(&context_);

  // Set the timeout period to 0.5 seconds.
  base::TimeDelta prev_timeout =
      pac_fetcher->SetTimeoutConstraint(base::TimeDelta::FromMilliseconds(500));

  // Try fetching a URL which takes 1.2 seconds. We should abort the request
  // after 500 ms, and fail with a timeout error.
  {
    GURL url(test_server_.GetURL("/slow/proxy.pac?1.2"));
    base::string16 text;
    TestCompletionCallback callback;
    int result = pac_fetcher->Fetch(url, &text, callback.callback(),
                                    TRAFFIC_ANNOTATION_FOR_TESTS);
    EXPECT_THAT(result, IsError(ERR_IO_PENDING));
    EXPECT_THAT(callback.WaitForResult(), IsError(ERR_TIMED_OUT));
    EXPECT_TRUE(text.empty());
  }

  // Restore the original timeout period.
  pac_fetcher->SetTimeoutConstraint(prev_timeout);

  {  // Make sure we can still fetch regular URLs.
    GURL url(test_server_.GetURL("/pac.nsproxy"));
    base::string16 text;
    TestCompletionCallback callback;
    int result = pac_fetcher->Fetch(url, &text, callback.callback(),
                                    TRAFFIC_ANNOTATION_FOR_TESTS);
    EXPECT_THAT(result, IsError(ERR_IO_PENDING));
    EXPECT_THAT(callback.WaitForResult(), IsOk());
    EXPECT_EQ(ASCIIToUTF16("-pac.nsproxy-\n"), text);
  }
}

// The PacFileFetcher should decode any content-codings
// (like gzip, bzip, etc.), and apply any charset conversions to yield
// UTF8.
TEST_F(PacFileFetcherImplTest, Encodings) {
  ASSERT_TRUE(test_server_.Start());

  auto pac_fetcher = PacFileFetcherImpl::Create(&context_);

  // Test a response that is gzip-encoded -- should get inflated.
  {
    GURL url(test_server_.GetURL("/gzipped_pac"));
    base::string16 text;
    TestCompletionCallback callback;
    int result = pac_fetcher->Fetch(url, &text, callback.callback(),
                                    TRAFFIC_ANNOTATION_FOR_TESTS);
    EXPECT_THAT(result, IsError(ERR_IO_PENDING));
    EXPECT_THAT(callback.WaitForResult(), IsOk());
    EXPECT_EQ(ASCIIToUTF16("This data was gzipped.\n"), text);
  }

  // Test a response that was served as UTF-16 (BE). It should
  // be converted to UTF8.
  {
    GURL url(test_server_.GetURL("/utf16be_pac"));
    base::string16 text;
    TestCompletionCallback callback;
    int result = pac_fetcher->Fetch(url, &text, callback.callback(),
                                    TRAFFIC_ANNOTATION_FOR_TESTS);
    EXPECT_THAT(result, IsError(ERR_IO_PENDING));
    EXPECT_THAT(callback.WaitForResult(), IsOk());
    EXPECT_EQ(ASCIIToUTF16("This was encoded as UTF-16BE.\n"), text);
  }
}

TEST_F(PacFileFetcherImplTest, DataURLs) {
  auto pac_fetcher = PacFileFetcherImpl::Create(&context_);

  const char kEncodedUrl[] =
      "data:application/x-ns-proxy-autoconfig;base64,ZnVuY3Rpb24gRmluZFByb3h5R"
      "m9yVVJMKHVybCwgaG9zdCkgewogIGlmIChob3N0ID09ICdmb29iYXIuY29tJykKICAgIHJl"
      "dHVybiAnUFJPWFkgYmxhY2tob2xlOjgwJzsKICByZXR1cm4gJ0RJUkVDVCc7Cn0=";
  const char kPacScript[] =
      "function FindProxyForURL(url, host) {\n"
      "  if (host == 'foobar.com')\n"
      "    return 'PROXY blackhole:80';\n"
      "  return 'DIRECT';\n"
      "}";

  // Test fetching a "data:"-url containing a base64 encoded PAC script.
  {
    GURL url(kEncodedUrl);
    base::string16 text;
    TestCompletionCallback callback;
    int result = pac_fetcher->Fetch(url, &text, callback.callback(),
                                    TRAFFIC_ANNOTATION_FOR_TESTS);
    EXPECT_THAT(result, IsOk());
    EXPECT_EQ(ASCIIToUTF16(kPacScript), text);
  }

  const char kEncodedUrlBroken[] =
      "data:application/x-ns-proxy-autoconfig;base64,ZnVuY3Rpb24gRmluZFByb3h5R";

  // Test a broken "data:"-url containing a base64 encoded PAC script.
  {
    GURL url(kEncodedUrlBroken);
    base::string16 text;
    TestCompletionCallback callback;
    int result = pac_fetcher->Fetch(url, &text, callback.callback(),
                                    TRAFFIC_ANNOTATION_FOR_TESTS);
    EXPECT_THAT(result, IsError(ERR_FAILED));
  }
}

// Makes sure that a request gets through when the socket group for the PAC URL
// is full, so PacFileFetcherImpl can use the same URLRequestContext as
// everything else.
TEST_F(PacFileFetcherImplTest, IgnoresLimits) {
  // Enough requests to exceed the per-group limit.
  int num_requests = 2 + ClientSocketPoolManager::max_sockets_per_group(
                             HttpNetworkSession::NORMAL_SOCKET_POOL);

  net::test_server::SimpleConnectionListener connection_listener(
      num_requests, net::test_server::SimpleConnectionListener::
                        FAIL_ON_ADDITIONAL_CONNECTIONS);
  test_server_.SetConnectionListener(&connection_listener);
  ASSERT_TRUE(test_server_.Start());

  std::vector<std::unique_ptr<PacFileFetcherImpl>> pac_fetchers;

  TestCompletionCallback callback;
  base::string16 text;
  for (int i = 0; i < num_requests; i++) {
    auto pac_fetcher = PacFileFetcherImpl::Create(&context_);
    GURL url(test_server_.GetURL("/hung"));
    // Fine to use the same string and callback for all of these, as they should
    // all hang.
    int result = pac_fetcher->Fetch(url, &text, callback.callback(),
                                    TRAFFIC_ANNOTATION_FOR_TESTS);
    EXPECT_THAT(result, IsError(ERR_IO_PENDING));
    pac_fetchers.push_back(std::move(pac_fetcher));
  }

  connection_listener.WaitForConnections();
  // None of the callbacks should have been invoked - all jobs should still be
  // hung.
  EXPECT_FALSE(callback.have_result());

  // Need to shut down the server before |connection_listener| is destroyed.
  EXPECT_TRUE(test_server_.ShutdownAndWaitUntilComplete());
}

TEST_F(PacFileFetcherImplTest, OnShutdown) {
  ASSERT_TRUE(test_server_.Start());

  auto pac_fetcher = PacFileFetcherImpl::Create(&context_);
  base::string16 text;
  TestCompletionCallback callback;
  int result =
      pac_fetcher->Fetch(test_server_.GetURL("/hung"), &text,
                         callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
  EXPECT_THAT(result, IsError(ERR_IO_PENDING));
  EXPECT_EQ(1u, context_.url_requests()->size());

  pac_fetcher->OnShutdown();
  EXPECT_EQ(0u, context_.url_requests()->size());
  EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONTEXT_SHUT_DOWN));

  // Make sure there's no asynchronous completion notification.
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(0u, context_.url_requests()->size());
  EXPECT_FALSE(callback.have_result());

  result =
      pac_fetcher->Fetch(test_server_.GetURL("/hung"), &text,
                         callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
  EXPECT_THAT(result, IsError(ERR_CONTEXT_SHUT_DOWN));
}

TEST_F(PacFileFetcherImplTest, OnShutdownWithNoLiveRequest) {
  ASSERT_TRUE(test_server_.Start());

  auto pac_fetcher = PacFileFetcherImpl::Create(&context_);
  pac_fetcher->OnShutdown();

  base::string16 text;
  TestCompletionCallback callback;
  int result =
      pac_fetcher->Fetch(test_server_.GetURL("/hung"), &text,
                         callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
  EXPECT_THAT(result, IsError(ERR_CONTEXT_SHUT_DOWN));
  EXPECT_EQ(0u, context_.url_requests()->size());
}

}  // namespace

}  // namespace net
