// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "services/network/url_loader.h"

#include <stdint.h>

#include <algorithm>
#include <limits>
#include <list>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>

#include "base/auto_reset.h"
#include "base/base64.h"
#include "base/byte_size.h"
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/metrics/field_trial_params.h"
#include "base/no_destructor.h"
#include "base/numerics/safe_conversions.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/strings/escape.h"
#include "base/strings/strcat.h"
#include "base/strings/string_util.h"
#include "base/strings/string_view_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
#include "base/test/bind.h"
#include "base/test/gtest_util.h"
#include "base/test/insecure_random_generator.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/run_until.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "mojo/public/c/system/data_pipe.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
#include "mojo/public/cpp/system/data_pipe_utils.h"
#include "mojo/public/cpp/system/wait.h"
#include "net/base/completion_repeating_callback.h"
#include "net/base/features.h"
#include "net/base/host_port_pair.h"
#include "net/base/io_buffer.h"
#include "net/base/ip_endpoint.h"
#include "net/base/isolation_info.h"
#include "net/base/load_flags.h"
#include "net/base/mime_sniffer.h"
#include "net/base/net_errors.h"
#include "net/base/transport_info.h"
#include "net/cert/test_root_certs.h"
#include "net/cookies/cookie_access_result.h"
#include "net/cookies/cookie_change_dispatcher.h"
#include "net/cookies/cookie_inclusion_status.h"
#include "net/cookies/cookie_partition_key.h"
#include "net/cookies/cookie_setting_override.h"
#include "net/cookies/cookie_util.h"
#include "net/dns/mock_host_resolver.h"
#include "net/filter/filter_source_stream_test_util.h"
#include "net/http/http_network_session.h"
#include "net/http/http_response_info.h"
#include "net/http/http_status_code.h"
#include "net/http/http_transaction_test_util.h"
#include "net/log/net_log_event_type.h"
#include "net/log/test_net_log.h"
#include "net/proxy_resolution/configured_proxy_resolution_service.h"
#include "net/socket/socket_test_util.h"
#include "net/ssl/client_cert_identity_test_util.h"
#include "net/storage_access_api/status.h"
#include "net/test/cert_test_util.h"
#include "net/test/embedded_test_server/controllable_http_response.h"
#include "net/test/embedded_test_server/default_handlers.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/http_connection.h"
#include "net/test/embedded_test_server/http_response.h"
#include "net/test/embedded_test_server/register_basic_auth_handler.h"
#include "net/test/gtest_util.h"
#include "net/test/quic_simple_test_server.h"
#include "net/test/test_data_directory.h"
#include "net/test/url_request/url_request_failed_job.h"
#include "net/third_party/quiche/src/quiche/common/http/http_header_block.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.h"
#include "net/url_request/url_request_context_builder.h"
#include "net/url_request/url_request_filter.h"
#include "net/url_request/url_request_interceptor.h"
#include "net/url_request/url_request_job.h"
#include "net/url_request/url_request_test_job.h"
#include "net/url_request/url_request_test_util.h"
#include "services/network/cookie_settings.h"
#include "services/network/devtools_durable_msg_accounting_delegate.h"
#include "services/network/devtools_durable_msg_collector.h"
#include "services/network/file_opener_for_upload.h"
#include "services/network/multiple_durable_message_writer_impl.h"
#include "services/network/observer_wrapper.h"
#include "services/network/pervasive_resources/shared_resource_checker.h"
#include "services/network/public/cpp/cors/origin_access_list.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/ip_address_space_util.h"
#include "services/network/public/cpp/loading_params.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/cpp/trust_token_http_headers.h"
#include "services/network/public/mojom/cookie_access_observer.mojom.h"
#include "services/network/public/mojom/early_hints.mojom.h"
#include "services/network/public/mojom/http_raw_headers.mojom.h"
#include "services/network/public/mojom/integrity_algorithm.mojom.h"
#include "services/network/public/mojom/integrity_metadata.mojom.h"
#include "services/network/public/mojom/ip_address_space.mojom.h"
#include "services/network/public/mojom/network_context.mojom.h"
#include "services/network/public/mojom/network_service.mojom.h"
#include "services/network/public/mojom/trust_tokens.mojom-shared.h"
#include "services/network/public/mojom/unencoded_digest.mojom.h"
#include "services/network/public/mojom/url_loader.mojom.h"
#include "services/network/public/mojom/url_loader_network_service_observer.mojom-shared.h"
#include "services/network/resource_scheduler/resource_scheduler_client.h"
#include "services/network/shared_dictionary/shared_dictionary_access_checker.h"
#include "services/network/test/mock_devtools_observer.h"
#include "services/network/test/test_data_pipe_getter.h"
#include "services/network/test/test_network_context_client.h"
#include "services/network/test/test_url_loader_client.h"
#include "services/network/test/test_url_loader_network_observer.h"
#include "services/network/test/url_loader_context_for_tests.h"
#include "services/network/test_chunked_data_pipe_getter.h"
#include "services/network/trust_tokens/trust_token_key_commitment_getter.h"
#include "services/network/trust_tokens/trust_token_request_helper.h"
#include "services/network/trust_tokens/trust_token_request_helper_factory.h"
#include "services/network/url_request_context_owner.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
#include "url/scheme_host_port.h"

namespace network {

namespace {

using ::net::test::IsError;
using ::net::test::IsOk;
using ::testing::Contains;
using ::testing::ElementsAre;
using ::testing::Eq;
using ::testing::Ge;
using ::testing::Key;
using ::testing::Not;
using ::testing::Optional;
using ::testing::Pointee;
using ::testing::SizeIs;
using ::testing::ValuesIn;

// Returns a URLLoader::DeleteCallback that destroys |url_loader| and quits
// |run_loop| when invoked. Tests must wait on the RunLoop to ensure nothing is
// leaked. Takes a std::unique_ptr<URLLoader>* instead of a unique_ptr because
// the callback must be created before the URLLoader is actually created.
URLLoader::DeleteCallback DeleteLoaderCallback(
    base::RunLoop* run_loop,
    std::unique_ptr<URLLoader>* url_loader) {
  return base::BindOnce(
      [](base::RunLoop* run_loop, std::unique_ptr<URLLoader>* url_loader,
         URLLoader* url_loader_ptr) {
        DCHECK_EQ(url_loader->get(), url_loader_ptr);
        url_loader->reset();
        run_loop->Quit();
      },
      run_loop, url_loader);
}

// Returns a URLLoader::DeleteCallback that does nothing, but calls NOTREACHED.
// Tests that use a URLLoader that actually tries to delete itself shouldn't use
// this method, as URLLoaders don't expect to be alive after they invoke their
// delete callback.
URLLoader::DeleteCallback NeverInvokedDeleteLoaderCallback() {
  return base::BindOnce([](URLLoader* /* loader*/) { NOTREACHED(); });
}

constexpr char kTestAuthURL[] = "/auth-basic?password=PASS&realm=REALM";

constexpr char kInsecureHost[] = "othersite.test";

constexpr char kHostnameWithAliases[] = "www.example.test";

constexpr char kHostnameWithoutAliases[] = "www.other.test";

const net::MockConnect kAsyncMockConnect =
    net::MockConnect(net::ASYNC, net::OK);

// MockWrite for requesting "http://origin.test/".
const net::MockWrite kOriginTestWrites[] = {
    net::MockWrite(net::SYNCHRONOUS,
                   0,
                   "GET / HTTP/1.1\r\n"
                   "Host: origin.test\r\n"
                   "Connection: keep-alive\r\n"
                   "User-Agent: \r\n"
                   "Accept-Encoding: gzip, deflate\r\n\r\n"),
};

static ResourceRequest CreateResourceRequest(const char* method,
                                             const GURL& url) {
  ResourceRequest request;
  request.method = std::string(method);
  request.url = url;
  request.site_for_cookies =
      net::SiteForCookies::FromUrl(url);  // bypass third-party cookie blocking
  url::Origin origin = url::Origin::Create(url);
  request.request_initiator = origin;  // ensure initiator is set
  request.is_outermost_main_frame = true;
  request.trusted_params = network::ResourceRequest::TrustedParams();
  request.trusted_params->isolation_info =
      net::IsolationInfo::CreateForInternalRequest(origin);
  return request;
}

class URLRequestMultipleWritesJob : public net::URLRequestJob {
 public:
  URLRequestMultipleWritesJob(net::URLRequest* request,
                              std::list<std::string> packets,
                              net::Error net_error,
                              bool async_reads)
      : URLRequestJob(request),
        packets_(std::move(packets)),
        net_error_(net_error),
        async_reads_(async_reads) {}

  URLRequestMultipleWritesJob(const URLRequestMultipleWritesJob&) = delete;
  URLRequestMultipleWritesJob& operator=(const URLRequestMultipleWritesJob&) =
      delete;

  ~URLRequestMultipleWritesJob() override = default;

  // net::URLRequestJob implementation:
  void Start() override {
    base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
        FROM_HERE, base::BindOnce(&URLRequestMultipleWritesJob::StartAsync,
                                  weak_factory_.GetWeakPtr()));
  }

  int ReadRawData(net::IOBuffer* buf, int buf_size) override {
    int result;
    if (packets_.empty()) {
      result = net_error_;
    } else {
      std::string packet = packets_.front();
      packets_.pop_front();
      CHECK_GE(buf_size, static_cast<int>(packet.length()));
      buf->span().copy_prefix_from(base::as_byte_span(packet));
      result = packet.length();
    }

    if (async_reads_) {
      base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
          FROM_HERE,
          base::BindOnce(&URLRequestMultipleWritesJob::ReadRawDataComplete,
                         weak_factory_.GetWeakPtr(), result));
      return net::ERR_IO_PENDING;
    }
    return result;
  }

 private:
  void StartAsync() { NotifyHeadersComplete(); }

  std::list<std::string> packets_;
  net::Error net_error_;
  bool async_reads_;

  base::WeakPtrFactory<URLRequestMultipleWritesJob> weak_factory_{this};
};

class MultipleWritesInterceptor : public net::URLRequestInterceptor {
 public:
  MultipleWritesInterceptor(std::list<std::string> packets,
                            net::Error net_error,
                            bool async_reads)
      : packets_(std::move(packets)),
        net_error_(net_error),
        async_reads_(async_reads) {}

  MultipleWritesInterceptor(const MultipleWritesInterceptor&) = delete;
  MultipleWritesInterceptor& operator=(const MultipleWritesInterceptor&) =
      delete;

  ~MultipleWritesInterceptor() override {}

  static GURL GetURL() { return GURL("http://foo"); }

  // URLRequestInterceptor implementation:
  std::unique_ptr<net::URLRequestJob> MaybeInterceptRequest(
      net::URLRequest* request) const override {
    EXPECT_FALSE(request->load_flags() & net::LOAD_BYPASS_CACHE);
    return std::make_unique<URLRequestMultipleWritesJob>(
        request, std::move(packets_), net_error_, async_reads_);
  }

 private:
  std::list<std::string> packets_;
  net::Error net_error_;
  bool async_reads_;
};

// Every read completes synchronously.
class URLRequestEternalSyncReadsJob : public net::URLRequestJob {
 public:
  // If |fill_entire_buffer| is true, each read fills the entire read buffer at
  // once. Otherwise, one byte is read at a time.
  URLRequestEternalSyncReadsJob(net::URLRequest* request,
                                bool fill_entire_buffer)
      : URLRequestJob(request), fill_entire_buffer_(fill_entire_buffer) {}

  URLRequestEternalSyncReadsJob(const URLRequestEternalSyncReadsJob&) = delete;
  URLRequestEternalSyncReadsJob& operator=(
      const URLRequestEternalSyncReadsJob&) = delete;

  ~URLRequestEternalSyncReadsJob() override = default;

  // net::URLRequestJob implementation:
  void Start() override {
    base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
        FROM_HERE, base::BindOnce(&URLRequestEternalSyncReadsJob::StartAsync,
                                  weak_factory_.GetWeakPtr()));
  }

  int ReadRawData(net::IOBuffer* buf, int buf_size) override {
    DCHECK_GT(buf_size, 0);
    if (fill_entire_buffer_) {
      std::ranges::fill(buf->first(base::checked_cast<size_t>(buf_size)), 'a');
      return buf_size;
    }

    buf->data()[0] = 'a';
    return 1;
  }

 private:
  void StartAsync() { NotifyHeadersComplete(); }

  const bool fill_entire_buffer_;

  base::WeakPtrFactory<URLRequestEternalSyncReadsJob> weak_factory_{this};
};

class EternalSyncReadsInterceptor : public net::URLRequestInterceptor {
 public:
  EternalSyncReadsInterceptor() {}

  EternalSyncReadsInterceptor(const EternalSyncReadsInterceptor&) = delete;
  EternalSyncReadsInterceptor& operator=(const EternalSyncReadsInterceptor&) =
      delete;

  ~EternalSyncReadsInterceptor() override {}

  static std::string GetHostName() { return "eternal"; }

  static GURL GetSingleByteURL() { return GURL("http://eternal/single-byte"); }
  static GURL GetFillBufferURL() { return GURL("http://eternal/fill-buffer"); }

  // URLRequestInterceptor implementation:
  std::unique_ptr<net::URLRequestJob> MaybeInterceptRequest(
      net::URLRequest* request) const override {
    EXPECT_FALSE(request->load_flags() & net::LOAD_BYPASS_CACHE);
    if (request->url() == GetSingleByteURL()) {
      return std::make_unique<URLRequestEternalSyncReadsJob>(
          request, false /* fill_entire_buffer */);
    }
    if (request->url() == GetFillBufferURL()) {
      return std::make_unique<URLRequestEternalSyncReadsJob>(
          request, true /* fill_entire_buffer */);
    }
    return nullptr;
  }
};

// Simulates handing over things to the disk to write before returning to the
// caller.
class URLRequestSimulatedCacheJob : public net::URLRequestJob {
 public:
  // If |fill_entire_buffer| is true, each read fills the entire read buffer at
  // once. Otherwise, one byte is read at a time.
  URLRequestSimulatedCacheJob(
      net::URLRequest* request,
      scoped_refptr<net::IOBuffer>* simulated_cache_dest,
      bool use_text_plain)
      : URLRequestJob(request),
        simulated_cache_dest_(simulated_cache_dest),
        use_text_plain_(use_text_plain) {}

  URLRequestSimulatedCacheJob(const URLRequestSimulatedCacheJob&) = delete;
  URLRequestSimulatedCacheJob& operator=(const URLRequestSimulatedCacheJob&) =
      delete;

  ~URLRequestSimulatedCacheJob() override = default;

  // net::URLRequestJob implementation:
  void Start() override {
    base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
        FROM_HERE, base::BindOnce(&URLRequestSimulatedCacheJob::StartAsync,
                                  weak_factory_.GetWeakPtr()));
  }

  void GetResponseInfo(net::HttpResponseInfo* info) override {
    if (!use_text_plain_) {
      return URLRequestJob::GetResponseInfo(info);
    }
    if (!info->headers) {
      info->headers = net::HttpResponseHeaders::TryToCreate(
          "HTTP/1.1 200 OK\r\nContent-Type: text/plain");
    }
  }

  int ReadRawData(net::IOBuffer* buf, int buf_size) override {
    DCHECK_GT(buf_size, 0);

    // Pretend this is the entire network stack, which has sent the buffer
    // to some worker thread to be written to disk.
    std::ranges::fill(buf->first(base::checked_cast<size_t>(buf_size)), 'a');
    *simulated_cache_dest_ = buf;

    // The network stack will not report the read result until the write
    // completes.
    return net::ERR_IO_PENDING;
  }

 private:
  void StartAsync() { NotifyHeadersComplete(); }

  raw_ptr<scoped_refptr<net::IOBuffer>> simulated_cache_dest_;
  bool use_text_plain_;
  base::WeakPtrFactory<URLRequestSimulatedCacheJob> weak_factory_{this};
};

class SimulatedCacheInterceptor : public net::URLRequestInterceptor {
 public:
  explicit SimulatedCacheInterceptor(
      scoped_refptr<net::IOBuffer>* simulated_cache_dest,
      bool use_text_plain)
      : simulated_cache_dest_(simulated_cache_dest),
        use_text_plain_(use_text_plain) {}

  SimulatedCacheInterceptor(const SimulatedCacheInterceptor&) = delete;
  SimulatedCacheInterceptor& operator=(const SimulatedCacheInterceptor&) =
      delete;

  std::unique_ptr<net::URLRequestJob> MaybeInterceptRequest(
      net::URLRequest* request) const override {
    EXPECT_FALSE(request->load_flags() & net::LOAD_BYPASS_CACHE);
    return std::make_unique<URLRequestSimulatedCacheJob>(
        request, simulated_cache_dest_, use_text_plain_);
  }

 private:
  raw_ptr<scoped_refptr<net::IOBuffer>> simulated_cache_dest_;
  bool use_text_plain_;
};

// Observes net error results. Thread-compatible.
class ResultObserver {
 public:
  ResultObserver() = default;

  ResultObserver(const ResultObserver&) = delete;
  ResultObserver& operator=(const ResultObserver&) = delete;

  void Observe(int result) { results_.push_back(result); }

  const std::vector<int>& results() { return results_; }

 private:
  std::vector<int> results_;
};

// Fakes the TransportInfo passed to `URLRequest::Delegate::OnConnected()`.
class URLRequestFakeTransportInfoJob : public net::URLRequestJob {
 public:
  // `transport_info` is subsequently passed to the `OnConnected()` callback
  // during `Start()`.
  // `second_transport_info`, if non-nullopt, is passed to the `OnConnected()`
  // callback during `ReadRawData()`.
  // `connected_callback_result_observer`, if non-nullptr, is notified of all
  // the results of calling `OnConnected()`.
  URLRequestFakeTransportInfoJob(
      net::URLRequest* request,
      net::TransportInfo transport_info,
      std::optional<net::TransportInfo> second_transport_info,
      ResultObserver* connected_callback_result_observer)
      : URLRequestJob(request),
        transport_info_(std::move(transport_info)),
        second_transport_info_(std::move(second_transport_info)),
        connected_callback_result_observer_(
            connected_callback_result_observer) {}

  URLRequestFakeTransportInfoJob(const URLRequestFakeTransportInfoJob&) =
      delete;
  URLRequestFakeTransportInfoJob& operator=(
      const URLRequestFakeTransportInfoJob&) = delete;

  ~URLRequestFakeTransportInfoJob() override = default;

  // net::URLRequestJob implementation:
  void Start() override {
    base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
        FROM_HERE, base::BindOnce(&URLRequestFakeTransportInfoJob::StartAsync,
                                  weak_factory_.GetWeakPtr()));
  }

  int ReadRawData(net::IOBuffer* buf, int buf_size) override {
    if (!second_transport_info_) {
      return 0;
    }

    int result = NotifyConnected(
        *second_transport_info_, base::BindLambdaForTesting([](int result) {
          ADD_FAILURE() << "NotifyConnected() callback called with " << result;
        }));
    ObserveResult(result);
    return result;
  }

 private:
  void StartAsync() {
    // Simulate notifying caller of a connection. Call NotifyStartError() or
    // NotifyHeadersComplete() synchronously/asynchronously on error/success,
    // depending on return value and callback invocation.
    const int result = NotifyConnected(
        transport_info_,
        base::BindOnce(
            &URLRequestFakeTransportInfoJob::ConnectedCallbackComplete,
            base::Unretained(this)));

    // Wait for callback to be invoked in async case.
    if (result == net::ERR_IO_PENDING) {
      return;
    }

    ConnectedCallbackComplete(result);
  }

  void ConnectedCallbackComplete(int result) {
    ObserveResult(result);

    if (result != net::OK) {
      NotifyStartError(result);
      return;
    }

    NotifyHeadersComplete();
  }

  void ObserveResult(int result) {
    if (!connected_callback_result_observer_) {
      return;
    }

    connected_callback_result_observer_->Observe(result);
  }

  // The fake transport info we pass to `NotifyConnected()` during `Start()`.
  const net::TransportInfo transport_info_;

  // An optional fake transport info we pass to `NotifyConnected()` during
  // `ReadRawData()`.
  const std::optional<net::TransportInfo> second_transport_info_;

  // An observer to be called with each result of calling `NotifyConnected()`.
  raw_ptr<ResultObserver> connected_callback_result_observer_;

  base::WeakPtrFactory<URLRequestFakeTransportInfoJob> weak_factory_{this};
};

// Intercepts URLRequestJob creation to a specific URL. All requests to this
// URL will report being connected with a fake TransportInfo struct.
class FakeTransportInfoInterceptor : public net::URLRequestInterceptor {
 public:
  // All intercepted requests will claim to be connected via |transport_info|.
  explicit FakeTransportInfoInterceptor(
      const net::TransportInfo& transport_info)
      : transport_info_(transport_info) {}

  // Sets a second transport info that will be passed to `OnConnected()` when
  // the response data is read.
  void SetSecondTransportInfo(const net::TransportInfo& transport_info) {
    second_transport_info_ = transport_info;
  }

  // Sets up `observer` to be notified of the result of all future calls to
  // `NotifyConnected` from within `URLRequestFakeTransportInfoJob`.
  //
  // `observer` must outlive this instance.
  void SetConnectedCallbackResultObserver(ResultObserver* observer) {
    connected_callback_result_observer_ = observer;
  }

  ~FakeTransportInfoInterceptor() override = default;

  FakeTransportInfoInterceptor(const FakeTransportInfoInterceptor&) = delete;
  FakeTransportInfoInterceptor& operator=(const FakeTransportInfoInterceptor&) =
      delete;

  // URLRequestInterceptor implementation:
  std::unique_ptr<net::URLRequestJob> MaybeInterceptRequest(
      net::URLRequest* request) const override {
    EXPECT_FALSE(request->load_flags() & net::LOAD_BYPASS_CACHE);
    return std::make_unique<URLRequestFakeTransportInfoJob>(
        request, transport_info_, second_transport_info_,
        connected_callback_result_observer_);
  }

 private:
  const net::TransportInfo transport_info_;
  std::optional<net::TransportInfo> second_transport_info_;

  raw_ptr<ResultObserver> connected_callback_result_observer_ = nullptr;
};

// Returns a maximally-restrictive security state for use in tests.
mojom::ClientSecurityStatePtr NewSecurityState() {
  auto result = mojom::ClientSecurityState::New();
  result->is_web_secure_context = false;
  result->local_network_access_request_policy =
      mojom::LocalNetworkAccessRequestPolicy::kBlock;
  result->ip_address_space = mojom::IPAddressSpace::kUnknown;
  return result;
}

CorsErrorStatus InsecureLocalNetworkCorsErrorStatus(
    mojom::IPAddressSpace resource_address_space) {
  return CorsErrorStatus(mojom::CorsError::kInsecureLocalNetwork,
                         resource_address_space);
}

std::string CookieOrLineToString(const mojom::CookieOrLinePtr& cookie_or_line) {
  switch (cookie_or_line->which()) {
    case mojom::CookieOrLine::Tag::kCookie:
      return base::StrCat({
          cookie_or_line->get_cookie().Name(),
          "=",
          cookie_or_line->get_cookie().Value(),
      });
    case mojom::CookieOrLine::Tag::kCookieString:
      return cookie_or_line->get_cookie_string();
  }
}

MATCHER_P2(CookieOrLine, string, type, "") {
  return type == arg->which() &&
         testing::ExplainMatchResult(string, CookieOrLineToString(arg),
                                     result_listener);
}

// Mock implementation of durable message accounting delegate.
class MockDurableMessageAccountingDelegate
    : public DevtoolsDurableMessageAccountingDelegate {
 public:
  void WillAddBytes(DevtoolsDurableMessage& message,
                    int64_t chunk_size) override {
    size_ += chunk_size;
  }

  void WillRemoveBytes(DevtoolsDurableMessage& message) override {
    size_ -= message.size();
  }

  void WillDestroyMessage(DevtoolsDurableMessage& message) override {}

  int64_t size() { return size_; }

 private:
  int64_t size_ = 0;
};

// Permits simply constructing a URLLoader object specifying only those options
// which are non-default.
// Replace:
//   auto url_loader = std::make_unique<URLLoader>(context(), ...,
//                                                 /*some_option=*/true);
// With:
//   URLLoaderOptions options;
//   options.some_option = true;
//   auto url_loader = options.MakeURLLoader(context(), ...);
struct URLLoaderOptions {
  // Non-optional arguments are passed to MakeURLLoader(). MakeURLLoader() can
  // only be called once for each URLLoaderOptions object.
  std::unique_ptr<URLLoader> MakeURLLoader(
      URLLoaderContext& context,
      URLLoader::DeleteCallback delete_callback,
      mojo::PendingReceiver<mojom::URLLoader> url_loader_receiver,
      const ResourceRequest& request,
      mojo::PendingRemote<mojom::URLLoaderClient> url_loader_client) {
    DCHECK(!used);
    used = true;
    shared_resource_checker =
        std::make_unique<SharedResourceChecker>(cookie_settings);

    mojo::ScopedDataPipeProducerHandle provided_response_body_stream;
    if (request.trusted_params &&
        request.trusted_params->response_body_stream) {
      provided_response_body_stream =
          std::move(const_cast<ResourceRequest&>(request)
                        .trusted_params->response_body_stream->pipe);
    }

    return std::make_unique<URLLoader>(
        context, std::move(delete_callback), std::move(url_loader_receiver),
        options, request, std::move(url_loader_client),
        std::move(sync_url_loader_client), traffic_annotation, request_id,
        keepalive_request_size, std::move(keepalive_statistics_recorder),
        std::move(trust_token_helper_factory),
        std::move(shared_dictionary_manager),
        std::move(shared_dictionary_checker),
        ObserverWrapper(std::move(cookie_observer)),
        ObserverWrapper(std::move(trust_token_observer)),
        ObserverWrapper(std::move(url_loader_network_observer)),
        ObserverWrapper(std::move(devtools_observer)),
        ObserverWrapper(std::move(device_bound_session_observer)),
        std::move(accept_ch_frame_observer), *shared_resource_checker,
        std::move(durable_message_writer),
        std::move(provided_response_body_stream));
  }

  int32_t options = mojom::kURLLoadOptionNone;
  base::WeakPtr<mojom::URLLoaderClient> sync_url_loader_client;
  net::NetworkTrafficAnnotationTag traffic_annotation =
      TRAFFIC_ANNOTATION_FOR_TESTS;
  int32_t request_id = 0;
  int keepalive_request_size = 0;
  base::WeakPtr<KeepaliveStatisticsRecorder> keepalive_statistics_recorder;
  std::unique_ptr<TrustTokenRequestHelperFactory> trust_token_helper_factory;
  raw_ptr<SharedDictionaryManager> shared_dictionary_manager;
  std::unique_ptr<SharedDictionaryAccessChecker> shared_dictionary_checker;
  mojo::PendingRemote<mojom::CookieAccessObserver> cookie_observer =
      mojo::NullRemote();
  mojo::PendingRemote<mojom::TrustTokenAccessObserver> trust_token_observer =
      mojo::NullRemote();
  mojo::PendingRemote<mojom::URLLoaderNetworkServiceObserver>
      url_loader_network_observer = mojo::NullRemote();
  mojo::PendingRemote<mojom::DevToolsObserver> devtools_observer =
      mojo::NullRemote();
  mojo::PendingRemote<mojom::DeviceBoundSessionAccessObserver>
      device_bound_session_observer = mojo::NullRemote();
  mojo::PendingRemote<mojom::AcceptCHFrameObserver> accept_ch_frame_observer =
      mojo::NullRemote();
  CookieSettings cookie_settings;
  std::unique_ptr<SharedResourceChecker> shared_resource_checker;
  std::unique_ptr<DevtoolsDurableMessageWriter> durable_message_writer;

 private:
  bool used = false;
};

}  // namespace

class MockAcceptCHFrameObserver : public mojom::AcceptCHFrameObserver {
 public:
  MockAcceptCHFrameObserver() = default;
  ~MockAcceptCHFrameObserver() override = default;

  mojo::PendingRemote<mojom::AcceptCHFrameObserver> Bind() {
    mojo::PendingRemote<mojom::AcceptCHFrameObserver> remote;
    receivers_.Add(this, remote.InitWithNewPipeAndPassReceiver());
    return remote;
  }

  void OnAcceptCHFrameReceived(
      const url::Origin& origin,
      const std::vector<network::mojom::WebClientHintsType>& accept_ch_frame,
      OnAcceptCHFrameReceivedCallback callback) override {
    called_ = true;
    accept_ch_frame_ = accept_ch_frame;
    std::move(callback).Run(net::OK);
  }
  void Clone(mojo::PendingReceiver<network::mojom::AcceptCHFrameObserver>
                 listener) override {
    receivers_.Add(this, std::move(listener));
  }

  bool called() const { return called_; }

  const std::vector<network::mojom::WebClientHintsType>& accept_ch_frame()
      const {
    return accept_ch_frame_;
  }

 private:
  bool called_ = false;
  std::vector<network::mojom::WebClientHintsType> accept_ch_frame_;
  mojo::ReceiverSet<mojom::AcceptCHFrameObserver> receivers_;
};

class SyntheticResponseFallbackInterceptor : public net::URLRequestInterceptor {
 public:
  SyntheticResponseFallbackInterceptor(const std::string& response_headers,
                                       const std::string& response_data)
      : response_headers_(response_headers), response_data_(response_data) {}
  ~SyntheticResponseFallbackInterceptor() override = default;

  std::unique_ptr<net::URLRequestJob> MaybeInterceptRequest(
      net::URLRequest* request) const override {
    return std::make_unique<net::URLRequestTestJob>(request, response_headers_,
                                                    response_data_, true);
  }

 private:
  std::string response_headers_;
  std::string response_data_;
};

class URLLoaderTestNetworkDelegate : public net::TestNetworkDelegate {
 public:
  int OnBeforeStartTransaction(
      net::URLRequest* request,
      const net::HttpRequestHeaders& headers,
      OnBeforeStartTransactionCallback callback) override {
    int rv = net::TestNetworkDelegate::OnBeforeStartTransaction(
        request, headers, base::DoNothing());
    if (rv != net::OK) {
      return rv;
    }
    URLLoader* url_loader = URLLoader::ForRequest(*request);
    if (url_loader) {
      return url_loader->OnBeforeStartTransaction(headers, std::move(callback));
    }
    return net::OK;
  }
};

class URLLoaderTest : public testing::Test {
 public:
  URLLoaderTest()
      : task_environment_(base::test::TaskEnvironment::MainThreadType::IO) {
    scoped_refptr<net::X509Certificate> quic_root = net::ImportCertFromFile(
        net::GetTestCertsDirectory().AppendASCII("quic-root.pem"));
    if (quic_root) {
      scoped_test_root_.Reset({quic_root});
    } else {
      ADD_FAILURE();
    }

    net::QuicSimpleTestServer::Start();
    net::URLRequestFailedJob::AddUrlHandler();
  }
  ~URLLoaderTest() override {
    net::URLRequestFilter::GetInstance()->ClearHandlers();
  }

  void SetUp() override {
    net::HttpNetworkSessionParams params;
    auto quic_context = std::make_unique<net::QuicContext>();
    quic_context->params()->origins_to_force_quic_on.insert(
        url::SchemeHostPort("https", net::QuicSimpleTestServer::GetHost(),
                            net::QuicSimpleTestServer::GetPort()));
    params.enable_quic = true;
    net::URLRequestContextBuilder context_builder;
    context_builder.set_http_network_session_params(params);
    context_builder.set_quic_context(std::move(quic_context));
    context_builder.set_proxy_resolution_service(
        net::ConfiguredProxyResolutionService::CreateDirect());
    auto test_network_delegate =
        std::make_unique<URLLoaderTestNetworkDelegate>();
    unowned_test_network_delegate_ = test_network_delegate.get();
    context_builder.set_network_delegate(std::move(test_network_delegate));
    context_builder.set_client_socket_factory_for_testing(GetSocketFactory());
    url_request_context_ = context_builder.Build();
    context().set_url_request_context(url_request_context_.get());
    resource_scheduler_client_ = base::MakeRefCounted<ResourceSchedulerClient>(
        ResourceScheduler::ClientId::Create(), IsBrowserInitiated(false),
        &resource_scheduler_,
        url_request_context_->network_quality_estimator());
    context().set_resource_scheduler_client(resource_scheduler_client_.get());

    test_server_.AddDefaultHandlers(
        base::FilePath(FILE_PATH_LITERAL("services/test/data")));
    // This Unretained is safe because test_server_ is owned by |this|.
    test_server_.RegisterRequestMonitor(
        base::BindRepeating(&URLLoaderTest::Monitor, base::Unretained(this)));
    RegisterAdditionalHandlers();
    ASSERT_TRUE(test_server_.Start());

    // Set up a scoped host resolver so that |kInsecureHost| will resolve to
    // the loopback address and will let us access |test_server_|.
    scoped_refptr<net::RuleBasedHostResolverProc> mock_resolver_proc =
        base::MakeRefCounted<net::RuleBasedHostResolverProc>(nullptr);
    mock_resolver_proc->AddIPLiteralRuleWithDnsAliases(
        kHostnameWithAliases, "127.0.0.1", {"alias1", "alias2", "host"});
    mock_resolver_proc->AddRule("*", "127.0.0.1");
    mock_host_resolver_ = std::make_unique<net::ScopedDefaultHostResolverProc>(
        mock_resolver_proc.get());
  }

  void TearDown() override {
    context().Detach();
    unowned_test_network_delegate_ = nullptr;
    url_request_context_.reset();
    net::QuicSimpleTestServer::Shutdown();
  }

  // For derived classes to register additional handlers for `test_server_`
  // before the server is started.
  virtual void RegisterAdditionalHandlers() {}

  // Attempts to load |url| and returns the resulting error code.
  [[nodiscard]] int Load(const GURL& url, std::string* body = nullptr) {
    DCHECK(!ran_);

    ResourceRequest request =
        CreateResourceRequest(!request_body_ ? "GET" : "POST", url);

    if (request_body_) {
      request.request_body = request_body_;
    }

    request.trusted_params->client_security_state.Swap(
        &request_client_security_state_);

    request.trusted_params->enabled_client_hints.swap(enabled_client_hints_);

    request.headers.MergeFrom(additional_headers_);

    request.client_side_content_decoding_enabled =
        client_side_content_decoding_enabled_;

    return LoadRequest(request, body);
  }

  // Attempts to load |request| and returns the resulting error code. If |body|
  // is non-NULL, also attempts to read the response body. The advantage of
  // using |body| instead of calling ReadBody() after Load is that it will load
  // the response body before URLLoader is complete, so URLLoader completion
  // won't block on trying to write the body buffer.
  [[nodiscard]] int LoadRequest(const ResourceRequest& request,
                                std::string* body = nullptr,
                                bool is_trusted = true) {
    uint32_t options = mojom::kURLLoadOptionNone;
    if (send_ssl_with_response_) {
      options |= mojom::kURLLoadOptionSendSSLInfoWithResponse;
    }
    if (sniff_) {
      options |= mojom::kURLLoadOptionSniffMimeType;
    }
    if (send_ssl_for_cert_error_) {
      options |= mojom::kURLLoadOptionSendSSLInfoForCertificateError;
    }

    std::unique_ptr<TestNetworkContextClient> network_context_client;
    std::unique_ptr<TestURLLoaderNetworkObserver> url_loader_network_observer;
    if (allow_file_uploads_) {
      network_context_client = std::make_unique<TestNetworkContextClient>();
      network_context_client->set_upload_files_invalid(upload_files_invalid_);
      network_context_client->set_ignore_last_upload_file(
          ignore_last_upload_file_);
    }
    context().set_network_context_client(network_context_client.get());

    base::RunLoop delete_run_loop;
    mojo::Remote<mojom::URLLoader> loader;
    std::unique_ptr<URLLoader> url_loader;

    SetUpContext(request.url, is_trusted);

    URLLoaderOptions url_loader_options;
    url_loader_options.options = options;
    url_loader_options.url_loader_network_observer =
        network_observer_ ? network_observer_->Bind() : mojo::NullRemote();
    url_loader_options.devtools_observer =
        devtools_observer_ ? devtools_observer_->Bind() : mojo::NullRemote();
    url_loader_options.accept_ch_frame_observer =
        accept_ch_frame_observer_ ? accept_ch_frame_observer_->Bind()
                                  : mojo::NullRemote();
    url_loader_options.durable_message_writer =
        make_unique<MultipleDurableMessageWriterImpl>(durable_messages_);
    url_loader = url_loader_options.MakeURLLoader(
        context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
        loader.BindNewPipeAndPassReceiver(), request, client_.CreateRemote());

    if (partial_decoder_decoding_buffer_size_) {
      url_loader->set_partial_decoder_decoding_buffer_size_for_testing(
          *partial_decoder_decoding_buffer_size_);
    }

    ran_ = true;
    devtools_observer_ = nullptr;
    accept_ch_frame_observer_ = nullptr;
    network_observer_ = nullptr;

    if (expect_redirect_) {
      client_.RunUntilRedirectReceived();
      loader->FollowRedirect(/*headers_update_params=*/{},
                             /*new_url=*/std::nullopt);
    }

    if (body) {
      client_.RunUntilResponseBodyArrived();
      *body = ReadBody();
    }

    client_.RunUntilComplete();
    if (body) {
      EXPECT_EQ(body->size(),
                client()->completion_status().decoded_body_length.InBytes());
    }

    delete_run_loop.Run();

    context().set_network_context_client(nullptr);
    return client_.completion_status().error_code;
  }

  void LoadAndCompareFile(const std::string& path) {
    base::FilePath file = GetTestFilePath(path);

    std::string expected;
    if (!base::ReadFileToString(file, &expected)) {
      ADD_FAILURE() << "File not found: " << file.value();
      return;
    }

    std::string body;
    EXPECT_EQ(net::OK,
              Load(test_server()->GetURL(std::string("/") + path), &body));
    EXPECT_EQ(expected, body);
    // The file isn't compressed, so both encoded and decoded body lengths
    // should match the read body length.
    EXPECT_EQ(expected.size(),
              client()->completion_status().decoded_body_length.InBytes());
    EXPECT_EQ(expected.size(),
              client()->completion_status().encoded_body_length.InBytes());
    // Over the wire length should include headers, so should be longer.
    // TODO(mmenke): Worth adding better tests for encoded_data_length?
    EXPECT_LT(expected.size(),
              client()->completion_status().encoded_data_length.InBytes());
  }

  void SetUpContext(const GURL& url, bool is_trusted) {
    context().mutable_factory_params().process_id =
        OriginatingProcessId::browser();
    context().mutable_factory_params().is_orb_enabled = orb_enabled_;
    context().mutable_factory_params().client_security_state.Swap(
        &factory_client_security_state_);
    context().mutable_factory_params().isolation_info =
        net::IsolationInfo::CreateForInternalRequest(url::Origin::Create(url));
    context().mutable_factory_params().is_trusted = is_trusted;
    context().mutable_factory_params().cookie_setting_overrides =
        cookie_setting_overrides_;
  }

  // Starts `proxy_server` as an HTTP proxy that requires basic auth with
  // "PROXY_USER" / "PROXY_PASS", and replaces the URLRequestContext with one
  // that sends all requests through it.
  void UseAuthenticatingProxy(net::EmbeddedTestServer& proxy_server) {
    net::test_server::RegisterProxyBasicAuthHandler(proxy_server, "PROXY_USER",
                                                    "PROXY_PASS");
    proxy_server.AddDefaultHandlers(
        base::FilePath(FILE_PATH_LITERAL("services/test/data")));
    ASSERT_TRUE(proxy_server.Start());

    net::URLRequestContextBuilder context_builder;
    context_builder.set_proxy_resolution_service(
        net::ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
            "PROXY " + proxy_server.host_port_pair().ToString(),
            TRAFFIC_ANNOTATION_FOR_TESTS));
    auto test_network_delegate = std::make_unique<net::TestNetworkDelegate>();
    unowned_test_network_delegate_ = test_network_delegate.get();
    context_builder.set_network_delegate(std::move(test_network_delegate));
    context_builder.set_client_socket_factory_for_testing(GetSocketFactory());
    context().set_url_request_context(nullptr);
    url_request_context_ = context_builder.Build();
    context().set_url_request_context(url_request_context_.get());
  }

  // Adds a MultipleWritesInterceptor for MultipleWritesInterceptor::GetURL()
  // that results in seeing each element of |packets| read individually, and
  // then a final read that returns |net_error|. The URLRequestInterceptor is
  // not removed from URLFilter until the test fixture is torn down.
  // |async_reads| indicates whether all reads (including those for |packets|
  // and |net_error|) complete asynchronously or not.
  void AddMultipleWritesInterceptor(std::list<std::string> packets,
                                    net::Error net_error,
                                    bool async_reads) {
    net::URLRequestFilter::GetInstance()->AddUrlInterceptor(
        MultipleWritesInterceptor::GetURL(),
        std::unique_ptr<net::URLRequestInterceptor>(
            new MultipleWritesInterceptor(std::move(packets), net_error,
                                          async_reads)));
  }

  // Adds an EternalSyncReadsInterceptor for
  // EternalSyncReadsInterceptor::GetURL(), which creates URLRequestJobs where
  // all reads return a sync byte that's read synchronously.
  void AddEternalSyncReadsInterceptor() {
    net::URLRequestFilter::GetInstance()->AddHostnameInterceptor(
        "http", EternalSyncReadsInterceptor::GetHostName(),
        std::make_unique<EternalSyncReadsInterceptor>());
  }

  // If |second| is empty, then it's ignored.
  void LoadPacketsAndVerifyContents(const std::string& first,
                                    const std::string& second) {
    EXPECT_FALSE(first.empty());
    std::list<std::string> packets;
    packets.push_back(first);
    if (!second.empty()) {
      packets.push_back(second);
    }
    AddMultipleWritesInterceptor(std::move(packets), net::OK,
                                 false /* async_reads */);

    std::string expected_body = first + second;
    std::string actual_body;
    EXPECT_EQ(net::OK, Load(MultipleWritesInterceptor::GetURL(), &actual_body));

    EXPECT_EQ(actual_body, expected_body);
  }

  const net::EmbeddedTestServer* test_server() const { return &test_server_; }
  net::EmbeddedTestServer* test_server() { return &test_server_; }
  net::URLRequestContext* url_request_context() {
    return url_request_context_.get();
  }
  URLLoaderContextForTests& context() { return url_loader_context_for_tests_; }
  TestURLLoaderClient* client() { return &client_; }

  // Returns the path of the requested file in the test data directory.
  base::FilePath GetTestFilePath(const std::string& file_name) {
    base::FilePath file_path;
    base::PathService::Get(base::DIR_SRC_TEST_DATA_ROOT, &file_path);
    file_path = file_path.Append(FILE_PATH_LITERAL("services"));
    file_path = file_path.Append(FILE_PATH_LITERAL("test"));
    file_path = file_path.Append(FILE_PATH_LITERAL("data"));
    return file_path.AppendASCII(file_name);
  }

  std::string ReadTestFile(const std::string& file_name) {
    std::string contents;
    CHECK(base::ReadFileToString(GetTestFilePath(file_name), &contents));
    return contents;
  }

  base::File OpenFileForUpload(const base::FilePath& file_path) {
    int open_flags = base::File::FLAG_OPEN | base::File::FLAG_READ;
#if BUILDFLAG(IS_WIN)
    open_flags |= base::File::FLAG_ASYNC;
#endif  //  BUILDFLAG(IS_WIN)
    base::File file(file_path, open_flags);
    EXPECT_TRUE(file.IsValid());
    return file;
  }

  ResourceScheduler* resource_scheduler() { return &resource_scheduler_; }
  scoped_refptr<ResourceSchedulerClient> resource_scheduler_client() {
    return resource_scheduler_client_;
  }

  // Configure how Load() works.
  void allow_file_uploads() {
    DCHECK(!ran_);
    allow_file_uploads_ = true;
  }
  void set_upload_files_invalid(bool upload_files_invalid) {
    DCHECK(!ran_);
    upload_files_invalid_ = upload_files_invalid;
  }
  void set_ignore_last_upload_file(bool ignore_last_upload_file) {
    DCHECK(!ran_);
    ignore_last_upload_file_ = ignore_last_upload_file;
  }
  void set_sniff() {
    DCHECK(!ran_);
    sniff_ = true;
  }
  void set_send_ssl_with_response() {
    DCHECK(!ran_);
    send_ssl_with_response_ = true;
  }
  void set_send_ssl_for_cert_error() {
    DCHECK(!ran_);
    send_ssl_for_cert_error_ = true;
  }
  void set_ignore_certificate_errors() {
    DCHECK(!ran_);
    ignore_certificate_errors_ = true;
  }
  void set_expect_redirect() {
    DCHECK(!ran_);
    expect_redirect_ = true;
  }
  void set_client_side_content_decoding_enabled() {
    DCHECK(!ran_);
    client_side_content_decoding_enabled_ = true;
  }
  void set_factory_client_security_state(mojom::ClientSecurityStatePtr state) {
    factory_client_security_state_ = std::move(state);
  }
  void set_request_client_security_state(mojom::ClientSecurityStatePtr state) {
    request_client_security_state_ = std::move(state);
  }
  void set_network_observer_for_next_request(
      TestURLLoaderNetworkObserver* observer) {
    network_observer_ = observer;
  }
  void set_devtools_observer_for_next_request(MockDevToolsObserver* observer) {
    devtools_observer_ = observer;
  }
  void set_request_body(scoped_refptr<ResourceRequestBody> request_body) {
    request_body_ = request_body;
  }
  void set_additional_headers(const net::HttpRequestHeaders& headers) {
    additional_headers_ = headers;
  }
  void set_accept_ch_frame_observer_for_next_request(
      MockAcceptCHFrameObserver* observer) {
    accept_ch_frame_observer_ = observer;
  }
  void set_enabled_client_hints_for_next_request(
      std::optional<network::ResourceRequest::TrustedParams::EnabledClientHints>
          enabled_client_hints) {
    enabled_client_hints_.swap(enabled_client_hints);
  }
  void set_cookie_setting_overrides(
      const net::CookieSettingOverrides& overrides) {
    cookie_setting_overrides_ = overrides;
  }
  void set_durable_messages(
      std::vector<base::WeakPtr<DevtoolsDurableMessage>> durable_messages) {
    durable_messages_ = std::move(durable_messages);
  }

  // Convenience methods after calling Load();
  std::string mime_type() const {
    DCHECK(ran_);
    return client_.response_head()->mime_type;
  }

  bool did_mime_sniff() const {
    DCHECK(ran_);
    return client_.response_head()->did_mime_sniff;
  }

  const std::optional<net::SSLInfo>& ssl_info() const {
    DCHECK(ran_);
    return client_.ssl_info();
  }

  // Reads the response body from client()->response_body() until the channel is
  // closed. Expects client()->response_body() to already be populated, and
  // non-NULL.
  std::string ReadBody() {
    std::string body;
    while (true) {
      MojoHandle consumer = client()->response_body().value();

      const void* buffer;
      uint32_t num_bytes;
      MojoResult rv = MojoBeginReadData(consumer, nullptr, &buffer, &num_bytes);
      // If no data has been received yet, spin the message loop until it has.
      if (rv == MOJO_RESULT_SHOULD_WAIT) {
        mojo::SimpleWatcher watcher(
            FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::AUTOMATIC,
            base::SequencedTaskRunner::GetCurrentDefault());
        base::RunLoop run_loop;

        watcher.Watch(
            client()->response_body(),
            MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
            MOJO_WATCH_CONDITION_SATISFIED,
            base::BindRepeating(
                [](base::RepeatingClosure quit, MojoResult result,
                   const mojo::HandleSignalsState& state) { quit.Run(); },
                run_loop.QuitClosure()));
        run_loop.Run();
        continue;
      }

      // The pipe was closed.
      if (rv == MOJO_RESULT_FAILED_PRECONDITION) {
        return body;
      }

      CHECK_EQ(rv, MOJO_RESULT_OK);

      body.append(static_cast<const char*>(buffer), num_bytes);
      MojoEndReadData(consumer, num_bytes, nullptr);
    }
  }

  std::string ReadAvailableBody() {
    MojoHandle consumer = client()->response_body().value();

    uint32_t num_bytes = 0;
    MojoReadDataOptions options;
    options.struct_size = sizeof(options);
    options.flags = MOJO_READ_DATA_FLAG_QUERY;
    MojoResult result = MojoReadData(consumer, &options, nullptr, &num_bytes);
    CHECK_EQ(MOJO_RESULT_OK, result);
    if (num_bytes == 0) {
      return std::string();
    }

    std::vector<char> buffer(num_bytes);
    result = MojoReadData(consumer, nullptr, buffer.data(), &num_bytes);
    CHECK_EQ(MOJO_RESULT_OK, result);
    CHECK_EQ(num_bytes, buffer.size());

    return std::string(buffer.data(), buffer.size());
  }

  const net::test_server::HttpRequest& sent_request() const {
    return sent_request_;
  }

  net::TestNetworkDelegate* test_network_delegate() {
    return unowned_test_network_delegate_;
  }

  void RunUntilIdle() { task_environment_.RunUntilIdle(); }

  static const OriginatingProcessId kProcessId;
  static constexpr int kRouteId = 8;

  // |OnServerReceivedRequest| allows subclasses to register additional logic to
  // execute once a request reaches the test server.
  virtual void OnServerReceivedRequest(const net::test_server::HttpRequest&) {}

  // Lets subclasses inject a mock ClientSocketFactory.
  virtual net::ClientSocketFactory* GetSocketFactory() { return nullptr; }

  ResourceRequest CreateCrossOriginResourceRequest() {
    ResourceRequest request =
        CreateResourceRequest("GET", test_server()->GetURL("/empty.html"));
    request.request_initiator =
        url::Origin::Create(GURL("http://other-origin.test/"));
    return request;
  }

 protected:
  void Monitor(const net::test_server::HttpRequest& request) {
    sent_request_ = request;
    OnServerReceivedRequest(request);
  }

  base::test::TaskEnvironment task_environment_;
  net::ScopedTestRoot scoped_test_root_;
  net::EmbeddedTestServer test_server_;
  std::unique_ptr<net::ScopedDefaultHostResolverProc> mock_host_resolver_;
  raw_ptr<net::TestNetworkDelegate>
      unowned_test_network_delegate_;  // owned by |url_request_context_|
  std::unique_ptr<net::URLRequestContext> url_request_context_;
  URLLoaderContextForTests url_loader_context_for_tests_;
  ResourceScheduler resource_scheduler_;
  scoped_refptr<ResourceSchedulerClient> resource_scheduler_client_;

  // Options applied to the created request in Load().
  bool allow_file_uploads_ = false;
  bool upload_files_invalid_ = false;
  bool ignore_last_upload_file_ = false;
  bool sniff_ = false;
  bool send_ssl_with_response_ = false;
  bool send_ssl_for_cert_error_ = false;
  bool ignore_certificate_errors_ = false;
  bool expect_redirect_ = false;
  bool client_side_content_decoding_enabled_ = false;
  mojom::ClientSecurityStatePtr factory_client_security_state_;
  mojom::ClientSecurityStatePtr request_client_security_state_;
  raw_ptr<TestURLLoaderNetworkObserver> network_observer_ = nullptr;
  raw_ptr<MockDevToolsObserver> devtools_observer_ = nullptr;
  scoped_refptr<ResourceRequestBody> request_body_;
  net::HttpRequestHeaders additional_headers_;
  net::CookieSettingOverrides cookie_setting_overrides_;
  std::optional<int> partial_decoder_decoding_buffer_size_;
  std::vector<base::WeakPtr<DevtoolsDurableMessage>> durable_messages_;

  bool orb_enabled_ = false;

  // Used to ensure that methods are called either before or after a request is
  // made, since the test fixture is meant to be used only once.
  bool ran_ = false;
  net::test_server::HttpRequest sent_request_;
  TestURLLoaderClient client_;

  raw_ptr<MockAcceptCHFrameObserver> accept_ch_frame_observer_ = nullptr;
  std::optional<network::ResourceRequest::TrustedParams::EnabledClientHints>
      enabled_client_hints_;
};

class URLLoaderMockSocketTest : public URLLoaderTest {
 public:
  URLLoaderMockSocketTest() = default;
  ~URLLoaderMockSocketTest() override = default;

  // Lets subclasses inject mock ClientSocketFactories.
  net::ClientSocketFactory* GetSocketFactory() override {
    return &socket_factory_;
  }

 protected:
  // Generates a sequence of random bytes that are hard to compress, using a
  // seed.
  std::vector<uint8_t> CreateRandomBytesWithSeed(uint64_t seed, size_t size) {
    std::vector<uint8_t> data;
    data.reserve(size);
    base::test::InsecureRandomGenerator gen;
    gen.ReseedForTesting(seed);
    for (size_t i = 0; i < size; ++i) {
      data.push_back(gen.RandUint32() & 0xFF);
    }
    return data;
  }

  net::MockClientSocketFactory socket_factory_;
};

const OriginatingProcessId URLLoaderTest::kProcessId =
    OriginatingProcessId::renderer(RendererProcessId(4));
constexpr int URLLoaderTest::kRouteId;

TEST_F(URLLoaderTest, ProvidedResponseBodyStream) {
  base::test::ScopedFeatureList feature_list;
  feature_list.InitAndEnableFeature(
      features::kURLLoaderUseProvidedResponseBodyStream);

  GURL url = test_server()->GetURL("/hello.html");
  ResourceRequest request = CreateResourceRequest("GET", url);

  mojo::ScopedDataPipeProducerHandle producer;
  mojo::ScopedDataPipeConsumerHandle consumer;
  ASSERT_EQ(MOJO_RESULT_OK, mojo::CreateDataPipe(nullptr, producer, consumer));

  request.trusted_params->response_body_stream =
      base::MakeRefCounted<network::SharedDataPipeProducerHandle>(
          std::move(producer));

  base::RunLoop delete_run_loop;
  mojo::Remote<mojom::URLLoader> loader;
  std::unique_ptr<URLLoader> url_loader;
  context().mutable_factory_params().process_id =
      OriginatingProcessId::browser();
  context().mutable_factory_params().is_orb_enabled = false;

  url_loader = URLLoaderOptions().MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.BindNewPipeAndPassReceiver(), request, client()->CreateRemote());

  // Wait until the load completes.
  client()->RunUntilComplete();
  EXPECT_EQ(net::OK, client()->completion_status().error_code);

  // When a response body stream is provided, the client should not receive one.
  EXPECT_FALSE(client()->response_body().is_valid());

  // Data should be written to our consumer handle.
  std::string body;
  EXPECT_TRUE(mojo::BlockingCopyToString(std::move(consumer), &body));

  base::FilePath file_path = GetTestFilePath("hello.html");
  std::string expected_body;
  ASSERT_TRUE(base::ReadFileToString(file_path, &expected_body));
  EXPECT_EQ(expected_body, body);

  delete_run_loop.Run();
}

TEST_F(URLLoaderTest, Basic) {
  LoadAndCompareFile("simple_page.html");
}

TEST_F(URLLoaderTest, Empty) {
  LoadAndCompareFile("empty.html");
}

TEST_F(URLLoaderTest, BasicSSL) {
  net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
  https_server.ServeFilesFromSourceDirectory(
      base::FilePath(FILE_PATH_LITERAL("services/test/data")));
  ASSERT_TRUE(https_server.Start());

  GURL url = https_server.GetURL("/simple_page.html");
  set_send_ssl_with_response();
  EXPECT_EQ(net::OK, Load(url));
  ASSERT_TRUE(!!ssl_info());
  ASSERT_TRUE(!!ssl_info()->cert);

  ASSERT_TRUE(https_server.GetCertificate()->EqualsExcludingChain(
      ssl_info()->cert.get()));
}

TEST_F(URLLoaderTest, SSLSentOnlyWhenRequested) {
  net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
  https_server.ServeFilesFromSourceDirectory(
      base::FilePath(FILE_PATH_LITERAL("services/test/data")));
  ASSERT_TRUE(https_server.Start());

  GURL url = https_server.GetURL("/simple_page.html");
  EXPECT_EQ(net::OK, Load(url));
  ASSERT_FALSE(!!ssl_info());
}

// This test verifies that when the request is same-origin and the origin is
// potentially trustworthy, the request is not blocked.
TEST_F(URLLoaderTest, PotentiallyTrustworthySameOriginIsOk) {
  mojom::ClientSecurityStatePtr client_security_state = NewSecurityState();
  client_security_state->ip_address_space = mojom::IPAddressSpace::kPublic;
  client_security_state->local_network_access_request_policy =
      mojom::LocalNetworkAccessRequestPolicy::kPermissionBlock;
  set_factory_client_security_state(std::move(client_security_state));

  GURL url = test_server()->GetURL("/empty.html");
  ResourceRequest request = CreateResourceRequest("GET", url);
  request.request_initiator = url::Origin::Create(url);

  EXPECT_EQ(net::OK, LoadRequest(request));
}

// This test verifies that when the URLLoaderFactory's parameters are missing
// a client security state, requests to local network resources are authorized.
TEST_F(URLLoaderTest, MissingClientSecurityStateIsOk) {
  EXPECT_EQ(net::OK, LoadRequest(CreateCrossOriginResourceRequest()));
}

// This test verifies that when the request calls `URLLoader::OnConnected()`
// twice with endpoints belonging to different IP address spaces, the request
// fails. In that case `URLLoader::OnConnected()` returns the right error code,
// which causes any cache entry in use to be invalidated.
TEST_F(URLLoaderTest, InconsistentIPAddressSpaceIsBlocked) {
  auto client_security_state = NewSecurityState();
  client_security_state->ip_address_space = mojom::IPAddressSpace::kPublic;
  client_security_state->is_web_secure_context = true;
  client_security_state->local_network_access_request_policy =
      mojom::LocalNetworkAccessRequestPolicy::kPermissionBlock;
  set_factory_client_security_state(std::move(client_security_state));

  ResultObserver connected_callback_result_observer;

  net::TransportInfo info = net::DefaultTransportInfo();
  info.endpoint = net::IPEndPoint(net::IPAddress(1, 2, 3, 4), 80);
  auto interceptor = std::make_unique<FakeTransportInfoInterceptor>(info);

  info.endpoint = net::IPEndPoint(net::IPAddress(127, 0, 0, 1), 80);
  interceptor->SetSecondTransportInfo(info);
  interceptor->SetConnectedCallbackResultObserver(
      &connected_callback_result_observer);

  const GURL url("http://fake-endpoint");

  net::URLRequestFilter::GetInstance()->AddUrlInterceptor(
      url, std::move(interceptor));

  ResourceRequest request = CreateResourceRequest("GET", url);
  request.request_initiator =
      url::Origin::Create(GURL("http://other-origin.test/"));

  EXPECT_EQ(net::ERR_FAILED, LoadRequest(request));
  EXPECT_THAT(
      client()->completion_status().cors_error_status,
      Optional(CorsErrorStatus(
          mojom::CorsError::kInvalidLocalNetworkAccess,
          /*resource_address_space=*/mojom::IPAddressSpace::kLoopback,
          /*inconsistent_address_space=*/mojom::IPAddressSpace::kPublic)));

  // The first connection was fine, but the second was inconsistent.
  EXPECT_THAT(connected_callback_result_observer.results(),
              ElementsAre(IsError(net::OK),
                          IsError(net::ERR_INCONSISTENT_IP_ADDRESS_SPACE)));
}

// These tests verify that requests from both secure and non-secure contexts to
// an IP in the `kLoopback` address space are only blocked when the policy is
// `kBlock` and the initiator's address space is not `kLoopback`.
//
// NOTE: These tests exercise the same codepath as
// URLLoaderFakeTransportInfoTest below, except they use real URLRequestJob and
// HttpTransaction implementations for higher confidence in the correctness of
// the whole stack. OTOH, using an embedded test server prevents us from mocking
// out the endpoint IP address.

TEST_F(URLLoaderTest, SecureUnknownToLoopbackBlock) {
  auto client_security_state = NewSecurityState();
  client_security_state->is_web_secure_context = true;
  client_security_state->ip_address_space = mojom::IPAddressSpace::kUnknown;
  set_factory_client_security_state(std::move(client_security_state));

  ResourceRequest request = CreateCrossOriginResourceRequest();

  EXPECT_EQ(net::ERR_BLOCKED_BY_LOCAL_NETWORK_ACCESS_CHECKS,
            LoadRequest(request));
  EXPECT_THAT(client()->completion_status().cors_error_status,
              Optional(InsecureLocalNetworkCorsErrorStatus(
                  mojom::IPAddressSpace::kLoopback)));
}

TEST_F(URLLoaderTest, SecureUnknownToLoopbackWarn) {
  auto client_security_state = NewSecurityState();
  client_security_state->is_web_secure_context = true;
  client_security_state->ip_address_space = mojom::IPAddressSpace::kUnknown;
  client_security_state->local_network_access_request_policy =
      mojom::LocalNetworkAccessRequestPolicy::kWarn;
  set_factory_client_security_state(std::move(client_security_state));

  ResourceRequest request = CreateCrossOriginResourceRequest();

  EXPECT_EQ(net::OK, LoadRequest(request));
}

TEST_F(URLLoaderTest, SecureUnknownToLoopbackAllow) {
  auto client_security_state = NewSecurityState();
  client_security_state->is_web_secure_context = true;
  client_security_state->ip_address_space = mojom::IPAddressSpace::kUnknown;
  client_security_state->local_network_access_request_policy =
      mojom::LocalNetworkAccessRequestPolicy::kAllow;
  set_factory_client_security_state(std::move(client_security_state));

  ResourceRequest request = CreateCrossOriginResourceRequest();

  EXPECT_EQ(net::OK, LoadRequest(request));
}

TEST_F(URLLoaderTest, NonSecureUnknownToLoopbackBlock) {
  auto client_security_state = NewSecurityState();
  client_security_state->ip_address_space = mojom::IPAddressSpace::kUnknown;
  set_factory_client_security_state(std::move(client_security_state));

  ResourceRequest request = CreateCrossOriginResourceRequest();

  EXPECT_EQ(net::ERR_BLOCKED_BY_LOCAL_NETWORK_ACCESS_CHECKS,
            LoadRequest(request));
  EXPECT_THAT(client()->completion_status().cors_error_status,
              Optional(InsecureLocalNetworkCorsErrorStatus(
                  mojom::IPAddressSpace::kLoopback)));
}

TEST_F(URLLoaderTest, NonSecureUnknownToLoopbackWarn) {
  auto client_security_state = NewSecurityState();
  client_security_state->ip_address_space = mojom::IPAddressSpace::kUnknown;
  client_security_state->local_network_access_request_policy =
      mojom::LocalNetworkAccessRequestPolicy::kWarn;
  set_factory_client_security_state(std::move(client_security_state));

  ResourceRequest request = CreateCrossOriginResourceRequest();

  EXPECT_EQ(net::OK, LoadRequest(request));
}

TEST_F(URLLoaderTest, NonSecureUnknownToLoopbackAllow) {
  auto client_security_state = NewSecurityState();
  client_security_state->ip_address_space = mojom::IPAddressSpace::kUnknown;
  client_security_state->local_network_access_request_policy =
      mojom::LocalNetworkAccessRequestPolicy::kAllow;
  set_factory_client_security_state(std::move(client_security_state));

  ResourceRequest request = CreateCrossOriginResourceRequest();

  EXPECT_EQ(net::OK, LoadRequest(request));
}


TEST_F(URLLoaderTest, SecurePublicToLoopbackBlock) {
  auto client_security_state = NewSecurityState();
  client_security_state->is_web_secure_context = true;
  client_security_state->ip_address_space = mojom::IPAddressSpace::kPublic;
  set_factory_client_security_state(std::move(client_security_state));

  ResourceRequest request = CreateCrossOriginResourceRequest();

  EXPECT_EQ(net::ERR_BLOCKED_BY_LOCAL_NETWORK_ACCESS_CHECKS,
            LoadRequest(request));
  EXPECT_THAT(client()->completion_status().cors_error_status,
              Optional(InsecureLocalNetworkCorsErrorStatus(
                  mojom::IPAddressSpace::kLoopback)));
}

TEST_F(URLLoaderTest, SecurePublicToLoopbackWarn) {
  auto client_security_state = NewSecurityState();
  client_security_state->is_web_secure_context = true;
  client_security_state->ip_address_space = mojom::IPAddressSpace::kPublic;
  client_security_state->local_network_access_request_policy =
      mojom::LocalNetworkAccessRequestPolicy::kWarn;
  set_factory_client_security_state(std::move(client_security_state));

  ResourceRequest request = CreateCrossOriginResourceRequest();

  EXPECT_EQ(net::OK, LoadRequest(request));
}

TEST_F(URLLoaderTest, SecurePublicToLoopbackAllow) {
  auto client_security_state = NewSecurityState();
  client_security_state->is_web_secure_context = true;
  client_security_state->ip_address_space = mojom::IPAddressSpace::kPublic;
  client_security_state->local_network_access_request_policy =
      mojom::LocalNetworkAccessRequestPolicy::kAllow;
  set_factory_client_security_state(std::move(client_security_state));

  ResourceRequest request = CreateCrossOriginResourceRequest();

  EXPECT_EQ(net::OK, LoadRequest(request));
}

TEST_F(URLLoaderTest, NonSecurePublicToLoopbackBlock) {
  auto client_security_state = NewSecurityState();
  client_security_state->ip_address_space = mojom::IPAddressSpace::kPublic;
  set_factory_client_security_state(std::move(client_security_state));

  ResourceRequest request = CreateCrossOriginResourceRequest();

  EXPECT_EQ(net::ERR_BLOCKED_BY_LOCAL_NETWORK_ACCESS_CHECKS,
            LoadRequest(request));
  EXPECT_THAT(client()->completion_status().cors_error_status,
              Optional(InsecureLocalNetworkCorsErrorStatus(
                  mojom::IPAddressSpace::kLoopback)));
}

TEST_F(URLLoaderTest, NonSecurePublicToLoopbackWarn) {
  auto client_security_state = NewSecurityState();
  client_security_state->ip_address_space = mojom::IPAddressSpace::kPublic;
  client_security_state->local_network_access_request_policy =
      mojom::LocalNetworkAccessRequestPolicy::kWarn;
  set_factory_client_security_state(std::move(client_security_state));

  ResourceRequest request = CreateCrossOriginResourceRequest();

  EXPECT_EQ(net::OK, LoadRequest(request));
}

TEST_F(URLLoaderTest, NonSecurePublicToLoopbackAllow) {
  auto client_security_state = NewSecurityState();
  client_security_state->ip_address_space = mojom::IPAddressSpace::kPublic;
  client_security_state->local_network_access_request_policy =
      mojom::LocalNetworkAccessRequestPolicy::kAllow;
  set_factory_client_security_state(std::move(client_security_state));

  ResourceRequest request = CreateCrossOriginResourceRequest();

  EXPECT_EQ(net::OK, LoadRequest(request));
}


TEST_F(URLLoaderTest, SecureLocalToLoopbackDefault) {
  // This test presumes that LNA enforcement is enabled.
  base::test::ScopedFeatureList feature_list(
      features::kLocalNetworkAccessChecks);

  auto client_security_state = NewSecurityState();
  client_security_state->is_web_secure_context = true;
  client_security_state->ip_address_space = mojom::IPAddressSpace::kLocal;
  set_factory_client_security_state(std::move(client_security_state));

  ResourceRequest request = CreateCrossOriginResourceRequest();

  // Local and Loopback are currently merged and LNA checks are not
  // enforced.
  EXPECT_EQ(net::OK, LoadRequest(request));
}

TEST_F(URLLoaderTest, SecureLocalToLoopbackWarn) {
  auto client_security_state = NewSecurityState();
  client_security_state->is_web_secure_context = true;
  client_security_state->ip_address_space = mojom::IPAddressSpace::kLocal;
  client_security_state->local_network_access_request_policy =
      mojom::LocalNetworkAccessRequestPolicy::kWarn;
  set_factory_client_security_state(std::move(client_security_state));

  ResourceRequest request = CreateCrossOriginResourceRequest();

  EXPECT_EQ(net::OK, LoadRequest(request));
}

TEST_F(URLLoaderTest, SecureLocalToLoopbackAllow) {
  auto client_security_state = NewSecurityState();
  client_security_state->is_web_secure_context = true;
  client_security_state->ip_address_space = mojom::IPAddressSpace::kLocal;
  client_security_state->local_network_access_request_policy =
      mojom::LocalNetworkAccessRequestPolicy::kAllow;
  set_factory_client_security_state(std::move(client_security_state));

  ResourceRequest request = CreateCrossOriginResourceRequest();

  EXPECT_EQ(net::OK, LoadRequest(request));
}

TEST_F(URLLoaderTest, NonSecureLocalToLoopbackDefault) {
  // This test presumes that LNA enforcement is enabled.
  base::test::ScopedFeatureList feature_list(
      features::kLocalNetworkAccessChecks);

  auto client_security_state = NewSecurityState();
  client_security_state->ip_address_space = mojom::IPAddressSpace::kLocal;
  set_factory_client_security_state(std::move(client_security_state));

  ResourceRequest request = CreateCrossOriginResourceRequest();

  // Local and Loopback are currently merged and LNA checks are not
  // enforced.
  EXPECT_EQ(net::OK, LoadRequest(request));
}

TEST_F(URLLoaderTest, NonSecureLocalToLoopbackWarn) {
  auto client_security_state = NewSecurityState();
  client_security_state->ip_address_space = mojom::IPAddressSpace::kLocal;
  client_security_state->local_network_access_request_policy =
      mojom::LocalNetworkAccessRequestPolicy::kWarn;
  set_factory_client_security_state(std::move(client_security_state));

  ResourceRequest request = CreateCrossOriginResourceRequest();

  EXPECT_EQ(net::OK, LoadRequest(request));
}

TEST_F(URLLoaderTest, NonSecureLocalToLoopbackAllow) {
  auto client_security_state = NewSecurityState();
  client_security_state->ip_address_space = mojom::IPAddressSpace::kLocal;
  client_security_state->local_network_access_request_policy =
      mojom::LocalNetworkAccessRequestPolicy::kAllow;
  set_factory_client_security_state(std::move(client_security_state));

  ResourceRequest request = CreateCrossOriginResourceRequest();

  EXPECT_EQ(net::OK, LoadRequest(request));
}

TEST_F(URLLoaderTest, SecureLoopbackToLoopbackBlock) {
  auto client_security_state = NewSecurityState();
  client_security_state->is_web_secure_context = true;
  client_security_state->ip_address_space = mojom::IPAddressSpace::kLoopback;
  set_factory_client_security_state(std::move(client_security_state));

  ResourceRequest request = CreateCrossOriginResourceRequest();

  EXPECT_EQ(net::OK, LoadRequest(request));
}

TEST_F(URLLoaderTest, SecureLoopbackToLoopbackWarn) {
  auto client_security_state = NewSecurityState();
  client_security_state->is_web_secure_context = true;
  client_security_state->ip_address_space = mojom::IPAddressSpace::kLoopback;
  client_security_state->local_network_access_request_policy =
      mojom::LocalNetworkAccessRequestPolicy::kWarn;
  set_factory_client_security_state(std::move(client_security_state));

  ResourceRequest request = CreateCrossOriginResourceRequest();

  EXPECT_EQ(net::OK, LoadRequest(request));
}

TEST_F(URLLoaderTest, SecureLoopbackToLoopbackAllow) {
  auto client_security_state = NewSecurityState();
  client_security_state->is_web_secure_context = true;
  client_security_state->ip_address_space = mojom::IPAddressSpace::kLoopback;
  client_security_state->local_network_access_request_policy =
      mojom::LocalNetworkAccessRequestPolicy::kAllow;
  set_factory_client_security_state(std::move(client_security_state));

  ResourceRequest request = CreateCrossOriginResourceRequest();

  EXPECT_EQ(net::OK, LoadRequest(request));
}

TEST_F(URLLoaderTest, NonSecureLoopbackToLoopbackBlock) {
  auto client_security_state = NewSecurityState();
  client_security_state->ip_address_space = mojom::IPAddressSpace::kLoopback;
  set_factory_client_security_state(std::move(client_security_state));

  ResourceRequest request = CreateCrossOriginResourceRequest();

  EXPECT_EQ(net::OK, LoadRequest(request));
}

TEST_F(URLLoaderTest, NonSecureLoopbackToLoopbackWarn) {
  auto client_security_state = NewSecurityState();
  client_security_state->ip_address_space = mojom::IPAddressSpace::kLoopback;
  client_security_state->local_network_access_request_policy =
      mojom::LocalNetworkAccessRequestPolicy::kWarn;
  set_factory_client_security_state(std::move(client_security_state));

  ResourceRequest request = CreateCrossOriginResourceRequest();

  EXPECT_EQ(net::OK, LoadRequest(request));
}

TEST_F(URLLoaderTest, NonSecureLoopbackToLoopbackAllow) {
  auto client_security_state = NewSecurityState();
  client_security_state->ip_address_space = mojom::IPAddressSpace::kLoopback;
  client_security_state->local_network_access_request_policy =
      mojom::LocalNetworkAccessRequestPolicy::kAllow;
  set_factory_client_security_state(std::move(client_security_state));

  ResourceRequest request = CreateCrossOriginResourceRequest();

  EXPECT_EQ(net::OK, LoadRequest(request));
}

TEST_F(URLLoaderTest, AddsNetLogEntryForLocalNetworkAccessCheckSuccess) {
  auto client_security_state = NewSecurityState();
  client_security_state->ip_address_space = mojom::IPAddressSpace::kLoopback;
  set_factory_client_security_state(std::move(client_security_state));

  net::RecordingNetLogObserver net_log_observer;

  ResourceRequest request = CreateCrossOriginResourceRequest();

  std::ignore = LoadRequest(request);

  std::vector<net::NetLogEntry> entries = net_log_observer.GetEntriesWithType(
      net::NetLogEventType::LOCAL_NETWORK_ACCESS_CHECK);

  ASSERT_THAT(entries, SizeIs(1));

  const base::DictValue& params = entries[0].params;

  EXPECT_THAT(params.FindString("client_address_space"),
              Pointee(Eq("loopback")));

  EXPECT_THAT(params.FindString("resource_address_space"),
              Pointee(Eq("loopback")));

  EXPECT_THAT(params.FindString("result"),
              Pointee(Eq("allowed-no-less-public")));
}

TEST_F(URLLoaderTest, AddsNetLogEntryForLocalNetworkAccessCheckFailure) {
  auto client_security_state = NewSecurityState();
  client_security_state->ip_address_space = mojom::IPAddressSpace::kPublic;
  client_security_state->local_network_access_request_policy =
      mojom::LocalNetworkAccessRequestPolicy::kPermissionBlock;
  set_factory_client_security_state(std::move(client_security_state));

  net::RecordingNetLogObserver net_log_observer;

  ResourceRequest request = CreateCrossOriginResourceRequest();

  std::ignore = LoadRequest(request);

  std::vector<net::NetLogEntry> entries = net_log_observer.GetEntriesWithType(
      net::NetLogEventType::LOCAL_NETWORK_ACCESS_CHECK);

  ASSERT_THAT(entries, SizeIs(1));

  const base::DictValue params = std::move(entries[0].params);

  EXPECT_THAT(params.FindString("client_address_space"), Pointee(Eq("public")));

  EXPECT_THAT(params.FindString("resource_address_space"),
              Pointee(Eq("loopback")));

  EXPECT_THAT(params.FindString("result"),
              Pointee(Eq("lna-permission-required")));
}

TEST_F(URLLoaderTest, AddsNetLogEntryForLocalNetworkAccessCheckSameOrigin) {
  mojom::ClientSecurityStatePtr client_security_state = NewSecurityState();
  client_security_state->ip_address_space = mojom::IPAddressSpace::kPublic;
  client_security_state->local_network_access_request_policy =
      mojom::LocalNetworkAccessRequestPolicy::kPermissionBlock;
  set_factory_client_security_state(std::move(client_security_state));

  net::RecordingNetLogObserver net_log_observer;

  GURL url = test_server()->GetURL("/empty.html");
  ResourceRequest request = CreateResourceRequest("GET", url);
  request.request_initiator = url::Origin::Create(url);

  EXPECT_EQ(net::OK, LoadRequest(request));

  std::vector<net::NetLogEntry> entries = net_log_observer.GetEntriesWithType(
      net::NetLogEventType::LOCAL_NETWORK_ACCESS_CHECK);

  ASSERT_THAT(entries, SizeIs(1));

  const base::DictValue& params = entries[0].params;

  EXPECT_THAT(params.FindString("client_address_space"), Pointee(Eq("public")));

  EXPECT_THAT(params.FindString("resource_address_space"),
              Pointee(Eq("loopback")));

  EXPECT_THAT(params.FindString("result"),
              Pointee(Eq("allowed-potentially-trustworthy-same-origin")));
}

class TestLNAPermissionURLLoaderNetworkObserver
    : public TestURLLoaderNetworkObserver {
 public:
  explicit TestLNAPermissionURLLoaderNetworkObserver(
      mojom::LocalNetworkAccessResult result)
      : result_(result) {}
  void OnLocalNetworkAccessPermissionRequired(
      mojom::TransportType type,
      network::mojom::IPAddressSpace ip_address_space,
      OnLocalNetworkAccessPermissionRequiredCallback callback) override {
    std::move(callback).Run(result_);
  }

 private:
  const mojom::LocalNetworkAccessResult result_;
};

TEST_F(URLLoaderTest, SecurePublicToLoopbackPermissionDenied) {
  base::test::ScopedFeatureList feature_list(
      features::kLocalNetworkAccessChecks);
  auto client_security_state = NewSecurityState();
  client_security_state->ip_address_space = mojom::IPAddressSpace::kPublic;
  client_security_state->local_network_access_request_policy =
      mojom::LocalNetworkAccessRequestPolicy::kPermissionBlock;
  set_factory_client_security_state(std::move(client_security_state));

  // Simulate that the permission request was denied.
  TestLNAPermissionURLLoaderNetworkObserver observer(
      mojom::LocalNetworkAccessResult::kDenied);
  set_network_observer_for_next_request(&observer);

  net::RecordingNetLogObserver net_log_observer;

  ResourceRequest request = CreateCrossOriginResourceRequest();

  EXPECT_EQ(net::ERR_BLOCKED_BY_LOCAL_NETWORK_ACCESS_CHECKS,
            LoadRequest(request));
  EXPECT_THAT(client()->completion_status().cors_error_status,
              Optional(CorsErrorStatus(
                  mojom::CorsError::kLocalNetworkAccessPermissionDenied,
                  mojom::IPAddressSpace::kLoopback)));

  std::vector<net::NetLogEntry> entries = net_log_observer.GetEntriesWithType(
      net::NetLogEventType::LOCAL_NETWORK_ACCESS_PERMISSION_REQUESTED);
  ASSERT_THAT(entries, SizeIs(2));
  {
    const base::DictValue& params = entries[0].params;

    EXPECT_THAT(params.FindString("address_space"), Pointee(Eq("loopback")));

    EXPECT_THAT(params.FindString("transport_type"), Pointee(Eq("direct")));

    EXPECT_THAT(params.FindString("result"), Pointee(Eq("denied")));
  }

  {
    const base::DictValue& params = entries[1].params;

    EXPECT_THAT(params.FindString("address_space"), Pointee(Eq("loopback")));

    EXPECT_THAT(params.FindString("transport_type"), Pointee(Eq("direct")));

    EXPECT_THAT(params.FindString("result"), Pointee(Eq("denied")));
  }
}

TEST_F(URLLoaderTest, SecurePublicToLoopbackPermissionGranted) {
  base::test::ScopedFeatureList feature_list(
      features::kLocalNetworkAccessChecks);
  auto client_security_state = NewSecurityState();
  client_security_state->ip_address_space = mojom::IPAddressSpace::kPublic;
  client_security_state->local_network_access_request_policy =
      mojom::LocalNetworkAccessRequestPolicy::kPermissionBlock;
  set_factory_client_security_state(std::move(client_security_state));

  // Simulate that the permission request was granted.
  TestLNAPermissionURLLoaderNetworkObserver observer(
      mojom::LocalNetworkAccessResult::kGranted);
  set_network_observer_for_next_request(&observer);

  net::RecordingNetLogObserver net_log_observer;

  ResourceRequest request = CreateCrossOriginResourceRequest();

  EXPECT_EQ(net::OK, LoadRequest(request));
  EXPECT_THAT(client()->completion_status().cors_error_status,
              Optional(CorsErrorStatus(
                  mojom::CorsError::kLocalNetworkAccessPermissionDenied,
                  mojom::IPAddressSpace::kLoopback)));

  std::vector<net::NetLogEntry> entries = net_log_observer.GetEntriesWithType(
      net::NetLogEventType::LOCAL_NETWORK_ACCESS_PERMISSION_REQUESTED);
  ASSERT_THAT(entries, SizeIs(2));
  {
    const base::DictValue& params = entries[0].params;

    EXPECT_THAT(params.FindString("address_space"), Pointee(Eq("loopback")));

    EXPECT_THAT(params.FindString("transport_type"), Pointee(Eq("direct")));

    EXPECT_THAT(params.FindString("result"), Pointee(Eq("granted")));
  }

  {
    const base::DictValue& params = entries[1].params;

    EXPECT_THAT(params.FindString("address_space"), Pointee(Eq("loopback")));

    EXPECT_THAT(params.FindString("transport_type"), Pointee(Eq("direct")));

    EXPECT_THAT(params.FindString("result"), Pointee(Eq("granted")));
  }
}

TEST_F(URLLoaderTest, SecureLocalToLoopbackLNAPermissionNotRequired) {
  base::test::ScopedFeatureList feature_list;
  base::FieldTrialParams params;
  params["LocalNetworkAccessChecksWarn"] = "false";
  feature_list.InitAndEnableFeatureWithParameters(
      features::kLocalNetworkAccessChecks, params);

  auto client_security_state = NewSecurityState();
  client_security_state->ip_address_space = mojom::IPAddressSpace::kLocal;
  client_security_state->local_network_access_request_policy =
      mojom::LocalNetworkAccessRequestPolicy::kPermissionBlock;
  set_factory_client_security_state(std::move(client_security_state));

  // Simulate that the permission request was denied.
  TestLNAPermissionURLLoaderNetworkObserver observer(
      mojom::LocalNetworkAccessResult::kDenied);
  set_network_observer_for_next_request(&observer);

  ResourceRequest request = CreateCrossOriginResourceRequest();

  // Request not blocked because private -> loopback is not current an LNA
  // request.
  EXPECT_EQ(net::OK, LoadRequest(request));
}

TEST_F(URLLoaderTest, SecureLoopbackToLoopbackPermission) {
  base::test::ScopedFeatureList feature_list(
      features::kLocalNetworkAccessChecks);
  auto client_security_state = NewSecurityState();
  client_security_state->ip_address_space = mojom::IPAddressSpace::kLoopback;
  client_security_state->local_network_access_request_policy =
      mojom::LocalNetworkAccessRequestPolicy::kPermissionBlock;
  set_factory_client_security_state(std::move(client_security_state));

  ResourceRequest request = CreateCrossOriginResourceRequest();

  EXPECT_EQ(net::OK, LoadRequest(request));
}

TEST_F(URLLoaderTest, SecurePublicToLoopbackPermissionWarn) {
  auto client_security_state = NewSecurityState();
  client_security_state->ip_address_space = mojom::IPAddressSpace::kPublic;
  client_security_state->local_network_access_request_policy =
      mojom::LocalNetworkAccessRequestPolicy::kPermissionWarn;
  set_factory_client_security_state(std::move(client_security_state));

  ResourceRequest request = CreateCrossOriginResourceRequest();

  EXPECT_EQ(net::OK, LoadRequest(request));
}

TEST_F(URLLoaderTest, SecureLocalToLoopbackPermissionWarn) {
  auto client_security_state = NewSecurityState();
  client_security_state->ip_address_space = mojom::IPAddressSpace::kLocal;
  client_security_state->local_network_access_request_policy =
      mojom::LocalNetworkAccessRequestPolicy::kPermissionWarn;
  set_factory_client_security_state(std::move(client_security_state));

  ResourceRequest request = CreateCrossOriginResourceRequest();

  EXPECT_EQ(net::OK, LoadRequest(request));
}

TEST_F(URLLoaderTest, LocalNetworkAccessRequestWarning) {
  url::Origin initiator =
      url::Origin::Create(GURL("http://other-origin.test/"));

  ResourceRequest request =
      CreateResourceRequest("GET", test_server()->GetURL("/simple_page.html"));
  request.mode = mojom::RequestMode::kNoCors;
  request.request_initiator = initiator;
  request.devtools_request_id = "fake-id";

  auto client_security_state = NewSecurityState();
  client_security_state->is_web_secure_context = false;
  client_security_state->local_network_access_request_policy =
      mojom::LocalNetworkAccessRequestPolicy::kPermissionWarn;
  client_security_state->ip_address_space = mojom::IPAddressSpace::kPublic;
  set_factory_client_security_state(std::move(client_security_state));

  MockDevToolsObserver devtools_observer;
  set_devtools_observer_for_next_request(&devtools_observer);

  EXPECT_EQ(net::OK, LoadRequest(request));

  devtools_observer.WaitUntilLocalNetworkRequest();
  ASSERT_TRUE(devtools_observer.local_network_request_params());
  auto& params = *devtools_observer.local_network_request_params();
  ASSERT_TRUE(params.client_security_state);
  auto& state = params.client_security_state;
  EXPECT_EQ(state->local_network_access_request_policy,
            mojom::LocalNetworkAccessRequestPolicy::kPermissionWarn);
  EXPECT_EQ(state->is_web_secure_context, false);
  EXPECT_EQ(state->ip_address_space, mojom::IPAddressSpace::kPublic);
  EXPECT_EQ(params.resource_address_space, mojom::IPAddressSpace::kLoopback);
  EXPECT_EQ(params.devtools_request_id, "fake-id");
  EXPECT_TRUE(params.is_warning);
  EXPECT_THAT(params.url.spec(), testing::HasSubstr("simple_page.html"));
}

// Bundles together the inputs to a parameterized private network request test.
struct URLLoaderFakeTransportInfoTestParams {
  // The address space of the client.
  mojom::IPAddressSpace client_address_space;

  // The address space of the endpoint serving the request.
  mojom::IPAddressSpace endpoint_address_space;

  // The type of transport to set in `TransportInfo`.
  net::TransportType transport_type;

  // The expected request result.
  int expected_result;
};

// For clarity when debugging parameterized test failures.
std::ostream& operator<<(std::ostream& out,
                         const URLLoaderFakeTransportInfoTestParams& params) {
  return out << "{ client_address_space: " << params.client_address_space
             << ", endpoint_address_space: " << params.endpoint_address_space
             << ", transport_type: "
             << net::TransportTypeToString(params.transport_type)
             << ", expected_result: "
             << net::ErrorToString(params.expected_result) << " }";
}

mojom::IPAddressSpace ResponseAddressSpace(
    const URLLoaderFakeTransportInfoTestParams& params) {
  switch (params.transport_type) {
    case net::TransportType::kDirect:
    case net::TransportType::kCached:
      return params.endpoint_address_space;
    case net::TransportType::kProxied:
    case net::TransportType::kCachedFromProxy:
      return mojom::IPAddressSpace::kUnknown;
  }
}

class URLLoaderFakeTransportInfoTest
    : public URLLoaderTest,
      public testing::WithParamInterface<URLLoaderFakeTransportInfoTestParams> {
 protected:
  // Returns an address in the given IP address space.
  static net::IPAddress FakeAddress(mojom::IPAddressSpace space) {
    switch (space) {
      case mojom::IPAddressSpace::kUnknown:
        return net::IPAddress();
      case mojom::IPAddressSpace::kPublic:
        return net::IPAddress(42, 0, 1, 2);
      case mojom::IPAddressSpace::kLocal:
        return net::IPAddress(10, 0, 1, 2);
      case mojom::IPAddressSpace::kLoopback:
        return net::IPAddress::IPv4Localhost();
    }
  }

  // Returns an endpoint in the given IP address space.
  static net::IPEndPoint FakeEndpoint(mojom::IPAddressSpace space) {
    return net::IPEndPoint(FakeAddress(space), 80);
  }

  // Returns a transport info with an endpoint in the given IP address space.
  static net::TransportInfo FakeTransportInfo(
      const URLLoaderFakeTransportInfoTestParams& params) {
    return net::TransportInfo(
        params.transport_type, FakeEndpoint(params.endpoint_address_space),
        /*accept_ch_frame_arg=*/"",
        /*cert_is_issued_by_known_root=*/false, net::NextProto::kProtoUnknown);
  }
};

// This test verifies that requests made from insecure contexts are handled
// appropriately when they go from a less-private address space to a
// more-private address space or not. The test is parameterized by
// (client address space, server address space, expected result) tuple.
TEST_P(URLLoaderFakeTransportInfoTest, LocalNetworkRequestLoadsCorrectly) {
  // This test presumes that LNA enforcement is enabled.
  base::test::ScopedFeatureList feature_list(
      features::kLocalNetworkAccessChecks);

  const auto params = GetParam();

  auto client_security_state = NewSecurityState();
  client_security_state->ip_address_space = params.client_address_space;
  set_factory_client_security_state(std::move(client_security_state));

  const GURL url("http://fake-endpoint");

  net::URLRequestFilter::GetInstance()->AddUrlInterceptor(
      url, std::make_unique<FakeTransportInfoInterceptor>(
               FakeTransportInfo(params)));

  // Despite its name, IsError(OK) asserts that the matched value is OK.
  EXPECT_THAT(Load(url), IsError(params.expected_result));
  if (params.expected_result != net::OK) {
    if (params.expected_result !=
        net::
            ERR_CACHED_IP_ADDRESS_SPACE_BLOCKED_BY_LOCAL_NETWORK_ACCESS_POLICY) {
      // CORS error status shouldn't be set when the cache entry was blocked by
      // private network access policy because we'll retry fetching from the
      // network.
      EXPECT_THAT(client()->completion_status().cors_error_status,
                  Optional(InsecureLocalNetworkCorsErrorStatus(
                      params.endpoint_address_space)));
    }
    return;
  }

  // Check that the right address spaces are reported in `URLResponseHead`.
  ASSERT_FALSE(client()->response_head().is_null());
  EXPECT_EQ(client()->response_head()->client_address_space,
            params.client_address_space);
  EXPECT_EQ(client()->response_head()->response_address_space,
            ResponseAddressSpace(params));
}

// Test the case where a LocalNetworkAccessRequestPolicy is set on the request
// via TrustedParams, rather than on the factory. the value should still be
// respected.
TEST_F(URLLoaderTest, LocalNetworkAccessRequestPolicyOnRequest) {
  auto client_security_state = NewSecurityState();
  client_security_state->ip_address_space = mojom::IPAddressSpace::kPublic;
  client_security_state->local_network_access_request_policy =
      mojom::LocalNetworkAccessRequestPolicy::kBlock;

  ResourceRequest request = CreateCrossOriginResourceRequest();
  request.trusted_params.emplace();
  request.trusted_params->client_security_state =
      std::move(client_security_state);

  EXPECT_EQ(net::ERR_BLOCKED_BY_LOCAL_NETWORK_ACCESS_CHECKS,
            LoadRequest(request));
  EXPECT_THAT(client()->completion_status().cors_error_status,
              Optional(CorsErrorStatus(mojom::CorsError::kInsecureLocalNetwork,
                                       mojom::IPAddressSpace::kLoopback)));
}

// Test the case where a LocalNetworkAccessRequestPolicy is set on the request
// via TrustedParams, and on the URLLoaderFactory via URLLoaderFactoryParams.
// The value set on the request should be preferred.
TEST_F(URLLoaderTest, LocalNetworkAccessRequestPolicyOnRequestAndFactory) {
  auto client_security_state = NewSecurityState();
  // The value set on the factory should not block the request. `kAllow` will
  // actually DCHECK(), so this test may DCHECK instead on regression, instead
  // of LoadRequest() succeeding.
  client_security_state->local_network_access_request_policy =
      mojom::LocalNetworkAccessRequestPolicy::kAllow;
  set_factory_client_security_state(client_security_state->Clone());

  // The value set on the request should block the request.
  client_security_state->ip_address_space = mojom::IPAddressSpace::kPublic;
  client_security_state->local_network_access_request_policy =
      mojom::LocalNetworkAccessRequestPolicy::kBlock;

  ResourceRequest request = CreateCrossOriginResourceRequest();
  request.trusted_params.emplace();
  request.trusted_params->client_security_state =
      std::move(client_security_state);

  // The request should be blocked, based on the per-request value, rather than
  // the factory value.
  EXPECT_EQ(net::ERR_BLOCKED_BY_LOCAL_NETWORK_ACCESS_CHECKS,
            LoadRequest(request));
  EXPECT_THAT(client()->completion_status().cors_error_status,
              Optional(CorsErrorStatus(mojom::CorsError::kInsecureLocalNetwork,
                                       mojom::IPAddressSpace::kLoopback)));
}

// Lists all combinations we want to test in URLLoaderFakeTransportInfoTest.
constexpr URLLoaderFakeTransportInfoTestParams
    kURLLoaderFakeTransportInfoTestParamsList[] = {
        // Client: kUnknown
        {
            mojom::IPAddressSpace::kUnknown,
            mojom::IPAddressSpace::kUnknown,
            net::TransportType::kDirect,
            net::OK,
        },
        {
            mojom::IPAddressSpace::kUnknown,
            mojom::IPAddressSpace::kPublic,
            net::TransportType::kDirect,
            net::OK,
        },
        {
            mojom::IPAddressSpace::kUnknown,
            mojom::IPAddressSpace::kLocal,
            net::TransportType::kDirect,
            net::ERR_BLOCKED_BY_LOCAL_NETWORK_ACCESS_CHECKS,
        },
        {
            mojom::IPAddressSpace::kUnknown,
            mojom::IPAddressSpace::kLoopback,
            net::TransportType::kDirect,
            net::ERR_BLOCKED_BY_LOCAL_NETWORK_ACCESS_CHECKS,
        },
        // Client: kPublic
        {
            mojom::IPAddressSpace::kPublic,
            mojom::IPAddressSpace::kUnknown,
            net::TransportType::kDirect,
            net::OK,
        },
        {
            mojom::IPAddressSpace::kPublic,
            mojom::IPAddressSpace::kPublic,
            net::TransportType::kDirect,
            net::OK,
        },
        {
            mojom::IPAddressSpace::kPublic,
            mojom::IPAddressSpace::kLocal,
            net::TransportType::kDirect,
            net::ERR_BLOCKED_BY_LOCAL_NETWORK_ACCESS_CHECKS,
        },
        {
            mojom::IPAddressSpace::kPublic,
            mojom::IPAddressSpace::kLoopback,
            net::TransportType::kDirect,
            net::ERR_BLOCKED_BY_LOCAL_NETWORK_ACCESS_CHECKS,
        },
        // Client: kLocal
        {
            mojom::IPAddressSpace::kLocal,
            mojom::IPAddressSpace::kUnknown,
            net::TransportType::kDirect,
            net::OK,
        },
        {
            mojom::IPAddressSpace::kLocal,
            mojom::IPAddressSpace::kPublic,
            net::TransportType::kDirect,
            net::OK,
        },
        {
            mojom::IPAddressSpace::kLocal,
            mojom::IPAddressSpace::kLocal,
            net::TransportType::kDirect,
            net::OK,
        },
        {
            mojom::IPAddressSpace::kLocal,
            mojom::IPAddressSpace::kLoopback,
            net::TransportType::kDirect,
            // Local and Loopback are currently merged and LNA checks are not
            // enforced.
            net::OK,
        },
        // Client: kLoopback
        {
            mojom::IPAddressSpace::kLoopback,
            mojom::IPAddressSpace::kUnknown,
            net::TransportType::kDirect,
            net::OK,
        },
        {
            mojom::IPAddressSpace::kLoopback,
            mojom::IPAddressSpace::kPublic,
            net::TransportType::kDirect,
            net::OK,
        },
        {
            mojom::IPAddressSpace::kLoopback,
            mojom::IPAddressSpace::kLocal,
            net::TransportType::kDirect,
            net::OK,
        },
        {
            mojom::IPAddressSpace::kLoopback,
            mojom::IPAddressSpace::kLoopback,
            net::TransportType::kDirect,
            net::OK,
        },
        // TransportType: kProxied
        {
            mojom::IPAddressSpace::kUnknown,
            mojom::IPAddressSpace::kLoopback,
            net::TransportType::kProxied,
            net::OK,
        },
        {
            mojom::IPAddressSpace::kPublic,
            mojom::IPAddressSpace::kLoopback,
            net::TransportType::kProxied,
            net::OK,
        },
        {
            mojom::IPAddressSpace::kPublic,
            mojom::IPAddressSpace::kLocal,
            net::TransportType::kProxied,
            net::OK,
        },
        {
            mojom::IPAddressSpace::kLocal,
            mojom::IPAddressSpace::kLoopback,
            net::TransportType::kProxied,
            net::OK,
        },
        // TransportType: kCachedFromProxy
        {
            mojom::IPAddressSpace::kUnknown,
            mojom::IPAddressSpace::kLoopback,
            net::TransportType::kCachedFromProxy,
            net::OK,
        },
        {
            mojom::IPAddressSpace::kPublic,
            mojom::IPAddressSpace::kLoopback,
            net::TransportType::kCachedFromProxy,
            net::OK,
        },
        {
            mojom::IPAddressSpace::kPublic,
            mojom::IPAddressSpace::kLocal,
            net::TransportType::kCachedFromProxy,
            net::OK,
        },
        {
            mojom::IPAddressSpace::kLocal,
            mojom::IPAddressSpace::kLoopback,
            net::TransportType::kCachedFromProxy,
            net::OK,
        },
        // TransportType: kCached. We only test a loopback target for brevity.
        {
            mojom::IPAddressSpace::kUnknown,
            mojom::IPAddressSpace::kLoopback,
            net::TransportType::kCached,
            net::
                ERR_CACHED_IP_ADDRESS_SPACE_BLOCKED_BY_LOCAL_NETWORK_ACCESS_POLICY,
        },
        {
            mojom::IPAddressSpace::kPublic,
            mojom::IPAddressSpace::kLoopback,
            net::TransportType::kCached,
            net::
                ERR_CACHED_IP_ADDRESS_SPACE_BLOCKED_BY_LOCAL_NETWORK_ACCESS_POLICY,
        },
        {
            mojom::IPAddressSpace::kLocal,
            mojom::IPAddressSpace::kLoopback,
            net::TransportType::kCached,
            // Local and Loopback are currently merged and LNA checks are not
            // enforced.
            net::OK,
        },
        {
            mojom::IPAddressSpace::kLoopback,
            mojom::IPAddressSpace::kLoopback,
            net::TransportType::kCached,
            net::OK,
        },
};

INSTANTIATE_TEST_SUITE_P(Parameterized,
                         URLLoaderFakeTransportInfoTest,
                         ValuesIn(kURLLoaderFakeTransportInfoTestParamsList));

// Tests that auth challenge info is present on the response when a request
// receives an authentication challenge.
TEST_F(URLLoaderTest, AuthChallengeInfo) {
  GURL url = test_server()->GetURL("/auth-basic");
  EXPECT_EQ(net::OK, Load(url));
  ASSERT_TRUE(client()->response_head()->auth_challenge_info.has_value());
  EXPECT_FALSE(client()->response_head()->auth_challenge_info->is_proxy);
  EXPECT_EQ(url::SchemeHostPort(url),
            client()->response_head()->auth_challenge_info->challenger);
  EXPECT_EQ("basic", client()->response_head()->auth_challenge_info->scheme);
  EXPECT_EQ("testrealm", client()->response_head()->auth_challenge_info->realm);
  EXPECT_EQ("Basic realm=\"testrealm\"",
            client()->response_head()->auth_challenge_info->challenge);
  EXPECT_EQ("/auth-basic",
            client()->response_head()->auth_challenge_info->path);
}

// Tests that no auth challenge info is present on the response when a request
// does not receive an authentication challenge.
TEST_F(URLLoaderTest, NoAuthChallengeInfo) {
  GURL url = test_server()->GetURL("/");
  EXPECT_EQ(net::OK, Load(url));
  EXPECT_FALSE(client()->response_head()->auth_challenge_info.has_value());
}

// Test decoded_body_length / encoded_body_length when they're different.
TEST_F(URLLoaderTest, GzipTest) {
  std::string body;
  EXPECT_EQ(net::OK, Load(test_server()->GetURL("/gzip-body?Body"), &body));
  EXPECT_EQ("Body", body);
  // Deflating a 4-byte string should result in a longer string - main thing to
  // check here, though, is that the two lengths are of different.
  EXPECT_LT(client()->completion_status().decoded_body_length,
            client()->completion_status().encoded_body_length);
  // Over the wire length should include headers, so should be longer.
  EXPECT_LT(client()->completion_status().encoded_body_length,
            client()->completion_status().encoded_data_length);
}

TEST_F(URLLoaderTest, ErrorBeforeHeaders) {
  EXPECT_EQ(net::ERR_EMPTY_RESPONSE,
            Load(test_server()->GetURL("/close-socket"), nullptr));
  EXPECT_FALSE(client()->response_body().is_valid());
}

TEST_F(URLLoaderTest, SyncErrorWhileReadingBody) {
  std::string body;
  EXPECT_EQ(net::ERR_FAILED,
            Load(net::URLRequestFailedJob::GetMockHttpUrlWithFailurePhase(
                     net::URLRequestFailedJob::READ_SYNC, net::ERR_FAILED),
                 &body));
  EXPECT_EQ("", body);
}

TEST_F(URLLoaderTest, AsyncErrorWhileReadingBody) {
  std::string body;
  EXPECT_EQ(net::ERR_FAILED,
            Load(net::URLRequestFailedJob::GetMockHttpUrlWithFailurePhase(
                     net::URLRequestFailedJob::READ_ASYNC, net::ERR_FAILED),
                 &body));
  EXPECT_EQ("", body);
}

TEST_F(URLLoaderTest, SyncErrorWhileReadingBodyAfterBytesReceived) {
  const std::string kBody("Foo.");

  std::list<std::string> packets;
  packets.push_back(kBody);
  AddMultipleWritesInterceptor(packets, net::ERR_ACCESS_DENIED,
                               false /*async_reads*/);
  std::string body;
  EXPECT_EQ(net::ERR_ACCESS_DENIED,
            Load(MultipleWritesInterceptor::GetURL(), &body));
  EXPECT_EQ(kBody, body);
}

TEST_F(URLLoaderTest, AsyncErrorWhileReadingBodyAfterBytesReceived) {
  const std::string kBody("Foo.");

  std::list<std::string> packets;
  packets.push_back(kBody);
  AddMultipleWritesInterceptor(packets, net::ERR_ACCESS_DENIED,
                               true /*async_reads*/);
  std::string body;
  EXPECT_EQ(net::ERR_ACCESS_DENIED,
            Load(MultipleWritesInterceptor::GetURL(), &body));
  EXPECT_EQ(kBody, body);
}

TEST_F(URLLoaderTest, DoNotSniffUnlessSpecified) {
  EXPECT_EQ(net::OK,
            Load(test_server()->GetURL("/content-sniffer-test0.html")));
  EXPECT_FALSE(did_mime_sniff());
  ASSERT_TRUE(mime_type().empty());
}

TEST_F(URLLoaderTest, SniffMimeType) {
  set_sniff();
  EXPECT_EQ(net::OK,
            Load(test_server()->GetURL("/content-sniffer-test0.html")));
  EXPECT_TRUE(did_mime_sniff());
  ASSERT_EQ(std::string("text/html"), mime_type());
}

TEST_F(URLLoaderTest, RespectNoSniff) {
  set_sniff();
  EXPECT_EQ(net::OK, Load(test_server()->GetURL("/nosniff-test.html")));
  EXPECT_FALSE(did_mime_sniff());
  ASSERT_EQ(std::string("text/plain"), mime_type());
}

TEST_F(URLLoaderTest, SniffTextPlainDoesNotResultInHTML) {
  set_sniff();
  EXPECT_EQ(net::OK,
            Load(test_server()->GetURL("/content-sniffer-test1.html")));
  EXPECT_TRUE(did_mime_sniff());
  ASSERT_EQ(std::string("text/plain"), mime_type());
}

TEST_F(URLLoaderTest, DoNotSniffHTMLFromImageGIF) {
  set_sniff();
  EXPECT_EQ(net::OK,
            Load(test_server()->GetURL("/content-sniffer-test2.html")));
  EXPECT_FALSE(did_mime_sniff());
  ASSERT_EQ(std::string("image/gif"), mime_type());
}

TEST_F(URLLoaderTest, EmptyHtmlIsTextPlain) {
  set_sniff();
  EXPECT_EQ(net::OK,
            Load(test_server()->GetURL("/content-sniffer-test4.html")));
  EXPECT_TRUE(did_mime_sniff());
  ASSERT_EQ(std::string("text/plain"), mime_type());
}

TEST_F(URLLoaderTest, EmptyHtmlIsTextPlainWithAsyncResponse) {
  set_sniff();

  const std::string kBody;

  std::list<std::string> packets;
  packets.push_back(kBody);
  AddMultipleWritesInterceptor(packets, net::OK, true /*async_reads*/);

  std::string body;
  EXPECT_EQ(net::OK, Load(MultipleWritesInterceptor::GetURL(), &body));
  EXPECT_EQ(kBody, body);
  EXPECT_TRUE(did_mime_sniff());
  ASSERT_EQ(std::string("text/plain"), mime_type());
}

// Tests the case where the first read doesn't have enough data to figure out
// the right mime type. The second read would have enough data even though the
// total bytes is still smaller than net::kMaxBytesToSniff.
TEST_F(URLLoaderTest, FirstReadNotEnoughToSniff1) {
  set_sniff();
  std::string first(500, 'a');
  std::string second(std::string(100, 'b'));
  second[10] = 0;
  EXPECT_LE(first.size() + second.size(),
            static_cast<uint32_t>(net::kMaxBytesToSniff));
  LoadPacketsAndVerifyContents(first, second);
  EXPECT_TRUE(did_mime_sniff());
  ASSERT_EQ(std::string("application/octet-stream"), mime_type());
}

// Like above, except that the total byte count is > kMaxBytesToSniff.
TEST_F(URLLoaderTest, FirstReadNotEnoughToSniff2) {
  set_sniff();
  std::string first(500, 'a');
  std::string second(std::string(1000, 'b'));
  second[10] = 0;
  EXPECT_GE(first.size() + second.size(),
            static_cast<uint32_t>(net::kMaxBytesToSniff));
  LoadPacketsAndVerifyContents(first, second);
  EXPECT_TRUE(did_mime_sniff());
  ASSERT_EQ(std::string("application/octet-stream"), mime_type());
}

// Tests that even if the first and only read is smaller than the minimum number
// of bytes needed to sniff, the loader works correctly and returns the data.
TEST_F(URLLoaderTest, LoneReadNotEnoughToSniff) {
  set_sniff();
  std::string first(net::kMaxBytesToSniff - 100, 'a');
  LoadPacketsAndVerifyContents(first, std::string());
  EXPECT_TRUE(did_mime_sniff());
  ASSERT_EQ(std::string("text/plain"), mime_type());
}

// Tests the simple case where the first read is enough to sniff.
TEST_F(URLLoaderTest, FirstReadIsEnoughToSniff) {
  set_sniff();
  std::string first(net::kMaxBytesToSniff + 100, 'a');
  LoadPacketsAndVerifyContents(first, std::string());
  EXPECT_TRUE(did_mime_sniff());
  ASSERT_EQ(std::string("text/plain"), mime_type());
}

TEST_F(URLLoaderTest, CompressedResponse) {
  std::string body;
  EXPECT_EQ(net::OK, Load(test_server()->GetURL("/hello.html.gz"), &body));
  ASSERT_EQ(std::string("text/html"), mime_type());
  EXPECT_EQ(body, ReadTestFile("hello.html"));
}

TEST_F(URLLoaderTest, CompressedResponseClienteSideDecoding) {
  set_client_side_content_decoding_enabled();
  std::string body;
  EXPECT_EQ(net::OK, Load(test_server()->GetURL("/hello.html.gz"), &body));
  ASSERT_EQ(std::string("text/html"), mime_type());
  EXPECT_EQ(body, ReadTestFile("hello.html.gz"));
  EXPECT_THAT(client()->response_head()->client_side_content_decoding_types,
              ElementsAre(net::SourceStreamType::kGzip));
}

TEST_F(URLLoaderTest, CompressedResponseSniffMime) {
  set_sniff();
  std::string body;
  EXPECT_EQ(
      net::OK,
      Load(test_server()->GetURL("/content-sniffer-test0.html.gz"), &body));
  EXPECT_TRUE(did_mime_sniff());
  ASSERT_EQ(std::string("text/html"), mime_type());
  EXPECT_EQ(body,
            base::as_string_view(ReadTestFile("content-sniffer-test0.html")));
}

TEST_F(URLLoaderTest, CompressedResponseSniffMimeClienteSideDecoding) {
  set_sniff();
  set_client_side_content_decoding_enabled();
  std::string body;
  EXPECT_EQ(
      net::OK,
      Load(test_server()->GetURL("/content-sniffer-test0.html.gz"), &body));
  EXPECT_TRUE(did_mime_sniff());
  ASSERT_EQ(std::string("text/html"), mime_type());
  EXPECT_THAT(client()->response_head()->client_side_content_decoding_types,
              ElementsAre(net::SourceStreamType::kGzip));
  EXPECT_EQ(body, ReadTestFile("content-sniffer-test0.html.gz"));
}

// Tests that URLLoader writes into given DurableMessage object when configured.
TEST_F(URLLoaderTest, WritesToDurableMessage) {
  MockDurableMessageAccountingDelegate accounting_delegate;
  DevtoolsDurableMessage durable_message("test", accounting_delegate);
  set_durable_messages({durable_message.GetWeakPtr()});
  std::string body;

  EXPECT_EQ(net::OK, Load(test_server()->GetURL("/hello.html.gz"), &body));
  EXPECT_EQ(body, ReadTestFile("hello.html"));
  EXPECT_TRUE(durable_message.is_complete());
  ASSERT_EQ(accounting_delegate.size(), static_cast<int64_t>(body.size()));
  ASSERT_EQ(durable_message.size(), body.size());
  // Retrieve the stored body and verify that it is accurate.
  EXPECT_EQ(durable_message.Retrieve(), base::as_byte_span(body));
}

TEST_F(URLLoaderTest, DurableMessageWorksWithMimeSniffing) {
  MockDurableMessageAccountingDelegate accounting_delegate;
  DevtoolsDurableMessage durable_message("test", accounting_delegate);
  set_durable_messages({durable_message.GetWeakPtr()});

  set_sniff();
  set_client_side_content_decoding_enabled();
  std::string encoded_body;
  EXPECT_EQ(net::OK,
            Load(test_server()->GetURL("/content-sniffer-test0.html.gz"),
                 &encoded_body));
  EXPECT_THAT(client()->response_head()->client_side_content_decoding_types,
              ElementsAre(net::SourceStreamType::kGzip));
  EXPECT_TRUE(did_mime_sniff());
  EXPECT_THAT(durable_message.get_client_decoding_types_for_testing(),
              ElementsAre(net::SourceStreamType::kGzip));
  EXPECT_EQ(encoded_body, ReadTestFile("content-sniffer-test0.html.gz"));
  EXPECT_TRUE(durable_message.is_complete());
  ASSERT_EQ(accounting_delegate.size(),
            static_cast<int64_t>(encoded_body.size()));
  ASSERT_EQ(durable_message.size(), encoded_body.size());
  // Retrieve the stored body and verify that it is accurate and contents are in
  // decoded form.
  mojo_base::BigBuffer buffer = durable_message.Retrieve();
  auto decoded_body = ReadTestFile("content-sniffer-test0.html");
  EXPECT_EQ(buffer.size(), decoded_body.size());
  EXPECT_EQ(buffer, base::as_byte_span(decoded_body));
}

// Tests a large response body, which would result in multiple asynchronous
// chunks being written into the configured durable message.
TEST_F(URLLoaderMockSocketTest, DurableMessageWorksWithLotsOfData) {
  std::string response_body;
  constexpr int kReadSize = 1024;
  response_body.reserve(5 * kReadSize * kReadSize);
  // Using a repeating patter with a length that's prime is more likely to spot
  // out of order or repeated chunks of data.
  while (response_body.size() < 5 * kReadSize * kReadSize) {
    response_body.append("foppity");
  }
  const auto compressed = net::CompressGzip(response_body);
  int seq = 1;
  std::vector<net::MockRead> reads;
  reads.emplace_back(net::ASYNC, /*seq=*/seq++,
                     "HTTP/1.1 200 OK\r\n"
                     "Content-Encoding: gzip\r\n\r\n");
  for (size_t i = 0; i < compressed.size(); i += kReadSize) {
    reads.emplace_back(net::ASYNC,
                       base::as_string_view(compressed).substr(i, kReadSize),
                       /*result=*/0, /*seq=*/seq++);
  }
  reads.emplace_back(net::ASYNC, net::OK, /*seq=*/seq);
  net::SequencedSocketData socket_data_connect(kAsyncMockConnect, {}, {});
  net::SequencedSocketData socket_data_reads_writes(reads, kOriginTestWrites);
  socket_data_reads_writes.set_receive_buffer_size(1);
  socket_factory_.AddSocketDataProvider(&socket_data_connect);
  socket_factory_.AddSocketDataProvider(&socket_data_reads_writes);
  ResourceRequest request =
      CreateResourceRequest("GET", GURL("http://origin.test/"));

  MockDurableMessageAccountingDelegate accounting_delegate;
  DevtoolsDurableMessage durable_message("test", accounting_delegate);
  set_durable_messages({durable_message.GetWeakPtr()});
  set_sniff();
  // Set the flag for ClientSideContentDecoding.
  request.client_side_content_decoding_enabled = true;

  std::string body;
  EXPECT_EQ(net::OK, LoadRequest(request, &body));
  EXPECT_TRUE(did_mime_sniff());
  EXPECT_EQ(mime_type(), "text/plain");
  EXPECT_THAT(body, base::as_string_view(compressed));
  EXPECT_THAT(client()->response_head()->client_side_content_decoding_types,
              ElementsAre(net::SourceStreamType::kGzip));
  EXPECT_TRUE(durable_message.is_complete());
  size_t compressed_size = compressed.size();
  ASSERT_EQ(accounting_delegate.size(), static_cast<int64_t>(compressed_size));
  ASSERT_EQ(durable_message.size(), compressed_size);
  EXPECT_EQ(durable_message.Retrieve(), base::as_byte_span(response_body));
}

// Tests that client side decoding types are written into DurableMessage and the
// body is decoded on retrieval.
TEST_F(URLLoaderTest, DurableMessagePerformsClientSideDecodingGzip) {
  MockDurableMessageAccountingDelegate accounting_delegate;
  DevtoolsDurableMessage durable_message("test", accounting_delegate);
  set_durable_messages({durable_message.GetWeakPtr()});

  set_sniff();
  set_client_side_content_decoding_enabled();
  std::string encoded_body;
  EXPECT_EQ(net::OK,
            Load(test_server()->GetURL("/hello.html.gz"), &encoded_body));
  EXPECT_THAT(client()->response_head()->client_side_content_decoding_types,
              ElementsAre(net::SourceStreamType::kGzip));
  EXPECT_THAT(durable_message.get_client_decoding_types_for_testing(),
              ElementsAre(net::SourceStreamType::kGzip));
  EXPECT_TRUE(durable_message.is_complete());
  ASSERT_EQ(accounting_delegate.size(),
            static_cast<int64_t>(encoded_body.size()));
  // Retrieve the stored body and verify that it is accurate and contents are in
  // decoded form.
  mojo_base::BigBuffer buffer = durable_message.Retrieve();
  auto decoded_body = ReadTestFile("hello.html");
  EXPECT_EQ(buffer.size(), decoded_body.size());
  EXPECT_EQ(buffer, base::as_byte_span(decoded_body));
}

// Tests that URLLoader still completes the load without errors/crashing, but
// does not write into the DurableMessage object when the original message has
// been evicted.
TEST_F(URLLoaderTest, DoesNotWriteToDurableMessageWithEvictedMessage) {
  MockDurableMessageAccountingDelegate accounting_delegate;
  std::unique_ptr<DevtoolsDurableMessage> durable_message =
      std::make_unique<DevtoolsDurableMessage>("test", accounting_delegate);
  set_durable_messages({durable_message->GetWeakPtr()});

  // Simulate eviction of the durable message.
  durable_message.reset();

  std::string body;
  EXPECT_EQ(net::OK, Load(test_server()->GetURL("/hello.html.gz"), &body));
  EXPECT_EQ(body, ReadTestFile("hello.html"));
  ASSERT_EQ(accounting_delegate.size(), 0);
}

// Tests Durable Message incomplete read scenarios.

TEST_F(URLLoaderTest, ErrorBeforeHeadersWritesIncompleteDurableMessage) {
  MockDurableMessageAccountingDelegate accounting_delegate;
  DevtoolsDurableMessage durable_message("test", accounting_delegate);
  set_durable_messages({durable_message.GetWeakPtr()});
  EXPECT_EQ(net::ERR_EMPTY_RESPONSE,
            Load(test_server()->GetURL("/close-socket"), nullptr));
  EXPECT_FALSE(client()->response_body().is_valid());
  EXPECT_FALSE(durable_message.is_complete());
  ASSERT_EQ(accounting_delegate.size(), 0);
}

TEST_F(URLLoaderTest, SyncErrorWhileReadingBodyWritesDurableMessage) {
  MockDurableMessageAccountingDelegate accounting_delegate;
  DevtoolsDurableMessage durable_message("test", accounting_delegate);
  set_durable_messages({durable_message.GetWeakPtr()});
  std::string body;
  EXPECT_EQ(net::ERR_FAILED,
            Load(net::URLRequestFailedJob::GetMockHttpUrlWithFailurePhase(
                     net::URLRequestFailedJob::READ_SYNC, net::ERR_FAILED),
                 &body));
  EXPECT_EQ("", body);
  EXPECT_TRUE(durable_message.is_complete());
  ASSERT_EQ(accounting_delegate.size(), 0);
}

TEST_F(URLLoaderTest, AsyncErrorWhileReadingBodyWritesDurableMessage) {
  MockDurableMessageAccountingDelegate accounting_delegate;
  DevtoolsDurableMessage durable_message("test", accounting_delegate);
  set_durable_messages({durable_message.GetWeakPtr()});
  std::string body;
  EXPECT_EQ(net::ERR_FAILED,
            Load(net::URLRequestFailedJob::GetMockHttpUrlWithFailurePhase(
                     net::URLRequestFailedJob::READ_ASYNC, net::ERR_FAILED),
                 &body));
  EXPECT_EQ("", body);
  EXPECT_TRUE(durable_message.is_complete());
  ASSERT_EQ(accounting_delegate.size(), 0);
}

TEST_F(URLLoaderTest,
       SyncErrorWhileReadingBodyAfterBytesReceivedWritesDurableMessage) {
  MockDurableMessageAccountingDelegate accounting_delegate;
  DevtoolsDurableMessage durable_message("test", accounting_delegate);
  set_durable_messages({durable_message.GetWeakPtr()});

  const std::string response_body("Foo.");
  std::list<std::string> packets = {response_body};
  AddMultipleWritesInterceptor(packets, net::ERR_ACCESS_DENIED,
                               false /*async_reads*/);
  std::string body_readback;
  EXPECT_EQ(net::ERR_ACCESS_DENIED,
            Load(MultipleWritesInterceptor::GetURL(), &body_readback));
  EXPECT_EQ(response_body, body_readback);
  EXPECT_TRUE(durable_message.is_complete());
  ASSERT_GT(accounting_delegate.size(), 0);
}

TEST_F(
    URLLoaderTest,
    AsyncErrorWhileReadingBodyAfterBytesReceivedWritesIncompleteDurableMessage) {
  MockDurableMessageAccountingDelegate accounting_delegate;
  DevtoolsDurableMessage durable_message("test", accounting_delegate);
  set_durable_messages({durable_message.GetWeakPtr()});
  const std::string kBody("Foo.");

  std::list<std::string> packets;
  packets.push_back(kBody);
  AddMultipleWritesInterceptor(packets, net::ERR_ACCESS_DENIED,
                               true /*async_reads*/);
  std::string body;
  EXPECT_EQ(net::ERR_ACCESS_DENIED,
            Load(MultipleWritesInterceptor::GetURL(), &body));
  EXPECT_EQ(kBody, body);
  EXPECT_TRUE(durable_message.is_complete());
  ASSERT_GT(accounting_delegate.size(), 0);
}

class NeverFinishedBodyHttpResponse : public net::test_server::HttpResponse {
 public:
  NeverFinishedBodyHttpResponse() = default;
  ~NeverFinishedBodyHttpResponse() override = default;

 private:
  // net::test_server::HttpResponse implementation.
  void SendResponse(
      base::WeakPtr<net::test_server::HttpResponseDelegate> delegate) override {
    delegate->SendResponseHeaders(net::HTTP_OK, "OK",
                                  {{"Content-Type", "text/plain"}});
    delegate->SendContents(
        "long long ago..." +
        std::string(static_cast<uint64_t>(1024 * 1024), 'a'));

    // Never call |done|, so the other side will never see the completion of the
    // response body.
  }
};

// Check that the URLLoader tears itself down when the URLLoader pipe is closed.
TEST_F(URLLoaderTest, DestroyOnURLLoaderPipeClosed) {
  net::EmbeddedTestServer server;
  server.RegisterRequestHandler(
      base::BindRepeating([](const net::test_server::HttpRequest& request) {
        std::unique_ptr<net::test_server::HttpResponse> response =
            std::make_unique<NeverFinishedBodyHttpResponse>();
        return response;
      }));
  ASSERT_TRUE(server.Start());

  ResourceRequest request =
      CreateResourceRequest("GET", server.GetURL("/hello.html"));

  base::RunLoop delete_run_loop;
  mojo::PendingRemote<mojom::URLLoader> loader;
  std::unique_ptr<URLLoader> url_loader;
  context().mutable_factory_params().process_id =
      OriginatingProcessId::browser();
  context().mutable_factory_params().is_orb_enabled = false;
  url_loader = URLLoaderOptions().MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.InitWithNewPipeAndPassReceiver(), request,
      client()->CreateRemote());

  // Run until the response body pipe arrives, to make sure that a live body
  // pipe does not result in keeping the loader alive when the URLLoader pipe is
  // closed.
  client()->RunUntilResponseBodyArrived();
  EXPECT_TRUE(client()->has_received_response());
  EXPECT_FALSE(client()->has_received_completion());

  loader.reset();

  // Spin the message loop until the delete callback is invoked, and then delete
  // the URLLoader.
  delete_run_loop.Run();

  // client()->RunUntilConnectionError();
  // EXPECT_FALSE(client()->has_received_completion());
  client()->RunUntilComplete();
  EXPECT_EQ(net::ERR_FAILED, client()->completion_status().error_code);
}

// Make sure that the URLLoader is destroyed when the data pipe is closed.
// The pipe may either be closed in
// URLLoader::OnResponseBodyStreamConsumerClosed() or URLLoader::DidRead(),
// depending on whether the closed pipe is first noticed when trying to write to
// it, or when a mojo close notification is received, so if only one path
// breaks, this test may flakily fail.
TEST_F(URLLoaderTest, CloseResponseBodyConsumerBeforeProducer) {
  net::EmbeddedTestServer server;
  server.RegisterRequestHandler(
      base::BindRepeating([](const net::test_server::HttpRequest& request) {
        std::unique_ptr<net::test_server::HttpResponse> response =
            std::make_unique<NeverFinishedBodyHttpResponse>();
        return response;
      }));
  ASSERT_TRUE(server.Start());

  ResourceRequest request =
      CreateResourceRequest("GET", server.GetURL("/hello.html"));

  base::RunLoop delete_run_loop;
  mojo::PendingRemote<mojom::URLLoader> loader;
  std::unique_ptr<URLLoader> url_loader;
  context().mutable_factory_params().process_id =
      OriginatingProcessId::browser();
  context().mutable_factory_params().is_orb_enabled = false;
  url_loader = URLLoaderOptions().MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.InitWithNewPipeAndPassReceiver(), request,
      client()->CreateRemote());

  client()->RunUntilResponseBodyArrived();
  EXPECT_TRUE(client()->has_received_response());
  EXPECT_FALSE(client()->has_received_completion());

  // Wait for a little amount of time for the response body pipe to be filled.
  // (Please note that this doesn't guarantee that the pipe is filled to the
  // point that it is not writable anymore.)
  base::RunLoop run_loop;
  base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
      FROM_HERE, run_loop.QuitClosure(), base::Milliseconds(100));
  run_loop.Run();

  auto response_body = client()->response_body_release();
  response_body.reset();

  // Spin the message loop until the delete callback is invoked, and then delete
  // the URLLoader.
  delete_run_loop.Run();

  client()->RunUntilComplete();
  EXPECT_EQ(net::ERR_FAILED, client()->completion_status().error_code);
}

TEST_F(URLLoaderTest, UploadBytes) {
  const std::string kRequestBody = "Request Body";

  scoped_refptr<ResourceRequestBody> request_body(new ResourceRequestBody());
  request_body->AppendCopyOfBytes(base::as_byte_span(kRequestBody));
  set_request_body(std::move(request_body));

  std::string response_body;
  EXPECT_EQ(net::OK, Load(test_server()->GetURL("/echo"), &response_body));
  EXPECT_EQ(kRequestBody, response_body);
}

TEST_F(URLLoaderTest, UploadFile) {
  allow_file_uploads();
  base::FilePath file_path = GetTestFilePath("simple_page.html");

  std::string expected_body;
  ASSERT_TRUE(base::ReadFileToString(file_path, &expected_body))
      << "File not found: " << file_path.value();

  scoped_refptr<ResourceRequestBody> request_body(new ResourceRequestBody());
  request_body->AppendFileRange(
      file_path, 0, std::numeric_limits<uint64_t>::max(), base::Time());
  set_request_body(std::move(request_body));

  std::string response_body;
  EXPECT_EQ(net::OK, Load(test_server()->GetURL("/echo"), &response_body));
  EXPECT_EQ(expected_body, response_body);
}

TEST_F(URLLoaderTest, UploadFileWithRange) {
  allow_file_uploads();
  base::FilePath file_path = GetTestFilePath("simple_page.html");

  std::string expected_body;
  ASSERT_TRUE(base::ReadFileToString(file_path, &expected_body))
      << "File not found: " << file_path.value();
  expected_body = expected_body.substr(1, expected_body.size() - 2);

  scoped_refptr<ResourceRequestBody> request_body(new ResourceRequestBody());
  request_body->AppendFileRange(file_path, 1, expected_body.size(),
                                base::Time());
  set_request_body(std::move(request_body));

  std::string response_body;
  EXPECT_EQ(net::OK, Load(test_server()->GetURL("/echo"), &response_body));
  EXPECT_EQ(expected_body, response_body);
}

TEST_F(URLLoaderTest, UploadTwoFiles) {
  allow_file_uploads();
  base::FilePath file_path1 = GetTestFilePath("simple_page.html");
  base::FilePath file_path2 = GetTestFilePath("hello.html");

  std::string expected_body1;
  std::string expected_body2;
  ASSERT_TRUE(base::ReadFileToString(file_path1, &expected_body1))
      << "File not found: " << file_path1.value();
  ASSERT_TRUE(base::ReadFileToString(file_path2, &expected_body2))
      << "File not found: " << file_path2.value();

  scoped_refptr<ResourceRequestBody> request_body(new ResourceRequestBody());
  request_body->AppendFileRange(
      file_path1, 0, std::numeric_limits<uint64_t>::max(), base::Time());
  request_body->AppendFileRange(
      file_path2, 0, std::numeric_limits<uint64_t>::max(), base::Time());
  set_request_body(std::move(request_body));

  std::string response_body;
  EXPECT_EQ(net::OK, Load(test_server()->GetURL("/echo"), &response_body));
  EXPECT_EQ(expected_body1 + expected_body2, response_body);
}

TEST_F(URLLoaderTest, UploadTwoBatchesOfFiles) {
  allow_file_uploads();
  base::FilePath file_path = GetTestFilePath("simple_page.html");

  std::string expected_body;
  size_t num_files = 2 * FileOpenerForUpload::kMaxFileUploadRequestsPerBatch;
  for (size_t i = 0; i < num_files; ++i) {
    std::string tmp_expected_body;
    ASSERT_TRUE(base::ReadFileToString(file_path, &tmp_expected_body))
        << "File not found: " << file_path.value();
    expected_body += tmp_expected_body;
  }

  scoped_refptr<ResourceRequestBody> request_body(new ResourceRequestBody());
  for (size_t i = 0; i < num_files; ++i) {
    request_body->AppendFileRange(
        file_path, 0, std::numeric_limits<uint64_t>::max(), base::Time());
  }
  set_request_body(std::move(request_body));

  std::string response_body;
  EXPECT_EQ(net::OK, Load(test_server()->GetURL("/echo"), &response_body));
  EXPECT_EQ(expected_body, response_body);
}

TEST_F(URLLoaderTest, UploadTwoBatchesOfFilesWithRespondInvalidFile) {
  allow_file_uploads();
  set_upload_files_invalid(true);
  base::FilePath file_path = GetTestFilePath("simple_page.html");

  scoped_refptr<ResourceRequestBody> request_body(new ResourceRequestBody());
  size_t num_files = 2 * FileOpenerForUpload::kMaxFileUploadRequestsPerBatch;
  for (size_t i = 0; i < num_files; ++i) {
    request_body->AppendFileRange(
        file_path, 0, std::numeric_limits<uint64_t>::max(), base::Time());
  }
  set_request_body(std::move(request_body));

  EXPECT_EQ(net::ERR_ACCESS_DENIED, Load(test_server()->GetURL("/echo")));
}

TEST_F(URLLoaderTest, UploadTwoBatchesOfFilesWithRespondDifferentNumOfFiles) {
  allow_file_uploads();
  set_ignore_last_upload_file(true);
  base::FilePath file_path = GetTestFilePath("simple_page.html");

  scoped_refptr<ResourceRequestBody> request_body(new ResourceRequestBody());
  size_t num_files = 2 * FileOpenerForUpload::kMaxFileUploadRequestsPerBatch;
  for (size_t i = 0; i < num_files; ++i) {
    request_body->AppendFileRange(
        file_path, 0, std::numeric_limits<uint64_t>::max(), base::Time());
  }
  set_request_body(std::move(request_body));

  EXPECT_EQ(net::ERR_FAILED, Load(test_server()->GetURL("/echo")));
}

TEST_F(URLLoaderTest, UploadInvalidFile) {
  allow_file_uploads();
  set_upload_files_invalid(true);
  base::FilePath file_path = GetTestFilePath("simple_page.html");

  scoped_refptr<ResourceRequestBody> request_body(new ResourceRequestBody());
  request_body->AppendFileRange(
      file_path, 0, std::numeric_limits<uint64_t>::max(), base::Time());
  set_request_body(std::move(request_body));

  EXPECT_EQ(net::ERR_ACCESS_DENIED, Load(test_server()->GetURL("/echo")));
}

TEST_F(URLLoaderTest, UploadFileWithoutNetworkServiceClient) {
  // Don't call allow_file_uploads();
  base::FilePath file_path = GetTestFilePath("simple_page.html");

  scoped_refptr<ResourceRequestBody> request_body(new ResourceRequestBody());
  request_body->AppendFileRange(
      file_path, 0, std::numeric_limits<uint64_t>::max(), base::Time());
  set_request_body(std::move(request_body));

  EXPECT_EQ(net::ERR_ACCESS_DENIED, Load(test_server()->GetURL("/echo")));
}

class CallbackSavingNetworkContextClient : public TestNetworkContextClient {
 public:
  void OnFileUploadRequested(const OriginatingProcessId& process_id,
                             bool async,
                             const std::vector<base::FilePath>& file_paths,
                             const GURL& destination_url,
                             OnFileUploadRequestedCallback callback) override {
    file_upload_requested_callback_ = std::move(callback);
    if (quit_closure_for_on_file_upload_requested_) {
      std::move(quit_closure_for_on_file_upload_requested_).Run();
    }
  }

  void RunUntilUploadRequested(OnFileUploadRequestedCallback* callback) {
    if (!file_upload_requested_callback_) {
      base::RunLoop run_loop;
      quit_closure_for_on_file_upload_requested_ = run_loop.QuitClosure();
      run_loop.Run();
    }
    *callback = std::move(file_upload_requested_callback_);
  }

 private:
  base::OnceClosure quit_closure_for_on_file_upload_requested_;
  OnFileUploadRequestedCallback file_upload_requested_callback_;
};

TEST_F(URLLoaderTest, UploadFileCanceled) {
  base::FilePath file_path = GetTestFilePath("simple_page.html");
  std::vector<base::File> opened_file;
  opened_file.emplace_back(file_path, base::File::FLAG_OPEN |
                                          base::File::FLAG_READ |
                                          base::File::FLAG_ASYNC);
  ASSERT_TRUE(opened_file.back().IsValid());

  ResourceRequest request =
      CreateResourceRequest("POST", test_server()->GetURL("/echo"));
  request.request_body = new ResourceRequestBody();
  request.request_body->AppendFileRange(
      file_path, 0, std::numeric_limits<uint64_t>::max(), base::Time());

  base::RunLoop delete_run_loop;
  mojo::Remote<mojom::URLLoader> loader;
  context().mutable_factory_params().process_id =
      OriginatingProcessId::browser();
  context().mutable_factory_params().is_orb_enabled = false;
  auto network_context_client =
      std::make_unique<CallbackSavingNetworkContextClient>();
  context().set_network_context_client(network_context_client.get());
  std::unique_ptr<URLLoader> url_loader = URLLoaderOptions().MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.BindNewPipeAndPassReceiver(), request, client()->CreateRemote());

  mojom::NetworkContextClient::OnFileUploadRequestedCallback callback;
  network_context_client->RunUntilUploadRequested(&callback);

  // Check we can call the callback from a deleted URLLoader without crashing.
  url_loader.reset();
  base::RunLoop().RunUntilIdle();
  std::move(callback).Run(net::OK, std::move(opened_file));
  base::RunLoop().RunUntilIdle();
  context().set_network_context_client(nullptr);
}

// Tests a request body with a data pipe element.
TEST_F(URLLoaderTest, UploadDataPipe) {
  const std::string kRequestBody = "Request Body";

  mojo::PendingRemote<mojom::DataPipeGetter> data_pipe_getter_remote;
  auto data_pipe_getter = std::make_unique<TestDataPipeGetter>(
      kRequestBody, data_pipe_getter_remote.InitWithNewPipeAndPassReceiver());

  auto resource_request_body = base::MakeRefCounted<ResourceRequestBody>();
  resource_request_body->AppendDataPipe(std::move(data_pipe_getter_remote));
  set_request_body(std::move(resource_request_body));

  std::string response_body;
  EXPECT_EQ(net::OK, Load(test_server()->GetURL("/echo"), &response_body));
  EXPECT_EQ(kRequestBody, response_body);
}

// Same as above and tests that the body is sent after a 307 redirect.
TEST_F(URLLoaderTest, UploadDataPipe_Redirect307) {
  const std::string kRequestBody = "Request Body";

  mojo::PendingRemote<mojom::DataPipeGetter> data_pipe_getter_remote;
  auto data_pipe_getter = std::make_unique<TestDataPipeGetter>(
      kRequestBody, data_pipe_getter_remote.InitWithNewPipeAndPassReceiver());

  auto resource_request_body = base::MakeRefCounted<ResourceRequestBody>();
  resource_request_body->AppendDataPipe(std::move(data_pipe_getter_remote));
  set_request_body(std::move(resource_request_body));
  set_expect_redirect();

  std::string response_body;
  EXPECT_EQ(net::OK, Load(test_server()->GetURL("/redirect307-to-echo"),
                          &response_body));
  EXPECT_EQ(kRequestBody, response_body);
}

// Tests a large request body, which should result in multiple asynchronous
// reads.
TEST_F(URLLoaderTest, UploadDataPipeWithLotsOfData) {
  std::string request_body;
  request_body.reserve(5 * 1024 * 1024);
  // Using a repeating patter with a length that's prime is more likely to spot
  // out of order or repeated chunks of data.
  while (request_body.size() < 5 * 1024 * 1024) {
    request_body.append("foppity");
  }

  mojo::PendingRemote<mojom::DataPipeGetter> data_pipe_getter_remote;
  auto data_pipe_getter = std::make_unique<TestDataPipeGetter>(
      request_body, data_pipe_getter_remote.InitWithNewPipeAndPassReceiver());

  auto resource_request_body = base::MakeRefCounted<ResourceRequestBody>();
  resource_request_body->AppendDataPipe(std::move(data_pipe_getter_remote));
  set_request_body(std::move(resource_request_body));

  std::string response_body;
  EXPECT_EQ(net::OK, Load(test_server()->GetURL("/echo"), &response_body));
  EXPECT_EQ(request_body, response_body);
}

TEST_F(URLLoaderTest, UploadDataPipeError) {
  const std::string kRequestBody = "Request Body";

  mojo::PendingRemote<mojom::DataPipeGetter> data_pipe_getter_remote;
  auto data_pipe_getter = std::make_unique<TestDataPipeGetter>(
      kRequestBody, data_pipe_getter_remote.InitWithNewPipeAndPassReceiver());
  data_pipe_getter->set_start_error(net::ERR_ACCESS_DENIED);

  auto resource_request_body = base::MakeRefCounted<ResourceRequestBody>();
  resource_request_body->AppendDataPipe(std::move(data_pipe_getter_remote));
  set_request_body(std::move(resource_request_body));

  EXPECT_EQ(net::ERR_ACCESS_DENIED, Load(test_server()->GetURL("/echo")));
}

TEST_F(URLLoaderTest, UploadDataPipeClosedEarly) {
  const std::string kRequestBody = "Request Body";

  mojo::PendingRemote<mojom::DataPipeGetter> data_pipe_getter_remote;
  auto data_pipe_getter = std::make_unique<TestDataPipeGetter>(
      kRequestBody, data_pipe_getter_remote.InitWithNewPipeAndPassReceiver());
  data_pipe_getter->set_pipe_closed_early(true);

  auto resource_request_body = base::MakeRefCounted<ResourceRequestBody>();
  resource_request_body->AppendDataPipe(std::move(data_pipe_getter_remote));
  set_request_body(std::move(resource_request_body));

  std::string response_body;
  EXPECT_EQ(net::ERR_FAILED, Load(test_server()->GetURL("/echo")));
}

// Tests a request body with a chunked data pipe element.
TEST_F(URLLoaderTest, UploadChunkedDataPipe) {
  const std::string kRequestBody = "Request Body";

  TestChunkedDataPipeGetter data_pipe_getter;

  ResourceRequest request =
      CreateResourceRequest("POST", test_server()->GetURL("/echo"));
  request.request_body = base::MakeRefCounted<ResourceRequestBody>();
  request.request_body->SetAllowHTTP1ForStreamingUpload(true);
  request.request_body->SetToChunkedDataPipe(
      data_pipe_getter.GetDataPipeGetterRemote(),
      ResourceRequestBody::ReadOnlyOnce(false));

  base::RunLoop delete_run_loop;
  mojo::Remote<mojom::URLLoader> loader;
  std::unique_ptr<URLLoader> url_loader;
  context().mutable_factory_params().process_id =
      OriginatingProcessId::browser();
  context().mutable_factory_params().is_orb_enabled = false;
  url_loader = URLLoaderOptions().MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.BindNewPipeAndPassReceiver(), request, client()->CreateRemote());

  mojom::ChunkedDataPipeGetter::GetSizeCallback get_size_callback =
      data_pipe_getter.WaitForGetSize();
  mojo::BlockingCopyFromString(kRequestBody,
                               data_pipe_getter.WaitForStartReading());
  std::move(get_size_callback).Run(net::OK, kRequestBody.size());
  delete_run_loop.Run();
  client()->RunUntilComplete();

  EXPECT_EQ(kRequestBody, ReadBody());
  EXPECT_EQ(net::OK, client()->completion_status().error_code);
}

TEST_F(URLLoaderTest, UploadChunkedDataPipeOverHTTP2) {
  const std::string kRequestBody = "Request Body";

  TestChunkedDataPipeGetter data_pipe_getter;

  ResourceRequest request = CreateResourceRequest(
      "POST", net::QuicSimpleTestServer::GetFileURL("/echo"));
  request.request_body = base::MakeRefCounted<ResourceRequestBody>();
  request.request_body->SetToChunkedDataPipe(
      data_pipe_getter.GetDataPipeGetterRemote(),
      ResourceRequestBody::ReadOnlyOnce(false));

  base::RunLoop delete_run_loop;
  mojo::Remote<mojom::URLLoader> loader;
  std::unique_ptr<URLLoader> url_loader;
  context().mutable_factory_params().process_id =
      OriginatingProcessId::browser();
  context().mutable_factory_params().is_orb_enabled = false;
  url_loader = URLLoaderOptions().MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.BindNewPipeAndPassReceiver(), request, client()->CreateRemote());

  mojom::ChunkedDataPipeGetter::GetSizeCallback get_size_callback =
      data_pipe_getter.WaitForGetSize();
  mojo::BlockingCopyFromString(kRequestBody,
                               data_pipe_getter.WaitForStartReading());
  std::move(get_size_callback).Run(net::OK, kRequestBody.size());
  delete_run_loop.Run();
  client()->RunUntilComplete();

  EXPECT_EQ(kRequestBody, ReadBody());
  EXPECT_EQ(net::OK, client()->completion_status().error_code);
}

TEST_F(URLLoaderTest, UploadChunkedDataPipeNotAllowHTTP1) {
  const std::string kRequestBody = "Request Body";

  TestChunkedDataPipeGetter data_pipe_getter;

  auto resource_request_body = base::MakeRefCounted<ResourceRequestBody>();
  resource_request_body->SetToChunkedDataPipe(
      data_pipe_getter.GetDataPipeGetterRemote(),
      ResourceRequestBody::ReadOnlyOnce(false));
  set_request_body(std::move(resource_request_body));

  EXPECT_EQ(net::ERR_ALPN_NEGOTIATION_FAILED,
            Load(test_server()->GetURL("/echo")));
}

// Tests a request body with ReadOnceStream.
TEST_F(URLLoaderTest, UploadChunkedDataPipeReadOnceStream) {
  const std::string kRequestBody = "Request Body";

  TestChunkedDataPipeGetter data_pipe_getter;

  ResourceRequest request =
      CreateResourceRequest("POST", test_server()->GetURL("/echo"));
  request.request_body = base::MakeRefCounted<ResourceRequestBody>();
  request.request_body->SetAllowHTTP1ForStreamingUpload(true);
  request.request_body->SetToChunkedDataPipe(
      data_pipe_getter.GetDataPipeGetterRemote(),
      ResourceRequestBody::ReadOnlyOnce(true));

  base::RunLoop delete_run_loop;
  mojo::Remote<mojom::URLLoader> loader;
  std::unique_ptr<URLLoader> url_loader;
  context().mutable_factory_params().process_id =
      OriginatingProcessId::browser();
  context().mutable_factory_params().is_orb_enabled = false;
  url_loader = URLLoaderOptions().MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.BindNewPipeAndPassReceiver(), request, client()->CreateRemote());

  mojom::ChunkedDataPipeGetter::GetSizeCallback get_size_callback =
      data_pipe_getter.WaitForGetSize();
  mojo::BlockingCopyFromString(kRequestBody,
                               data_pipe_getter.WaitForStartReading());
  std::move(get_size_callback).Run(net::OK, kRequestBody.size());
  delete_run_loop.Run();
  client()->RunUntilComplete();

  EXPECT_EQ(kRequestBody, ReadBody());
  EXPECT_EQ(net::OK, client()->completion_status().error_code);
}

// Tests that SSLInfo is not attached to OnComplete messages or the
// URLResponseHead when there is no certificate error.
TEST_F(URLLoaderTest, NoSSLInfoWithoutCertificateError) {
  net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
  ASSERT_TRUE(https_server.Start());
  set_send_ssl_for_cert_error();
  EXPECT_EQ(net::OK, Load(https_server.GetURL("/")));
  EXPECT_FALSE(client()->completion_status().ssl_info.has_value());
  EXPECT_FALSE(client()->response_head()->ssl_info.has_value());
}

// Tests that SSLInfo is not attached to OnComplete messages when the
// corresponding option is not set.
TEST_F(URLLoaderTest, NoSSLInfoOnComplete) {
  net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
  https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_EXPIRED);
  ASSERT_TRUE(https_server.Start());
  EXPECT_EQ(net::ERR_CERT_DATE_INVALID, Load(https_server.GetURL("/")));
  EXPECT_FALSE(client()->completion_status().ssl_info.has_value());
}

// Tests that SSLInfo is attached to OnComplete messages when the corresponding
// option is set and the certificate error causes the load to fail.
TEST_F(URLLoaderTest, SSLInfoOnComplete) {
  net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
  https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_EXPIRED);
  ASSERT_TRUE(https_server.Start());
  set_send_ssl_for_cert_error();
  EXPECT_EQ(net::ERR_CERT_DATE_INVALID, Load(https_server.GetURL("/")));
  ASSERT_TRUE(client()->completion_status().ssl_info.has_value());
  EXPECT_TRUE(client()->completion_status().ssl_info.value().cert);
  EXPECT_EQ(net::CERT_STATUS_DATE_INVALID,
            client()->completion_status().ssl_info.value().cert_status);
}

// Tests that SSLInfo is attached to OnComplete messages and the URLResponseHead
// when the corresponding option is set and the certificate error doesn't cause
// the load to fail.
TEST_F(URLLoaderTest, SSLInfoOnResponseWithCertificateError) {
  net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
  https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_EXPIRED);
  ASSERT_TRUE(https_server.Start());
  set_send_ssl_for_cert_error();

  TestURLLoaderNetworkObserver observer;
  observer.set_ignore_certificate_errors(true);
  set_network_observer_for_next_request(&observer);

  EXPECT_EQ(net::OK, Load(https_server.GetURL("/")));
  ASSERT_TRUE(client()->completion_status().ssl_info.has_value());
  EXPECT_TRUE(client()->completion_status().ssl_info.value().cert);
  EXPECT_EQ(net::CERT_STATUS_DATE_INVALID,
            client()->completion_status().ssl_info.value().cert_status);
  ASSERT_TRUE(client()->response_head()->ssl_info.has_value());
  EXPECT_TRUE(client()->response_head()->ssl_info.value().cert);
  EXPECT_EQ(net::CERT_STATUS_DATE_INVALID,
            client()->response_head()->ssl_info.value().cert_status);
}

// Tests that SSLInfo is attached to the URLResponseHead on redirects when the
// corresponding option is set and the certificate error doesn't cause the load
// to fail.
TEST_F(URLLoaderTest, SSLInfoOnRedirectWithCertificateError) {
  net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
  https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_EXPIRED);
  https_server.AddDefaultHandlers(
      base::FilePath(FILE_PATH_LITERAL("services/test/data")));
  ASSERT_TRUE(https_server.Start());

  TestURLLoaderClient client;
  ResourceRequest request = CreateResourceRequest(
      "GET", https_server.GetURL("/server-redirect?http://foo.test"));

  base::RunLoop delete_run_loop;
  mojo::Remote<mojom::URLLoader> loader;
  context().mutable_factory_params().process_id =
      OriginatingProcessId::browser();
  context().mutable_factory_params().is_orb_enabled = false;
  auto network_context_client = std::make_unique<TestNetworkContextClient>();
  context().set_network_context_client(network_context_client.get());
  TestURLLoaderNetworkObserver url_loader_network_observer;
  url_loader_network_observer.set_ignore_certificate_errors(true);
  URLLoaderOptions url_loader_options;
  url_loader_options.options =
      mojom::kURLLoadOptionSendSSLInfoWithResponse |
      mojom::kURLLoadOptionSendSSLInfoForCertificateError;
  url_loader_options.url_loader_network_observer =
      url_loader_network_observer.Bind();
  std::unique_ptr<URLLoader> url_loader = url_loader_options.MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.BindNewPipeAndPassReceiver(), request, client.CreateRemote());

  client.RunUntilRedirectReceived();
  ASSERT_TRUE(client.response_head()->ssl_info.has_value());
  EXPECT_TRUE(client.response_head()->ssl_info.value().cert);
  EXPECT_EQ(net::CERT_STATUS_DATE_INVALID,
            client.response_head()->ssl_info.value().cert_status);
  context().set_network_context_client(nullptr);
}

// Make sure the client can modify headers during a redirect.
TEST_F(URLLoaderTest, RedirectModifiedHeaders) {
  ResourceRequest request = CreateResourceRequest(
      "GET", test_server()->GetURL("/redirect307-to-echo"));
  request.headers.SetHeader("Header1", "Value1");
  request.headers.SetHeader("Header2", "Value2");

  base::RunLoop delete_run_loop;
  mojo::Remote<mojom::URLLoader> loader;
  std::unique_ptr<URLLoader> url_loader;
  context().mutable_factory_params().process_id =
      OriginatingProcessId::browser();
  context().mutable_factory_params().is_orb_enabled = false;
  url_loader = URLLoaderOptions().MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.BindNewPipeAndPassReceiver(), request, client()->CreateRemote());

  client()->RunUntilRedirectReceived();

  // Initial request should only have initial headers.
  const auto& request_headers1 = sent_request().headers;
  EXPECT_EQ("Value1", request_headers1.find("Header1")->second);
  EXPECT_EQ("Value2", request_headers1.find("Header2")->second);
  EXPECT_EQ(request_headers1.end(), request_headers1.find("Header3"));

  // Overwrite Header2 and add Header3.
  network::HttpRequestHeadersUpdateParams headers_update_params;
  headers_update_params.modified_headers.SetHeader("Header2", "");
  headers_update_params.modified_headers.SetHeader("Header3", "Value3");
  loader->FollowRedirect(std::move(headers_update_params), std::nullopt);

  client()->RunUntilComplete();
  delete_run_loop.Run();

  // Redirected request should also have modified headers.
  const auto& request_headers2 = sent_request().headers;
  EXPECT_EQ("Value1", request_headers2.find("Header1")->second);
  EXPECT_EQ("", request_headers2.find("Header2")->second);
  EXPECT_EQ("Value3", request_headers2.find("Header3")->second);
}

TEST_F(URLLoaderTest, RedirectFailsOnModifyUnsafeHeader) {
  const char* kUnsafeHeaders[] = {
      net::HttpRequestHeaders::kContentLength,
      net::HttpRequestHeaders::kHost,
      net::HttpRequestHeaders::kProxyConnection,
      net::HttpRequestHeaders::kProxyAuthorization,
      "Proxy-Foo",
  };

  for (const auto* unsafe_header : kUnsafeHeaders) {
    TestURLLoaderClient client;
    ResourceRequest request = CreateResourceRequest(
        "GET", test_server()->GetURL("/redirect307-to-echo"));

    base::RunLoop delete_run_loop;
    mojo::Remote<mojom::URLLoader> loader;
    std::unique_ptr<URLLoader> url_loader;
    context().mutable_factory_params().process_id =
        OriginatingProcessId::browser();
    context().mutable_factory_params().is_orb_enabled = false;
    url_loader = URLLoaderOptions().MakeURLLoader(
        context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
        loader.BindNewPipeAndPassReceiver(), request, client.CreateRemote());

    client.RunUntilRedirectReceived();

    network::HttpRequestHeadersUpdateParams headers_update_params;
    headers_update_params.modified_headers.SetHeader(unsafe_header, "foo");
    loader->FollowRedirect(std::move(headers_update_params), std::nullopt);

    client.RunUntilComplete();
    delete_run_loop.Run();

    EXPECT_TRUE(client.has_received_completion());
    EXPECT_EQ(net::ERR_INVALID_ARGUMENT, client.completion_status().error_code);
  }
}

// Test the client can remove headers during a redirect.
TEST_F(URLLoaderTest, RedirectRemoveHeader) {
  ResourceRequest request = CreateResourceRequest(
      "GET", test_server()->GetURL("/redirect307-to-echo"));
  request.headers.SetHeader("Header1", "Value1");
  request.headers.SetHeader("Header2", "Value2");

  base::RunLoop delete_run_loop;
  mojo::Remote<mojom::URLLoader> loader;
  std::unique_ptr<URLLoader> url_loader;
  context().mutable_factory_params().process_id =
      OriginatingProcessId::browser();
  context().mutable_factory_params().is_orb_enabled = false;
  url_loader = URLLoaderOptions().MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.BindNewPipeAndPassReceiver(), request, client()->CreateRemote());

  client()->RunUntilRedirectReceived();

  // Initial request should only have initial headers.
  const auto& request_headers1 = sent_request().headers;
  EXPECT_EQ("Value1", request_headers1.find("Header1")->second);
  EXPECT_EQ("Value2", request_headers1.find("Header2")->second);

  // Remove Header1.
  network::HttpRequestHeadersUpdateParams headers_update_params;
  headers_update_params.removed_headers = {"Header1"};
  loader->FollowRedirect(std::move(headers_update_params), std::nullopt);

  client()->RunUntilComplete();
  delete_run_loop.Run();

  // Redirected request should have the updated headers.
  const auto& request_headers2 = sent_request().headers;
  EXPECT_EQ(request_headers2.end(), request_headers2.find("Header1"));
  EXPECT_EQ("Value2", request_headers2.find("Header2")->second);
}

// Test the client can remove headers and add headers back during a redirect.
TEST_F(URLLoaderTest, RedirectRemoveHeaderAndAddItBack) {
  ResourceRequest request = CreateResourceRequest(
      "GET", test_server()->GetURL("/redirect307-to-echo"));
  request.headers.SetHeader("Header1", "Value1");
  request.headers.SetHeader("Header2", "Value2");

  base::RunLoop delete_run_loop;
  mojo::Remote<mojom::URLLoader> loader;
  std::unique_ptr<URLLoader> url_loader;
  context().mutable_factory_params().process_id =
      OriginatingProcessId::browser();
  context().mutable_factory_params().is_orb_enabled = false;
  url_loader = URLLoaderOptions().MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.BindNewPipeAndPassReceiver(), request, client()->CreateRemote());

  client()->RunUntilRedirectReceived();

  // Initial request should only have initial headers.
  const auto& request_headers1 = sent_request().headers;
  EXPECT_EQ("Value1", request_headers1.find("Header1")->second);
  EXPECT_EQ("Value2", request_headers1.find("Header2")->second);

  // Remove Header1 and add it back using a different value.
  network::HttpRequestHeadersUpdateParams headers_update_params;
  headers_update_params.removed_headers = {"Header1"};
  headers_update_params.modified_headers.SetHeader("Header1", "NewValue1");
  loader->FollowRedirect(std::move(headers_update_params), std::nullopt);

  client()->RunUntilComplete();
  delete_run_loop.Run();

  // Redirected request should have the updated headers.
  const auto& request_headers2 = sent_request().headers;
  EXPECT_EQ("NewValue1", request_headers2.find("Header1")->second);
  EXPECT_EQ("Value2", request_headers2.find("Header2")->second);
}

// Validate Sec- prefixed headers are handled properly when redirecting from
// insecure => secure urls. The Sec-Fetch-Site header should be re-added on the
// secure url.
TEST_F(URLLoaderTest, UpgradeAddsSecHeaders) {
  // Set up a redirect to signal we will go from insecure => secure.
  GURL url = test_server()->GetURL(
      kInsecureHost,
      "/server-redirect?" + test_server()->GetURL("/echo").spec());
  ResourceRequest request = CreateResourceRequest("GET", url);

  base::RunLoop delete_run_loop;
  mojo::Remote<mojom::URLLoader> loader;
  std::unique_ptr<URLLoader> url_loader;
  context().mutable_factory_params().process_id =
      OriginatingProcessId::browser();
  url_loader = URLLoaderOptions().MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.BindNewPipeAndPassReceiver(), request, client()->CreateRemote());

  client()->RunUntilRedirectReceived();

  // The initial request is received when the redirect before it has been
  // followed. It should have no added Sec- headers as it is not trustworthy.
  const auto& request_headers1 = sent_request().headers;
  EXPECT_EQ(request_headers1.end(), request_headers1.find("Sec-Fetch-Site"));
  EXPECT_EQ(request_headers1.end(), request_headers1.find("Sec-Fetch-User"));

  // Now follow the redirect to the final destination and validate again.
  loader->FollowRedirect(/*headers_update_params=*/{},
                         /*new_url=*/std::nullopt);
  client()->RunUntilComplete();
  delete_run_loop.Run();

  // The Sec-Fetch-Site header should have been added again since we are now on
  // a trustworthy url again.
  const auto& request_headers2 = sent_request().headers;
  EXPECT_EQ("cross-site", request_headers2.find("Sec-Fetch-Site")->second);
  EXPECT_EQ(request_headers2.end(), request_headers2.find("Sec-Fetch-User"));
}

// Validate Sec- prefixed headers are properly handled when redirecting from
// secure => insecure urls. All Sec-CH- and Sec-Fetch- prefixed
// headers should be removed.
TEST_F(URLLoaderTest, DowngradeRemovesSecHeaders) {
  // Set up a redirect to signal we will go from secure => insecure.
  GURL url = test_server()->GetURL(
      "/server-redirect?" +
      test_server()->GetURL(kInsecureHost, "/echo").spec());

  // Add some initial headers to ensure the right ones are removed and
  // everything else is left alone.
  ResourceRequest request = CreateResourceRequest("GET", url);
  request.headers.SetHeader("Sec-CH-UA", "Value1");
  request.headers.SetHeader("Sec-Other-Type", "Value2");
  request.headers.SetHeader("Other-Header", "Value3");

  base::RunLoop delete_run_loop;
  mojo::Remote<mojom::URLLoader> loader;
  std::unique_ptr<URLLoader> url_loader;
  context().mutable_factory_params().process_id =
      OriginatingProcessId::browser();
  url_loader = URLLoaderOptions().MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.BindNewPipeAndPassReceiver(), request, client()->CreateRemote());

  client()->RunUntilRedirectReceived();

  // The initial request is received when the redirect before it has been
  // followed. It should have all the Sec- headers as it is trustworthy. It
  // should also have added a Sec-Fetch-Site header
  const auto& request_headers1 = sent_request().headers;
  EXPECT_EQ("Value1", request_headers1.find("Sec-CH-UA")->second);
  EXPECT_EQ("Value2", request_headers1.find("Sec-Other-Type")->second);
  EXPECT_EQ("Value3", request_headers1.find("Other-Header")->second);
  EXPECT_EQ("same-origin", request_headers1.find("Sec-Fetch-Site")->second);
  EXPECT_EQ(request_headers1.end(), request_headers1.find("Sec-Fetch-User"));

  // Now follow the redirect to the final destination and validate again.
  loader->FollowRedirect(/*headers_update_params=*/{},
                         /*new_url=*/std::nullopt);
  client()->RunUntilComplete();
  delete_run_loop.Run();

  // We should have removed our special Sec-CH- and Sec-Fetch- prefixed headers
  // and left the others. We are now operating on an un-trustworthy context.
  const auto& request_headers2 = sent_request().headers;
  EXPECT_EQ(request_headers2.end(), request_headers2.find("Sec-CH-UA"));
  EXPECT_EQ("Value2", request_headers2.find("Sec-Other-Type")->second);
  EXPECT_EQ("Value3", request_headers2.find("Other-Header")->second);
  EXPECT_EQ(request_headers2.end(), request_headers2.find("Sec-Fetch-Site"));
  EXPECT_EQ(request_headers2.end(), request_headers2.find("Sec-Fetch-User"));
}

// Validate Sec- prefixed headers are properly handled when redirecting from
// secure => insecure => secure urls.The headers on insecure
// urls should be removed and Sec-Fetch-Site should be re-added on secure ones.
TEST_F(URLLoaderTest, RedirectChainRemovesAndAddsSecHeaders) {
  // Set up a redirect to signal we will go from secure => insecure => secure.
  GURL insecure_upgrade_url = test_server()->GetURL(
      kInsecureHost,
      "/server-redirect?" + test_server()->GetURL("/echo").spec());
  GURL url =
      test_server()->GetURL("/server-redirect?" + insecure_upgrade_url.spec());

  // Add some initial headers to ensure the right ones are removed and
  // everything else is left alone.
  ResourceRequest request = CreateResourceRequest("GET", url);
  request.headers.SetHeader("Sec-CH-UA", "Value1");
  request.headers.SetHeader("Sec-Other-Type", "Value2");
  request.headers.SetHeader("Other-Header", "Value3");

  base::RunLoop delete_run_loop;
  mojo::Remote<mojom::URLLoader> loader;
  std::unique_ptr<URLLoader> url_loader;
  context().mutable_factory_params().process_id =
      OriginatingProcessId::browser();
  url_loader = URLLoaderOptions().MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.BindNewPipeAndPassReceiver(), request, client()->CreateRemote());

  client()->RunUntilRedirectReceived();

  // The initial request is received when the redirect before it has been
  // followed. It should have all the Sec- headers as it is trustworthy. It
  // should also have added a Sec-Fetch-Site header
  const auto& request_headers1 = sent_request().headers;
  EXPECT_EQ("Value1", request_headers1.find("Sec-CH-UA")->second);
  EXPECT_EQ("Value2", request_headers1.find("Sec-Other-Type")->second);
  EXPECT_EQ("Value3", request_headers1.find("Other-Header")->second);
  EXPECT_EQ("same-origin", request_headers1.find("Sec-Fetch-Site")->second);
  EXPECT_EQ(request_headers1.end(), request_headers1.find("Sec-Fetch-User"));

  // Follow our redirect and then verify again.
  loader->FollowRedirect(/*headers_update_params=*/{},
                         /*new_url=*/std::nullopt);
  client()->ClearHasReceivedRedirect();
  client()->RunUntilRedirectReceived();

  // Special Sec-CH- and Sec-Fetch- prefixed headers should have been removed
  // and the others left alone. We are now operating on an un-trustworthy
  // context.
  const auto& request_headers2 = sent_request().headers;
  EXPECT_EQ(request_headers2.end(), request_headers2.find("Sec-CH-UA"));
  EXPECT_EQ("Value2", request_headers2.find("Sec-Other-Type")->second);
  EXPECT_EQ("Value3", request_headers2.find("Other-Header")->second);
  EXPECT_EQ(request_headers2.end(), request_headers2.find("Sec-Fetch-Site"));
  EXPECT_EQ(request_headers2.end(), request_headers2.find("Sec-Fetch-User"));

  // Now follow the final redirect back to a trustworthy destination and
  // re-validate.
  loader->FollowRedirect(/*headers_update_params=*/{},
                         /*new_url=*/std::nullopt);
  client()->RunUntilComplete();
  delete_run_loop.Run();

  const auto& request_headers3 = sent_request().headers;
  EXPECT_EQ(request_headers3.end(), request_headers3.find("Sec-CH-UA"));
  EXPECT_EQ("Value2", request_headers3.find("Sec-Other-Type")->second);
  EXPECT_EQ("Value3", request_headers3.find("Other-Header")->second);
  EXPECT_EQ("cross-site", request_headers3.find("Sec-Fetch-Site")->second);
  EXPECT_EQ(request_headers3.end(), request_headers3.find("Sec-Fetch-User"));
}

// Validate Sec-Fetch-User header is properly handled.
TEST_F(URLLoaderTest, RedirectSecHeadersUser) {
  GURL url = test_server()->GetURL("/server-redirect?" +
                                   test_server()->GetURL("/echo").spec());

  // Add some initial headers to ensure the right ones are removed and
  // everything else is left alone.
  ResourceRequest request = CreateResourceRequest("GET", url);
  request.trusted_params->has_user_activation = true;

  base::RunLoop delete_run_loop;
  mojo::PendingRemote<mojom::URLLoader> loader;
  std::unique_ptr<URLLoader> url_loader;
  context().mutable_factory_params().process_id =
      OriginatingProcessId::browser();
  url_loader = URLLoaderOptions().MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.InitWithNewPipeAndPassReceiver(), request,
      client()->CreateRemote());

  client()->RunUntilRedirectReceived();

  const auto& request_headers = sent_request().headers;
  EXPECT_EQ("same-origin", request_headers.find("Sec-Fetch-Site")->second);
  EXPECT_EQ("?1", request_headers.find("Sec-Fetch-User")->second);
}

// Validate Sec-Fetch-User header cannot be modified by manually set the value.
TEST_F(URLLoaderTest, RedirectDirectlyModifiedSecHeadersUser) {
  GURL url = test_server()->GetURL("/server-redirect?" +
                                   test_server()->GetURL("/echo").spec());

  // Try to modify `Sec-Fetch-User` directly.
  ResourceRequest request = CreateResourceRequest("GET", url);
  request.headers.SetHeader("Sec-Fetch-User", "?1");
  request.headers.SetHeader("Sec-Fetch-Dest", "embed");

  base::RunLoop delete_run_loop;
  mojo::PendingRemote<mojom::URLLoader> loader;
  std::unique_ptr<URLLoader> url_loader;
  context().mutable_factory_params().process_id =
      OriginatingProcessId::browser();
  url_loader = URLLoaderOptions().MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.InitWithNewPipeAndPassReceiver(), request,
      client()->CreateRemote());

  client()->RunUntilRedirectReceived();

  const auto& request_headers = sent_request().headers;
  EXPECT_EQ(request_headers.end(), request_headers.find("Sec-Fetch-User"));
  EXPECT_EQ("empty", request_headers.find("Sec-Fetch-Dest")->second);
}

// A mock URLRequestJob which simulates an HTTPS request with a certificate
// error.
class MockHTTPSURLRequestJob : public net::URLRequestTestJob {
 public:
  MockHTTPSURLRequestJob(net::URLRequest* request,
                         const std::string& response_headers,
                         const std::string& response_data,
                         bool auto_advance)
      : net::URLRequestTestJob(request,
                               response_headers,
                               response_data,
                               auto_advance) {}

  MockHTTPSURLRequestJob(const MockHTTPSURLRequestJob&) = delete;
  MockHTTPSURLRequestJob& operator=(const MockHTTPSURLRequestJob&) = delete;

  ~MockHTTPSURLRequestJob() override = default;

  // net::URLRequestTestJob:
  void GetResponseInfo(net::HttpResponseInfo* info) override {
    // Get the original response info, but override the SSL info.
    net::URLRequestJob::GetResponseInfo(info);
    info->ssl_info.cert =
        net::ImportCertFromFile(net::GetTestCertsDirectory(), "ok_cert.pem");
    info->ssl_info.cert_status = net::CERT_STATUS_DATE_INVALID;
  }
};

class MockHTTPSJobURLRequestInterceptor : public net::URLRequestInterceptor {
 public:
  MockHTTPSJobURLRequestInterceptor() {}
  ~MockHTTPSJobURLRequestInterceptor() override {}

  // net::URLRequestInterceptor:
  std::unique_ptr<net::URLRequestJob> MaybeInterceptRequest(
      net::URLRequest* request) const override {
    EXPECT_FALSE(request->load_flags() & net::LOAD_BYPASS_CACHE);
    return std::make_unique<MockHTTPSURLRequestJob>(request, std::string(),
                                                    "dummy response", true);
  }
};

// Tests that |cert_status| is set on the resource response.
TEST_F(URLLoaderTest, CertStatusOnResponse) {
  net::URLRequestFilter::GetInstance()->ClearHandlers();
  net::URLRequestFilter::GetInstance()->AddHostnameInterceptor(
      "https", "example.test",
      std::unique_ptr<net::URLRequestInterceptor>(
          new MockHTTPSJobURLRequestInterceptor()));

  EXPECT_EQ(net::OK, Load(GURL("https://example.test/")));
  EXPECT_EQ(net::CERT_STATUS_DATE_INVALID,
            client()->response_head()->cert_status);
}

// Verifies if URLLoader works well with ResourceScheduler.
TEST_F(URLLoaderTest, ResourceSchedulerIntegration) {
  // ResourceScheduler limits the number of connections for the same host
  // by 6.
  constexpr int kRepeat = 6;
  constexpr char kPath[] = "/hello.html";

  net::EmbeddedTestServer server;
  // This is needed to stall all requests to the server.
  net::test_server::ControllableHttpResponse response_controllers[kRepeat] = {
      {&server, kPath}, {&server, kPath}, {&server, kPath},
      {&server, kPath}, {&server, kPath}, {&server, kPath},
  };

  ASSERT_TRUE(server.Start());

  ResourceRequest request = CreateResourceRequest("GET", server.GetURL(kPath));
  request.load_flags = net::LOAD_DISABLE_CACHE;
  request.priority = net::IDLE;

  // Fill up the ResourceScheduler with delayable requests.
  std::vector<
      std::pair<std::unique_ptr<URLLoader>, mojo::Remote<mojom::URLLoader>>>
      loaders;
  context().mutable_factory_params().process_id = kProcessId;
  context().mutable_factory_params().is_orb_enabled = false;
  for (int i = 0; i < kRepeat; ++i) {
    TestURLLoaderClient client;
    mojo::PendingRemote<mojom::URLLoader> loader_remote;

    std::unique_ptr<URLLoader> url_loader = URLLoaderOptions().MakeURLLoader(
        context(), NeverInvokedDeleteLoaderCallback(),
        loader_remote.InitWithNewPipeAndPassReceiver(), request,
        client.CreateRemote());

    loaders.emplace_back(std::move(url_loader), std::move(loader_remote));
  }

  ASSERT_TRUE(base::test::RunUntil([&]() {
    return std::ranges::all_of(loaders, [](const auto& pair) {
      return pair.first->GetLoadState() == net::LOAD_STATE_WAITING_FOR_RESPONSE;
    });
  })) << "Timeout waiting for all loaders to be in state "
         "net::LOAD_STATE_WAITING_FOR_RESPONSE";

  mojo::PendingRemote<mojom::URLLoader> loader_remote;
  std::unique_ptr<URLLoader> loader = URLLoaderOptions().MakeURLLoader(
      context(), NeverInvokedDeleteLoaderCallback(),
      loader_remote.InitWithNewPipeAndPassReceiver(), request,
      client()->CreateRemote());
  base::RunLoop().RunUntilIdle();

  // Make sure that the ResourceScheduler throttles this request.
  EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_DELEGATE, loader->GetLoadState());

  loader->SetPriority(net::HIGHEST, 0 /* intra_priority_value */);
  base::RunLoop().RunUntilIdle();

  // Make sure that the ResourceScheduler stops throtting.
  EXPECT_EQ(net::LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET,
            loader->GetLoadState());
}

// This tests that case where a read pipe is closed while there's a post task to
// invoke ReadMore.
TEST_F(URLLoaderTest, ReadPipeClosedWhileReadTaskPosted) {
  AddEternalSyncReadsInterceptor();

  ResourceRequest request = CreateResourceRequest(
      "GET", EternalSyncReadsInterceptor::GetSingleByteURL());

  base::RunLoop delete_run_loop;
  mojo::PendingRemote<mojom::URLLoader> loader;
  std::unique_ptr<URLLoader> url_loader;
  context().mutable_factory_params().process_id =
      OriginatingProcessId::browser();
  context().mutable_factory_params().is_orb_enabled = false;
  url_loader = URLLoaderOptions().MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.InitWithNewPipeAndPassReceiver(), request,
      client()->CreateRemote());

  client()->RunUntilResponseBodyArrived();
  client()->response_body_release();
  delete_run_loop.Run();
}

class FakeSSLPrivateKeyImpl : public network::mojom::SSLPrivateKey {
 public:
  explicit FakeSSLPrivateKeyImpl(
      scoped_refptr<net::SSLPrivateKey> ssl_private_key)
      : ssl_private_key_(std::move(ssl_private_key)) {}

  FakeSSLPrivateKeyImpl(const FakeSSLPrivateKeyImpl&) = delete;
  FakeSSLPrivateKeyImpl& operator=(const FakeSSLPrivateKeyImpl&) = delete;

  ~FakeSSLPrivateKeyImpl() override {}

  // network::mojom::SSLPrivateKey:
  void Sign(uint16_t algorithm,
            const std::vector<uint8_t>& input,
            network::mojom::SSLPrivateKey::SignCallback callback) override {
    base::span<const uint8_t> input_span(input);
    ssl_private_key_->Sign(
        algorithm, input_span,
        base::BindOnce(&FakeSSLPrivateKeyImpl::Callback, base::Unretained(this),
                       std::move(callback)));
  }

 private:
  void Callback(network::mojom::SSLPrivateKey::SignCallback callback,
                net::Error net_error,
                const std::vector<uint8_t>& signature) {
    std::move(callback).Run(static_cast<int32_t>(net_error), signature);
  }

  scoped_refptr<net::SSLPrivateKey> ssl_private_key_;
};

using CookieAccessType = mojom::CookieAccessDetails::Type;

class MockCookieObserver : public network::mojom::CookieAccessObserver {
 public:
  explicit MockCookieObserver(
      std::optional<CookieAccessType> access_type = std::nullopt)
      : access_type_(access_type) {}
  ~MockCookieObserver() override = default;

  struct CookieDetails {
    CookieDetails(const mojom::CookieAccessDetailsPtr& details,
                  const mojom::CookieOrLineWithAccessResultPtr& cookie)
        : type(details->type),
          cookie_or_line(std::move(cookie->cookie_or_line)),
          is_include(cookie->access_result.status.IsInclude()),
          url(details->url),
          status(cookie->access_result.status) {}

    CookieAccessType type;
    mojom::CookieOrLinePtr cookie_or_line;
    bool is_include;

    // The full details are available for the tests to query manually, but
    // they are not covered by operator== (and testing::ElementsAre).
    GURL url;
    net::CookieInclusionStatus status;
  };

  mojo::PendingRemote<mojom::CookieAccessObserver> GetRemote() {
    mojo::PendingRemote<mojom::CookieAccessObserver> remote;
    receivers_.Add(this, remote.InitWithNewPipeAndPassReceiver());
    return remote;
  }

  void OnCookiesAccessed(std::vector<network::mojom::CookieAccessDetailsPtr>
                             details_vector) override {
    for (auto& details : details_vector) {
      if (access_type_ && access_type_ != details->type) {
        continue;
      }

      for (const auto& cookie_with_status : details->cookie_list) {
        observed_cookies_.emplace_back(details, cookie_with_status);
      }
    }
    if (wait_for_cookie_count_ &&
        observed_cookies().size() >= wait_for_cookie_count_) {
      std::move(wait_for_cookies_quit_closure_).Run();
    }
  }

  void WaitForCookies(size_t cookie_count) {
    if (observed_cookies_.size() < cookie_count) {
      wait_for_cookie_count_ = cookie_count;
      base::RunLoop run_loop;
      wait_for_cookies_quit_closure_ = run_loop.QuitClosure();
      run_loop.Run();
    }
    EXPECT_EQ(observed_cookies_.size(), cookie_count);
  }

  void Clone(
      mojo::PendingReceiver<mojom::CookieAccessObserver> observer) override {
    receivers_.Add(this, std::move(observer));
  }

  const std::vector<CookieDetails>& observed_cookies() {
    return observed_cookies_;
  }

 private:
  std::optional<CookieAccessType> access_type_;
  size_t wait_for_cookie_count_ = 0;
  base::OnceClosure wait_for_cookies_quit_closure_;
  std::vector<CookieDetails> observed_cookies_;
  mojo::ReceiverSet<mojom::CookieAccessObserver> receivers_;
};

MATCHER_P3(MatchesCookieDetails, type, cookie_or_line, is_include, "") {
  return testing::ExplainMatchResult(
      testing::AllOf(
          testing::Field(&MockCookieObserver::CookieDetails::type, type),
          testing::Field(&MockCookieObserver::CookieDetails::cookie_or_line,
                         cookie_or_line),
          testing::Field(&MockCookieObserver::CookieDetails::is_include,
                         is_include)),
      arg, result_listener);
}

class MockTrustTokenObserver : public network::mojom::TrustTokenAccessObserver {
 public:
  MockTrustTokenObserver() = default;
  ~MockTrustTokenObserver() override = default;

  struct TrustTokenDetails {
    explicit TrustTokenDetails(
        const mojom::TrustTokenAccessDetailsPtr& details) {
      switch (details->which()) {
        case mojom::TrustTokenAccessDetails::Tag::kIssuance:
          type = mojom::TrustTokenOperationType::kIssuance;
          origin = details->get_issuance()->origin;
          issuer = details->get_issuance()->issuer;
          blocked = details->get_issuance()->blocked;
          break;
        case mojom::TrustTokenAccessDetails::Tag::kRedemption:
          type = mojom::TrustTokenOperationType::kRedemption;
          origin = details->get_redemption()->origin;
          issuer = details->get_redemption()->issuer;
          blocked = details->get_redemption()->blocked;
          break;
        case mojom::TrustTokenAccessDetails::Tag::kSigning:
          type = mojom::TrustTokenOperationType::kSigning;
          origin = details->get_signing()->origin;
          blocked = details->get_signing()->blocked;
          break;
      }
    }

    url::Origin origin;
    mojom::TrustTokenOperationType type;
    std::optional<url::Origin> issuer;
    bool blocked;
  };

  mojo::PendingRemote<mojom::TrustTokenAccessObserver> GetRemote() {
    mojo::PendingRemote<mojom::TrustTokenAccessObserver> remote;
    receivers_.Add(this, remote.InitWithNewPipeAndPassReceiver());
    return remote;
  }

  void OnTrustTokensAccessed(
      mojom::TrustTokenAccessDetailsPtr details) override {
    observed_tokens_.emplace_back(details);
    if (wait_for_token_count_ &&
        observed_tokens().size() >= wait_for_token_count_) {
      std::move(wait_for_tokens_quit_closure_).Run();
    }
  }

  void WaitForTrustTokens(size_t token_count) {
    if (observed_tokens_.size() < token_count) {
      wait_for_token_count_ = token_count;
      base::RunLoop run_loop;
      wait_for_tokens_quit_closure_ = run_loop.QuitClosure();
      run_loop.Run();
    }
    EXPECT_EQ(observed_tokens_.size(), token_count);
  }

  void Clone(mojo::PendingReceiver<mojom::TrustTokenAccessObserver> observer)
      override {
    receivers_.Add(this, std::move(observer));
  }

  const std::vector<TrustTokenDetails>& observed_tokens() {
    return observed_tokens_;
  }

 private:
  size_t wait_for_token_count_ = 0;
  base::OnceClosure wait_for_tokens_quit_closure_;
  std::vector<TrustTokenDetails> observed_tokens_;
  mojo::ReceiverSet<mojom::TrustTokenAccessObserver> receivers_;
};

MATCHER_P3(MatchesTrustTokenDetails, origin, issuer, blocked, "") {
  return testing::ExplainMatchResult(
      testing::AllOf(
          testing::Field(&MockTrustTokenObserver::TrustTokenDetails::origin,
                         origin),
          testing::Field(&MockTrustTokenObserver::TrustTokenDetails::issuer,
                         issuer),
          testing::Field(&MockTrustTokenObserver::TrustTokenDetails::blocked,
                         blocked)),
      arg, result_listener);
}

// Responds certificate request with previously set responses and to HTTP auth
// challenges as well.
class ClientCertAndHttpAuthObserver : public TestURLLoaderNetworkObserver {
 public:
  ClientCertAndHttpAuthObserver() = default;
  ~ClientCertAndHttpAuthObserver() override = default;

  enum class CertificateResponse {
    INVALID = -1,
    URL_LOADER_REQUEST_CANCELLED,
    CANCEL_CERTIFICATE_SELECTION,
    NULL_CERTIFICATE,
    VALID_CERTIFICATE_SIGNATURE,
    INVALID_CERTIFICATE_SIGNATURE,
    DESTROY_CLIENT_CERT_RESPONDER,
  };

  enum class CredentialsResponse {
    NO_CREDENTIALS,
    CORRECT_CREDENTIALS,
    INCORRECT_CREDENTIALS_THEN_CORRECT_ONES,
    CORRECT_PROXY_CREDENTIALS,
  };
  void OnAuthRequired(
      const std::optional<base::UnguessableToken>& window_id,
      int32_t request_id,
      const GURL& url,
      bool first_auth_attempt,
      bool do_not_prompt_for_login,
      const net::AuthChallengeInfo& auth_info,
      const scoped_refptr<net::HttpResponseHeaders>& head_headers,
      mojo::PendingRemote<mojom::AuthChallengeResponder>
          auth_challenge_responder) override {
    switch (credentials_response_) {
      case CredentialsResponse::NO_CREDENTIALS:
        auth_credentials_ = std::nullopt;
        break;
      case CredentialsResponse::CORRECT_CREDENTIALS:
        ASSERT_FALSE(auth_info.is_proxy);
        auth_credentials_ = net::AuthCredentials(u"USER", u"PASS");
        break;
      case CredentialsResponse::INCORRECT_CREDENTIALS_THEN_CORRECT_ONES:
        auth_credentials_ = net::AuthCredentials(u"USER", u"FAIL");
        credentials_response_ = CredentialsResponse::CORRECT_CREDENTIALS;
        break;
      case CredentialsResponse::CORRECT_PROXY_CREDENTIALS:
        ASSERT_TRUE(auth_info.is_proxy);
        auth_credentials_ = net::AuthCredentials(u"PROXY_USER", u"PROXY_PASS");
        break;
    }
    mojo::Remote<mojom::AuthChallengeResponder> auth_challenge_responder_remote(
        std::move(auth_challenge_responder));
    auth_challenge_responder_remote->OnAuthCredentials(auth_credentials_);
    ++on_auth_required_call_counter_;
    last_seen_response_headers_ = head_headers;
    last_do_not_prompt_for_login_ = do_not_prompt_for_login;
  }

  void OnCertificateRequested(
      const std::optional<base::UnguessableToken>& window_id,
      const scoped_refptr<net::SSLCertRequestInfo>& cert_info,
      mojo::PendingRemote<mojom::ClientCertificateResponder>
          client_cert_responder_remote) override {
    mojo::Remote<mojom::ClientCertificateResponder> client_cert_responder(
        std::move(client_cert_responder_remote));
    switch (certificate_response_) {
      case CertificateResponse::INVALID:
        NOTREACHED();
      case CertificateResponse::URL_LOADER_REQUEST_CANCELLED:
        ASSERT_TRUE(url_loader_remote_);
        url_loader_remote_->reset();
        break;
      case CertificateResponse::CANCEL_CERTIFICATE_SELECTION:
        client_cert_responder->CancelRequest();
        break;
      case CertificateResponse::NULL_CERTIFICATE:
        client_cert_responder->ContinueWithoutCertificate();
        break;
      case CertificateResponse::VALID_CERTIFICATE_SIGNATURE:
      case CertificateResponse::INVALID_CERTIFICATE_SIGNATURE:
        client_cert_responder->ContinueWithCertificate(
            std::move(certificate_), provider_name_, algorithm_preferences_,
            std::move(ssl_private_key_remote_));
        break;
      case CertificateResponse::DESTROY_CLIENT_CERT_RESPONDER:
        // Send no response and let the local variable be destroyed.
        break;
    }
    ++on_certificate_requested_counter_;
  }

  void set_certificate_response(CertificateResponse certificate_response) {
    certificate_response_ = certificate_response;
  }

  void set_private_key(scoped_refptr<net::SSLPrivateKey> ssl_private_key) {
    ssl_private_key_ = std::move(ssl_private_key);
    provider_name_ = ssl_private_key_->GetProviderName();
    algorithm_preferences_ = ssl_private_key_->GetAlgorithmPreferences();
    mojo::MakeSelfOwnedReceiver(
        std::make_unique<FakeSSLPrivateKeyImpl>(std::move(ssl_private_key_)),
        ssl_private_key_remote_.InitWithNewPipeAndPassReceiver());
  }

  void set_certificate(scoped_refptr<net::X509Certificate> certificate) {
    certificate_ = std::move(certificate);
  }

  int on_certificate_requested_counter() {
    return on_certificate_requested_counter_;
  }

  void set_url_loader_remote(
      mojo::Remote<mojom::URLLoader>* url_loader_remote) {
    url_loader_remote_ = url_loader_remote;
  }

  void set_credentials_response(CredentialsResponse credentials_response) {
    credentials_response_ = credentials_response;
  }

  int on_auth_required_call_counter() { return on_auth_required_call_counter_; }

  net::HttpResponseHeaders* last_seen_response_headers() {
    return last_seen_response_headers_.get();
  }

  // std::nullopt if OnAuthRequired() was never called.
  std::optional<bool> last_do_not_prompt_for_login() const {
    return last_do_not_prompt_for_login_;
  }

 private:
  CredentialsResponse credentials_response_ =
      CredentialsResponse::NO_CREDENTIALS;
  std::optional<net::AuthCredentials> auth_credentials_;
  int on_auth_required_call_counter_ = 0;
  scoped_refptr<net::HttpResponseHeaders> last_seen_response_headers_;
  std::optional<bool> last_do_not_prompt_for_login_;
  CertificateResponse certificate_response_ = CertificateResponse::INVALID;
  scoped_refptr<net::SSLPrivateKey> ssl_private_key_;
  scoped_refptr<net::X509Certificate> certificate_;
  mojo::PendingRemote<network::mojom::SSLPrivateKey> ssl_private_key_remote_;
  std::string provider_name_;
  std::vector<uint16_t> algorithm_preferences_;
  int on_certificate_requested_counter_ = 0;
  raw_ptr<mojo::Remote<mojom::URLLoader>> url_loader_remote_ = nullptr;
};

TEST_F(URLLoaderTest, SetAuth) {
  ClientCertAndHttpAuthObserver client_auth_observer;
  client_auth_observer.set_credentials_response(
      ClientCertAndHttpAuthObserver::CredentialsResponse::CORRECT_CREDENTIALS);

  ResourceRequest request =
      CreateResourceRequest("GET", test_server()->GetURL(kTestAuthURL));
  base::RunLoop delete_run_loop;
  mojo::PendingRemote<mojom::URLLoader> loader;
  context().mutable_factory_params().process_id = kProcessId;
  context().mutable_factory_params().is_orb_enabled = false;
  URLLoaderOptions url_loader_options;
  url_loader_options.url_loader_network_observer = client_auth_observer.Bind();
  std::unique_ptr<URLLoader> url_loader = url_loader_options.MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.InitWithNewPipeAndPassReceiver(), request,
      client()->CreateRemote());

  client()->RunUntilResponseBodyArrived();
  EXPECT_TRUE(client()->has_received_response());
  EXPECT_FALSE(client()->has_received_completion());

  // Spin the message loop until the delete callback is invoked, and then delete
  // the URLLoader.
  delete_run_loop.Run();

  client()->RunUntilComplete();
  EXPECT_TRUE(client()->has_received_completion());
  scoped_refptr<net::HttpResponseHeaders> headers =
      client()->response_head()->headers;
  ASSERT_TRUE(headers);
  EXPECT_EQ(200, headers->response_code());
  EXPECT_EQ(1, client_auth_observer.on_auth_required_call_counter());
  ASSERT_FALSE(url_loader);
  EXPECT_FALSE(client()->response_head()->auth_challenge_info.has_value());
}

TEST_F(URLLoaderTest, CancelAuth) {
  ClientCertAndHttpAuthObserver client_auth_observer;
  client_auth_observer.set_credentials_response(
      ClientCertAndHttpAuthObserver::CredentialsResponse::NO_CREDENTIALS);

  ResourceRequest request =
      CreateResourceRequest("GET", test_server()->GetURL(kTestAuthURL));
  base::RunLoop delete_run_loop;
  mojo::PendingRemote<mojom::URLLoader> loader;
  context().mutable_factory_params().process_id = kProcessId;
  context().mutable_factory_params().is_orb_enabled = false;
  URLLoaderOptions url_loader_options;
  url_loader_options.url_loader_network_observer = client_auth_observer.Bind();
  std::unique_ptr<URLLoader> url_loader = url_loader_options.MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.InitWithNewPipeAndPassReceiver(), request,
      client()->CreateRemote());

  client()->RunUntilResponseBodyArrived();
  EXPECT_TRUE(client()->has_received_response());
  EXPECT_FALSE(client()->has_received_completion());

  // Spin the message loop until the delete callback is invoked, and then delete
  // the URLLoader.
  delete_run_loop.Run();

  client()->RunUntilComplete();
  EXPECT_TRUE(client()->has_received_completion());
  scoped_refptr<net::HttpResponseHeaders> headers =
      client()->response_head()->headers;
  ASSERT_TRUE(headers);
  EXPECT_EQ(401, headers->response_code());
  EXPECT_EQ(1, client_auth_observer.on_auth_required_call_counter());
  ASSERT_FALSE(url_loader);
}

TEST_F(URLLoaderTest, TwoChallenges) {
  ClientCertAndHttpAuthObserver client_auth_observer;
  client_auth_observer.set_credentials_response(
      ClientCertAndHttpAuthObserver::CredentialsResponse::
          INCORRECT_CREDENTIALS_THEN_CORRECT_ONES);

  ResourceRequest request =
      CreateResourceRequest("GET", test_server()->GetURL(kTestAuthURL));
  base::RunLoop delete_run_loop;
  mojo::PendingRemote<mojom::URLLoader> loader;
  context().mutable_factory_params().process_id = kProcessId;
  context().mutable_factory_params().is_orb_enabled = false;
  URLLoaderOptions url_loader_options;
  url_loader_options.url_loader_network_observer = client_auth_observer.Bind();
  std::unique_ptr<URLLoader> url_loader = url_loader_options.MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.InitWithNewPipeAndPassReceiver(), request,
      client()->CreateRemote());

  client()->RunUntilResponseBodyArrived();
  EXPECT_TRUE(client()->has_received_response());
  EXPECT_FALSE(client()->has_received_completion());

  // Spin the message loop until the delete callback is invoked, and then delete
  // the URLLoader.
  delete_run_loop.Run();

  client()->RunUntilComplete();
  EXPECT_TRUE(client()->has_received_completion());
  scoped_refptr<net::HttpResponseHeaders> headers =
      client()->response_head()->headers;
  ASSERT_TRUE(headers);
  EXPECT_EQ(200, headers->response_code());
  EXPECT_EQ(2, client_auth_observer.on_auth_required_call_counter());
  ASSERT_FALSE(url_loader);
}

TEST_F(URLLoaderTest, NoAuthRequiredForFavicon) {
  constexpr char kFaviconTestPage[] = "/has_favicon.html";

  ClientCertAndHttpAuthObserver client_auth_observer;
  client_auth_observer.set_credentials_response(
      ClientCertAndHttpAuthObserver::CredentialsResponse::CORRECT_CREDENTIALS);

  ResourceRequest request =
      CreateResourceRequest("GET", test_server()->GetURL(kFaviconTestPage));
  base::RunLoop delete_run_loop;
  mojo::PendingRemote<mojom::URLLoader> loader;
  context().mutable_factory_params().process_id = kProcessId;
  context().mutable_factory_params().is_orb_enabled = false;
  URLLoaderOptions url_loader_options;
  url_loader_options.url_loader_network_observer = client_auth_observer.Bind();
  std::unique_ptr<URLLoader> url_loader = url_loader_options.MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.InitWithNewPipeAndPassReceiver(), request,
      client()->CreateRemote());

  client()->RunUntilResponseBodyArrived();
  EXPECT_TRUE(client()->has_received_response());
  EXPECT_FALSE(client()->has_received_completion());

  // Spin the message loop until the delete callback is invoked, and then delete
  // the URLLoader.
  delete_run_loop.Run();

  client()->RunUntilComplete();
  EXPECT_TRUE(client()->has_received_completion());
  scoped_refptr<net::HttpResponseHeaders> headers =
      client()->response_head()->headers;
  ASSERT_TRUE(headers);
  EXPECT_EQ(200, headers->response_code());
  // No auth required for favicon.
  EXPECT_EQ(0, client_auth_observer.on_auth_required_call_counter());
  ASSERT_FALSE(url_loader);
}

TEST_F(URLLoaderTest, HttpAuthResponseHeadersAvailable) {
  ClientCertAndHttpAuthObserver client_auth_observer;
  client_auth_observer.set_credentials_response(
      ClientCertAndHttpAuthObserver::CredentialsResponse::CORRECT_CREDENTIALS);

  ResourceRequest request =
      CreateResourceRequest("GET", test_server()->GetURL(kTestAuthURL));
  base::RunLoop delete_run_loop;
  mojo::PendingRemote<mojom::URLLoader> loader;
  context().mutable_factory_params().process_id = kProcessId;
  context().mutable_factory_params().is_orb_enabled = false;
  URLLoaderOptions url_loader_options;
  url_loader_options.url_loader_network_observer = client_auth_observer.Bind();
  std::unique_ptr<URLLoader> url_loader = url_loader_options.MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.InitWithNewPipeAndPassReceiver(), request,
      client()->CreateRemote());

  client()->RunUntilResponseBodyArrived();

  // Spin the message loop until the delete callback is invoked, and then delete
  // the URLLoader.
  delete_run_loop.Run();

  EXPECT_EQ(1, client_auth_observer.on_auth_required_call_counter());

  auto* auth_required_headers =
      client_auth_observer.last_seen_response_headers();
  ASSERT_TRUE(auth_required_headers);
  EXPECT_EQ(auth_required_headers->response_code(), 401);
}

// Tests that `did_use_server_http_auth` is present on the response when a
// request receives and responds to an authentication challenge.
TEST_F(URLLoaderTest, ServerHttpAuthFlagSet) {
  ClientCertAndHttpAuthObserver client_auth_observer;
  client_auth_observer.set_credentials_response(
      ClientCertAndHttpAuthObserver::CredentialsResponse::CORRECT_CREDENTIALS);

  ResourceRequest request =
      CreateResourceRequest("GET", test_server()->GetURL(kTestAuthURL));
  base::RunLoop delete_run_loop;
  mojo::Remote<mojom::URLLoader> loader;
  context().mutable_factory_params().process_id = kProcessId;
  context().mutable_factory_params().is_orb_enabled = false;
  URLLoaderOptions url_loader_options;
  url_loader_options.url_loader_network_observer = client_auth_observer.Bind();
  std::unique_ptr<URLLoader> url_loader = url_loader_options.MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.BindNewPipeAndPassReceiver(), request, client()->CreateRemote());

  client()->RunUntilResponseBodyArrived();
  EXPECT_TRUE(client()->has_received_response());
  EXPECT_FALSE(client()->has_received_completion());
  EXPECT_TRUE(client()->response_head()->did_use_server_http_auth);

  // Spin the message loop until the delete callback is invoked, and then delete
  // the URLLoader.
  delete_run_loop.Run();

  client()->RunUntilComplete();
  EXPECT_TRUE(client()->has_received_completion());
  scoped_refptr<net::HttpResponseHeaders> headers =
      client()->response_head()->headers;
  ASSERT_TRUE(headers);
  EXPECT_EQ(200, headers->response_code());
  EXPECT_EQ(1, client_auth_observer.on_auth_required_call_counter());
  ASSERT_FALSE(url_loader);
}

// Tests that `did_use_server_http_auth` is not present on the response when a
// request does not use an authentication challenge.
TEST_F(URLLoaderTest, ServerHttpAuthFlagNotSet) {
  ResourceRequest request =
      CreateResourceRequest("GET", test_server()->GetURL("/simple_page.html"));
  base::RunLoop delete_run_loop;
  mojo::Remote<mojom::URLLoader> loader;
  context().mutable_factory_params().process_id = kProcessId;
  context().mutable_factory_params().is_orb_enabled = false;
  URLLoaderOptions url_loader_options;
  std::unique_ptr<URLLoader> url_loader = url_loader_options.MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.BindNewPipeAndPassReceiver(), request, client()->CreateRemote());

  client()->RunUntilResponseBodyArrived();
  EXPECT_TRUE(client()->has_received_response());
  EXPECT_FALSE(client()->has_received_completion());
  EXPECT_FALSE(client()->response_head()->did_use_server_http_auth);

  // Spin the message loop until the delete callback is invoked, and then delete
  // the URLLoader.
  delete_run_loop.Run();

  client()->RunUntilComplete();
  EXPECT_TRUE(client()->has_received_completion());
  scoped_refptr<net::HttpResponseHeaders> headers =
      client()->response_head()->headers;
  ASSERT_TRUE(headers);
  EXPECT_EQ(200, headers->response_code());
  ASSERT_FALSE(url_loader);
}

// Tests that `did_use_server_http_auth` is not present on the response when a
// request receives and responds to a proxy authentication challenge.
TEST_F(URLLoaderTest, ServerHttpAuthFlagNotSetForProxy) {
  net::EmbeddedTestServer proxy_server(net::EmbeddedTestServer::TYPE_HTTP);
  ASSERT_NO_FATAL_FAILURE(UseAuthenticatingProxy(proxy_server));

  ClientCertAndHttpAuthObserver client_auth_observer;
  client_auth_observer.set_credentials_response(
      ClientCertAndHttpAuthObserver::CredentialsResponse::
          CORRECT_PROXY_CREDENTIALS);

  ResourceRequest request = CreateResourceRequest(
      "GET", test_server()->GetURL(kHostnameWithAliases, "/hello.html"));
  base::RunLoop delete_run_loop;
  mojo::Remote<mojom::URLLoader> loader;
  context().mutable_factory_params().process_id = kProcessId;
  context().mutable_factory_params().is_orb_enabled = false;
  URLLoaderOptions url_loader_options;
  url_loader_options.url_loader_network_observer = client_auth_observer.Bind();
  std::unique_ptr<URLLoader> url_loader = url_loader_options.MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.BindNewPipeAndPassReceiver(), request, client()->CreateRemote());

  client()->RunUntilComplete();
  delete_run_loop.Run();

  // This should be false as we do not set the flag for proxy auth.
  EXPECT_FALSE(client()->response_head()->did_use_server_http_auth);
  ASSERT_FALSE(url_loader);
}

// Tests that a proxy auth challenge for a request with
// `do_not_prompt_for_login` is forwarded to the observer, flagged as such, so
// that credential sources that don't show UI can answer it.
TEST_F(URLLoaderTest, DoNotPromptForLoginForwardsProxyAuthChallenge) {
  net::EmbeddedTestServer proxy_server(net::EmbeddedTestServer::TYPE_HTTP);
  ASSERT_NO_FATAL_FAILURE(UseAuthenticatingProxy(proxy_server));

  ClientCertAndHttpAuthObserver client_auth_observer;
  client_auth_observer.set_credentials_response(
      ClientCertAndHttpAuthObserver::CredentialsResponse::
          CORRECT_PROXY_CREDENTIALS);

  ResourceRequest request = CreateResourceRequest(
      "GET", test_server()->GetURL(kHostnameWithAliases, "/hello.html"));
  request.do_not_prompt_for_login = true;
  base::RunLoop delete_run_loop;
  mojo::Remote<mojom::URLLoader> loader;
  context().mutable_factory_params().process_id = kProcessId;
  context().mutable_factory_params().is_orb_enabled = false;
  URLLoaderOptions url_loader_options;
  url_loader_options.url_loader_network_observer = client_auth_observer.Bind();
  std::unique_ptr<URLLoader> url_loader = url_loader_options.MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.BindNewPipeAndPassReceiver(), request, client()->CreateRemote());

  client()->RunUntilComplete();
  delete_run_loop.Run();

  EXPECT_EQ(net::OK, client()->completion_status().error_code);
  ASSERT_TRUE(client()->response_head()->headers);
  EXPECT_EQ(200, client()->response_head()->headers->response_code());
  EXPECT_EQ(1, client_auth_observer.on_auth_required_call_counter());
  EXPECT_THAT(client_auth_observer.last_do_not_prompt_for_login(),
              Optional(true));
  ASSERT_FALSE(url_loader);
}

// Tests that, when the `kForwardProxyAuthWithoutPrompt` kill switch is
// disabled, a proxy auth challenge for a request with `do_not_prompt_for_login`
// is cancelled without notifying the observer.
TEST_F(URLLoaderTest,
       DoNotPromptForLoginCancelsProxyAuthChallengeWithoutForwarding) {
  base::test::ScopedFeatureList feature_list;
  feature_list.InitAndDisableFeature(features::kForwardProxyAuthWithoutPrompt);

  net::EmbeddedTestServer proxy_server(net::EmbeddedTestServer::TYPE_HTTP);
  ASSERT_NO_FATAL_FAILURE(UseAuthenticatingProxy(proxy_server));

  ClientCertAndHttpAuthObserver client_auth_observer;
  client_auth_observer.set_credentials_response(
      ClientCertAndHttpAuthObserver::CredentialsResponse::
          CORRECT_PROXY_CREDENTIALS);

  ResourceRequest request = CreateResourceRequest(
      "GET", test_server()->GetURL(kHostnameWithAliases, "/hello.html"));
  request.do_not_prompt_for_login = true;
  base::RunLoop delete_run_loop;
  mojo::Remote<mojom::URLLoader> loader;
  context().mutable_factory_params().process_id = kProcessId;
  context().mutable_factory_params().is_orb_enabled = false;
  URLLoaderOptions url_loader_options;
  url_loader_options.url_loader_network_observer = client_auth_observer.Bind();
  std::unique_ptr<URLLoader> url_loader = url_loader_options.MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.BindNewPipeAndPassReceiver(), request, client()->CreateRemote());

  client()->RunUntilComplete();
  delete_run_loop.Run();

  EXPECT_EQ(net::OK, client()->completion_status().error_code);
  ASSERT_TRUE(client()->response_head()->headers);
  EXPECT_EQ(net::HTTP_PROXY_AUTHENTICATION_REQUIRED,
            client()->response_head()->headers->response_code());
  EXPECT_EQ(0, client_auth_observer.on_auth_required_call_counter());
  EXPECT_EQ(std::nullopt, client_auth_observer.last_do_not_prompt_for_login());
  ASSERT_FALSE(url_loader);
}

// Tests that a server auth challenge for a request with
// `do_not_prompt_for_login` is cancelled without notifying the observer.
TEST_F(URLLoaderTest, DoNotPromptForLoginCancelsServerAuthChallenge) {
  ClientCertAndHttpAuthObserver client_auth_observer;
  client_auth_observer.set_credentials_response(
      ClientCertAndHttpAuthObserver::CredentialsResponse::CORRECT_CREDENTIALS);

  ResourceRequest request =
      CreateResourceRequest("GET", test_server()->GetURL(kTestAuthURL));
  request.do_not_prompt_for_login = true;
  base::RunLoop delete_run_loop;
  mojo::Remote<mojom::URLLoader> loader;
  context().mutable_factory_params().process_id = kProcessId;
  context().mutable_factory_params().is_orb_enabled = false;
  URLLoaderOptions url_loader_options;
  url_loader_options.url_loader_network_observer = client_auth_observer.Bind();
  std::unique_ptr<URLLoader> url_loader = url_loader_options.MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.BindNewPipeAndPassReceiver(), request, client()->CreateRemote());

  client()->RunUntilComplete();
  delete_run_loop.Run();

  EXPECT_EQ(net::OK, client()->completion_status().error_code);
  ASSERT_TRUE(client()->response_head()->headers);
  EXPECT_EQ(401, client()->response_head()->headers->response_code());
  EXPECT_EQ(0, client_auth_observer.on_auth_required_call_counter());
  ASSERT_FALSE(url_loader);
}

// Make sure the client can't call FollowRedirect if there's no pending
// redirect.
TEST_F(URLLoaderTest, FollowRedirectTwice) {
  ResourceRequest request = CreateResourceRequest(
      "GET", test_server()->GetURL("/redirect307-to-echo"));
  request.headers.SetHeader("Header1", "Value1");
  request.headers.SetHeader("Header2", "Value2");

  base::RunLoop delete_run_loop;
  mojo::PendingRemote<mojom::URLLoader> loader;
  std::unique_ptr<URLLoader> url_loader;
  context().mutable_factory_params().process_id =
      OriginatingProcessId::browser();
  context().mutable_factory_params().is_orb_enabled = false;
  url_loader = URLLoaderOptions().MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.InitWithNewPipeAndPassReceiver(), request,
      client()->CreateRemote());

  client()->RunUntilRedirectReceived();

  url_loader->FollowRedirect(/*headers_update_params=*/{},
                             /*new_url=*/std::nullopt);
  EXPECT_NOTREACHED_DEATH(url_loader->FollowRedirect(
      /*headers_update_params=*/{}, /*new_url=*/std::nullopt));

  client()->RunUntilComplete();
  delete_run_loop.Run();
}

class TestSSLPrivateKey : public net::SSLPrivateKey {
 public:
  explicit TestSSLPrivateKey(scoped_refptr<net::SSLPrivateKey> key)
      : key_(std::move(key)) {}

  TestSSLPrivateKey(const TestSSLPrivateKey&) = delete;
  TestSSLPrivateKey& operator=(const TestSSLPrivateKey&) = delete;

  void set_fail_signing(bool fail_signing) { fail_signing_ = fail_signing; }
  int sign_count() const { return sign_count_; }

  std::string GetProviderName() override { return key_->GetProviderName(); }
  std::vector<uint16_t> GetAlgorithmPreferences() override {
    return key_->GetAlgorithmPreferences();
  }
  void Sign(uint16_t algorithm,
            base::span<const uint8_t> input,
            SignCallback callback) override {
    sign_count_++;
    if (fail_signing_) {
      base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
          FROM_HERE, base::BindOnce(std::move(callback),
                                    net::ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED,
                                    std::vector<uint8_t>()));
    } else {
      key_->Sign(algorithm, input, std::move(callback));
    }
  }

 private:
  ~TestSSLPrivateKey() override = default;

  scoped_refptr<net::SSLPrivateKey> key_;
  bool fail_signing_ = false;
  int sign_count_ = 0;
};

#if !BUILDFLAG(IS_IOS)
TEST_F(URLLoaderTest, ClientAuthRespondTwice) {
  // This tests that one URLLoader can handle two client cert requests.

  net::SSLServerConfig ssl_config;
  ssl_config.client_cert_type =
      net::SSLServerConfig::ClientCertType::REQUIRE_CLIENT_CERT;

  net::EmbeddedTestServer test_server_1(net::EmbeddedTestServer::TYPE_HTTPS);
  test_server_1.SetSSLConfig(net::EmbeddedTestServer::CERT_OK, ssl_config);
  test_server_1.AddDefaultHandlers(
      base::FilePath(FILE_PATH_LITERAL("services/test/data")));
  ASSERT_TRUE(test_server_1.Start());

  net::EmbeddedTestServer test_server_2(net::EmbeddedTestServer::TYPE_HTTPS);
  test_server_2.SetSSLConfig(net::EmbeddedTestServer::CERT_OK, ssl_config);
  test_server_2.AddDefaultHandlers(
      base::FilePath(FILE_PATH_LITERAL("services/test/data")));
  ASSERT_TRUE(test_server_2.Start());

  std::unique_ptr<net::FakeClientCertIdentity> identity =
      net::FakeClientCertIdentity::CreateFromCertAndKeyFiles(
          net::GetTestCertsDirectory(), "client_1.pem", "client_1.pk8");
  ASSERT_TRUE(identity);
  scoped_refptr<TestSSLPrivateKey> private_key =
      base::MakeRefCounted<TestSSLPrivateKey>(identity->ssl_private_key());

  ClientCertAndHttpAuthObserver client_cert_observer;
  client_cert_observer.set_certificate_response(
      ClientCertAndHttpAuthObserver::CertificateResponse::
          VALID_CERTIFICATE_SIGNATURE);
  client_cert_observer.set_private_key(private_key);
  client_cert_observer.set_certificate(identity->certificate());

  // Create a request to server_1 that will redirect to server_2
  ResourceRequest request = CreateResourceRequest(
      "GET",
      test_server_1.GetURL("/server-redirect-307?" +
                           base::EscapeQueryParamValue(
                               test_server_2.GetURL("/echo").spec(), true)));

  base::RunLoop delete_run_loop;
  mojo::Remote<mojom::URLLoader> loader;
  std::unique_ptr<URLLoader> url_loader;
  context().mutable_factory_params().process_id = kProcessId;
  context().mutable_factory_params().is_orb_enabled = false;
  URLLoaderOptions url_loader_options;
  url_loader_options.url_loader_network_observer = client_cert_observer.Bind();
  url_loader = url_loader_options.MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.BindNewPipeAndPassReceiver(), request, client()->CreateRemote());

  EXPECT_EQ(0, client_cert_observer.on_certificate_requested_counter());
  EXPECT_EQ(0, private_key->sign_count());

  client()->RunUntilRedirectReceived();
  loader->FollowRedirect(/*headers_update_params=*/{},
                         /*new_url=*/std::nullopt);
  // MockNetworkServiceClient gives away the private key when it invokes
  // ContinueWithCertificate, so we have to give it the key again.
  client_cert_observer.set_private_key(private_key);
  client()->RunUntilComplete();
  delete_run_loop.Run();

  EXPECT_EQ(net::OK, client()->completion_status().error_code);
  EXPECT_EQ(2, client_cert_observer.on_certificate_requested_counter());
  EXPECT_EQ(2, private_key->sign_count());
}

TEST_F(URLLoaderTest, ClientAuthDestroyResponder) {
  // When URLLoader receives no message from the ClientCertificateResponder and
  // its connection errors out, we expect the request to be canceled rather than
  // just hang.
  net::EmbeddedTestServer test_server(net::EmbeddedTestServer::TYPE_HTTPS);
  net::SSLServerConfig ssl_config;
  ssl_config.client_cert_type =
      net::SSLServerConfig::ClientCertType::REQUIRE_CLIENT_CERT;
  test_server.SetSSLConfig(net::EmbeddedTestServer::CERT_OK, ssl_config);
  test_server.AddDefaultHandlers(
      base::FilePath(FILE_PATH_LITERAL("services/test/data")));
  ASSERT_TRUE(test_server.Start());

  ClientCertAndHttpAuthObserver client_cert_observer;
  client_cert_observer.set_certificate_response(
      ClientCertAndHttpAuthObserver::CertificateResponse::
          DESTROY_CLIENT_CERT_RESPONDER);

  ResourceRequest request =
      CreateResourceRequest("GET", test_server.GetURL("/defaultresponse"));
  base::RunLoop delete_run_loop;
  mojo::Remote<mojom::URLLoader> loader;
  context().mutable_factory_params().process_id = kProcessId;
  context().mutable_factory_params().is_orb_enabled = false;
  URLLoaderOptions url_loader_options;
  url_loader_options.url_loader_network_observer = client_cert_observer.Bind();
  std::unique_ptr<URLLoader> url_loader = url_loader_options.MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.BindNewPipeAndPassReceiver(), request, client()->CreateRemote());
  client_cert_observer.set_url_loader_remote(&loader);

  client()->RunUntilComplete();

  EXPECT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED,
            client()->completion_status().error_code);
}

TEST_F(URLLoaderTest, ClientAuthCancelConnection) {
  net::EmbeddedTestServer test_server(net::EmbeddedTestServer::TYPE_HTTPS);
  net::SSLServerConfig ssl_config;
  ssl_config.client_cert_type =
      net::SSLServerConfig::ClientCertType::REQUIRE_CLIENT_CERT;
  test_server.SetSSLConfig(net::EmbeddedTestServer::CERT_OK, ssl_config);
  test_server.AddDefaultHandlers(
      base::FilePath(FILE_PATH_LITERAL("services/test/data")));
  ASSERT_TRUE(test_server.Start());

  ClientCertAndHttpAuthObserver client_cert_observer;
  client_cert_observer.set_certificate_response(
      ClientCertAndHttpAuthObserver::CertificateResponse::
          URL_LOADER_REQUEST_CANCELLED);

  ResourceRequest request =
      CreateResourceRequest("GET", test_server.GetURL("/defaultresponse"));
  base::RunLoop delete_run_loop;
  mojo::Remote<mojom::URLLoader> loader;
  context().mutable_factory_params().process_id = kProcessId;
  context().mutable_factory_params().is_orb_enabled = false;
  URLLoaderOptions url_loader_options;
  url_loader_options.url_loader_network_observer = client_cert_observer.Bind();
  std::unique_ptr<URLLoader> url_loader = url_loader_options.MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.BindNewPipeAndPassReceiver(), request, client()->CreateRemote());
  client_cert_observer.set_url_loader_remote(&loader);

  client()->RunUntilComplete();

  EXPECT_EQ(net::ERR_FAILED, client()->completion_status().error_code);
}

TEST_F(URLLoaderTest, ClientAuthCancelCertificateSelection) {
  net::EmbeddedTestServer test_server(net::EmbeddedTestServer::TYPE_HTTPS);
  net::SSLServerConfig ssl_config;
  ssl_config.client_cert_type =
      net::SSLServerConfig::ClientCertType::REQUIRE_CLIENT_CERT;
  test_server.SetSSLConfig(net::EmbeddedTestServer::CERT_OK, ssl_config);
  test_server.AddDefaultHandlers(
      base::FilePath(FILE_PATH_LITERAL("services/test/data")));
  ASSERT_TRUE(test_server.Start());

  ClientCertAndHttpAuthObserver client_cert_observer;
  client_cert_observer.set_certificate_response(
      ClientCertAndHttpAuthObserver::CertificateResponse::
          CANCEL_CERTIFICATE_SELECTION);

  ResourceRequest request =
      CreateResourceRequest("GET", test_server.GetURL("/defaultresponse"));
  base::RunLoop delete_run_loop;
  mojo::PendingRemote<mojom::URLLoader> loader;
  context().mutable_factory_params().process_id = kProcessId;
  context().mutable_factory_params().is_orb_enabled = false;
  URLLoaderOptions url_loader_options;
  url_loader_options.url_loader_network_observer = client_cert_observer.Bind();
  std::unique_ptr<URLLoader> url_loader = url_loader_options.MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.InitWithNewPipeAndPassReceiver(), request,
      client()->CreateRemote());

  client()->RunUntilComplete();

  EXPECT_EQ(1, client_cert_observer.on_certificate_requested_counter());
  EXPECT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED,
            client()->completion_status().error_code);
}

TEST_F(URLLoaderTest, ClientAuthNoCertificate) {
  net::EmbeddedTestServer test_server(net::EmbeddedTestServer::TYPE_HTTPS);
  net::SSLServerConfig ssl_config;
  ssl_config.client_cert_type =
      net::SSLServerConfig::ClientCertType::REQUIRE_CLIENT_CERT;

  // TLS 1.3 client auth errors show up post-handshake, resulting in a read
  // error which on Windows causes the socket to shutdown immediately before the
  // error is read.
  // TODO(crbug.com/41427061): Add support for testing this in TLS 1.3.
  ssl_config.version_max = net::SSL_PROTOCOL_VERSION_TLS1_2;

  test_server.SetSSLConfig(net::EmbeddedTestServer::CERT_OK, ssl_config);
  test_server.AddDefaultHandlers(
      base::FilePath(FILE_PATH_LITERAL("services/test/data")));
  ASSERT_TRUE(test_server.Start());

  ClientCertAndHttpAuthObserver client_cert_observer;
  client_cert_observer.set_certificate_response(
      ClientCertAndHttpAuthObserver::CertificateResponse::NULL_CERTIFICATE);

  ResourceRequest request =
      CreateResourceRequest("GET", test_server.GetURL("/defaultresponse"));
  base::RunLoop delete_run_loop;
  mojo::PendingRemote<mojom::URLLoader> loader;
  context().mutable_factory_params().process_id = kProcessId;
  context().mutable_factory_params().is_orb_enabled = false;
  URLLoaderOptions url_loader_options;
  url_loader_options.url_loader_network_observer = client_cert_observer.Bind();
  std::unique_ptr<URLLoader> url_loader = url_loader_options.MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.InitWithNewPipeAndPassReceiver(), request,
      client()->CreateRemote());

  client()->RunUntilComplete();

  EXPECT_EQ(1, client_cert_observer.on_certificate_requested_counter());
  EXPECT_EQ(net::ERR_BAD_SSL_CLIENT_AUTH_CERT,
            client()->completion_status().error_code);
}

TEST_F(URLLoaderTest, ClientAuthCertificateWithValidSignature) {
  std::unique_ptr<net::FakeClientCertIdentity> identity =
      net::FakeClientCertIdentity::CreateFromCertAndKeyFiles(
          net::GetTestCertsDirectory(), "client_1.pem", "client_1.pk8");
  ASSERT_TRUE(identity);
  scoped_refptr<TestSSLPrivateKey> private_key =
      base::MakeRefCounted<TestSSLPrivateKey>(identity->ssl_private_key());

  net::EmbeddedTestServer test_server(net::EmbeddedTestServer::TYPE_HTTPS);
  net::SSLServerConfig ssl_config;
  ssl_config.client_cert_type =
      net::SSLServerConfig::ClientCertType::REQUIRE_CLIENT_CERT;
  test_server.SetSSLConfig(net::EmbeddedTestServer::CERT_OK, ssl_config);
  test_server.AddDefaultHandlers(
      base::FilePath(FILE_PATH_LITERAL("services/test/data")));
  ASSERT_TRUE(test_server.Start());

  ClientCertAndHttpAuthObserver client_cert_observer;
  client_cert_observer.set_certificate_response(
      ClientCertAndHttpAuthObserver::CertificateResponse::
          VALID_CERTIFICATE_SIGNATURE);
  client_cert_observer.set_private_key(private_key);
  scoped_refptr<net::X509Certificate> certificate =
      test_server.GetCertificate();
  client_cert_observer.set_certificate(std::move(certificate));

  ResourceRequest request =
      CreateResourceRequest("GET", test_server.GetURL("/defaultresponse"));
  base::RunLoop delete_run_loop;
  mojo::PendingRemote<mojom::URLLoader> loader;
  context().mutable_factory_params().process_id = kProcessId;
  context().mutable_factory_params().is_orb_enabled = false;
  URLLoaderOptions url_loader_options;
  url_loader_options.url_loader_network_observer = client_cert_observer.Bind();
  std::unique_ptr<URLLoader> url_loader = url_loader_options.MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.InitWithNewPipeAndPassReceiver(), request,
      client()->CreateRemote());

  client()->RunUntilComplete();

  EXPECT_EQ(1, client_cert_observer.on_certificate_requested_counter());
  // The private key should have been used.
  EXPECT_EQ(1, private_key->sign_count());
}

TEST_F(URLLoaderTest, ClientAuthCertificateWithInvalidSignature) {
  std::unique_ptr<net::FakeClientCertIdentity> identity =
      net::FakeClientCertIdentity::CreateFromCertAndKeyFiles(
          net::GetTestCertsDirectory(), "client_1.pem", "client_1.pk8");
  ASSERT_TRUE(identity);
  scoped_refptr<TestSSLPrivateKey> private_key =
      base::MakeRefCounted<TestSSLPrivateKey>(identity->ssl_private_key());
  private_key->set_fail_signing(true);

  net::EmbeddedTestServer test_server(net::EmbeddedTestServer::TYPE_HTTPS);
  net::SSLServerConfig ssl_config;
  ssl_config.client_cert_type =
      net::SSLServerConfig::ClientCertType::REQUIRE_CLIENT_CERT;
  test_server.SetSSLConfig(net::EmbeddedTestServer::CERT_OK, ssl_config);
  test_server.AddDefaultHandlers(
      base::FilePath(FILE_PATH_LITERAL("services/test/data")));
  ASSERT_TRUE(test_server.Start());

  ClientCertAndHttpAuthObserver client_cert_observer;
  client_cert_observer.set_certificate_response(
      ClientCertAndHttpAuthObserver::CertificateResponse::
          VALID_CERTIFICATE_SIGNATURE);
  client_cert_observer.set_private_key(private_key);
  scoped_refptr<net::X509Certificate> certificate =
      test_server.GetCertificate();
  client_cert_observer.set_certificate(std::move(certificate));

  ResourceRequest request =
      CreateResourceRequest("GET", test_server.GetURL("/defaultresponse"));
  base::RunLoop delete_run_loop;
  mojo::PendingRemote<mojom::URLLoader> loader;
  context().mutable_factory_params().process_id = kProcessId;
  context().mutable_factory_params().is_orb_enabled = false;
  URLLoaderOptions url_loader_options;
  url_loader_options.url_loader_network_observer = client_cert_observer.Bind();
  std::unique_ptr<URLLoader> url_loader = url_loader_options.MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.InitWithNewPipeAndPassReceiver(), request,
      client()->CreateRemote());

  client()->RunUntilComplete();

  EXPECT_EQ(1, client_cert_observer.on_certificate_requested_counter());
  // The private key should have been used.
  EXPECT_EQ(1, private_key->sign_count());
  EXPECT_EQ(net::ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED,
            client()->completion_status().error_code);
}

TEST_F(URLLoaderTest, BlockAllCookies) {
  GURL first_party_url("http://www.example.com.test/");
  net::SiteForCookies site_for_cookies =
      net::SiteForCookies::FromUrl(first_party_url);
  GURL third_party_url("http://www.some.other.origin.test/");

  ResourceRequest request = CreateResourceRequest("GET", first_party_url);
  base::RunLoop delete_run_loop;
  mojo::PendingRemote<mojom::URLLoader> loader;
  context().mutable_factory_params().process_id = kProcessId;
  context().mutable_factory_params().is_orb_enabled = false;
  URLLoaderOptions url_loader_options;
  url_loader_options.options = mojom::kURLLoadOptionBlockAllCookies;
  std::unique_ptr<URLLoader> url_loader = url_loader_options.MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.InitWithNewPipeAndPassReceiver(), request,
      client()->CreateRemote());

  GURL cookie_url = test_server()->GetURL("/");
  auto cc = net::CanonicalCookie::CreateForTesting(
      cookie_url, "a=b", base::Time::Now(), net::CookieSourceType::kOther,
      std::nullopt /* server_time */,
      net::CookiePartitionKey::FromURLForTesting(
          GURL("https://toplevelsite.com")));

  EXPECT_FALSE(url_loader->AllowCookie(*cc, first_party_url, site_for_cookies));
  EXPECT_FALSE(url_loader->AllowFullCookies(first_party_url, site_for_cookies));
  EXPECT_FALSE(url_loader->AllowFullCookies(third_party_url, site_for_cookies));
}

TEST_F(URLLoaderTest, BlockOnlyThirdPartyCookies) {
  GURL first_party_url("http://www.example.com.test/");
  net::SiteForCookies site_for_cookies =
      net::SiteForCookies::FromUrl(first_party_url);
  GURL third_party_url("http://www.some.other.origin.test/");

  ResourceRequest request = CreateResourceRequest("GET", first_party_url);
  base::RunLoop delete_run_loop;
  mojo::PendingRemote<mojom::URLLoader> loader;
  context().mutable_factory_params().process_id = kProcessId;
  context().mutable_factory_params().is_orb_enabled = false;
  URLLoaderOptions url_loader_options;
  url_loader_options.options = mojom::kURLLoadOptionBlockThirdPartyCookies;
  std::unique_ptr<URLLoader> url_loader = url_loader_options.MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.InitWithNewPipeAndPassReceiver(), request,
      client()->CreateRemote());

  GURL cookie_url = test_server()->GetURL("/");
  auto cc = net::CanonicalCookie::CreateForTesting(
      cookie_url, "a=b", base::Time::Now(), net::CookieSourceType::kOther,
      std::nullopt /* server_time */,
      net::CookiePartitionKey::FromURLForTesting(
          GURL("https://toplevelsite.com")));

  EXPECT_TRUE(url_loader->AllowCookie(*cc, first_party_url, site_for_cookies));
  EXPECT_TRUE(url_loader->AllowFullCookies(first_party_url, site_for_cookies));
  EXPECT_FALSE(url_loader->AllowFullCookies(third_party_url, site_for_cookies));
}

TEST_F(URLLoaderTest, AllowAllCookies) {
  GURL first_party_url("http://www.example.com.test/");
  net::SiteForCookies site_for_cookies =
      net::SiteForCookies::FromUrl(first_party_url);
  GURL third_party_url("http://www.some.other.origin.test/");

  ResourceRequest request = CreateResourceRequest("GET", first_party_url);
  base::RunLoop delete_run_loop;
  mojo::PendingRemote<mojom::URLLoader> loader;
  context().mutable_factory_params().process_id = kProcessId;
  context().mutable_factory_params().is_orb_enabled = false;
  std::unique_ptr<URLLoader> url_loader = URLLoaderOptions().MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.InitWithNewPipeAndPassReceiver(), request,
      client()->CreateRemote());

  GURL cookie_url = test_server()->GetURL("/");
  auto cc = net::CanonicalCookie::CreateForTesting(
      cookie_url, "a=b", base::Time::Now(), net::CookieSourceType::kOther,
      std::nullopt /* server_time */,
      net::CookiePartitionKey::FromURLForTesting(
          GURL("https://toplevelsite.com")));

  EXPECT_TRUE(url_loader->AllowCookie(*cc, first_party_url, site_for_cookies));
  EXPECT_TRUE(url_loader->AllowFullCookies(first_party_url, site_for_cookies));
  EXPECT_TRUE(url_loader->AllowFullCookies(third_party_url, site_for_cookies));
}

class StorageAccessHeaderURLLoaderTest : public URLLoaderTest {
 public:
  StorageAccessHeaderURLLoaderTest() = default;

  void RegisterAdditionalHandlers() override {
    test_server_.RegisterRequestHandler(base::BindRepeating(
        &StorageAccessHeaderURLLoaderTest::HandleLoadWithStorageAccessRequest,
        base::Unretained(this)));
  }

 protected:
  static constexpr char kStorageAccessRedirectLoadPath[] =
      "/redirect-load-with-storage-access";

 private:
  std::unique_ptr<net::test_server::HttpResponse>
  HandleLoadWithStorageAccessRequest(
      const net::test_server::HttpRequest& request) {
    if (!base::StartsWith(request.GetURL().GetPath(),
                          kStorageAccessRedirectLoadPath)) {
      return nullptr;
    }
    std::string destination =
        base::UnescapeBinaryURLComponent(request.GetURL().query());
    auto http_response =
        std::make_unique<net::test_server::BasicHttpResponse>();
    http_response->set_content_type("text/plain");
    http_response->AddCustomHeader("Activate-Storage-Access", "load");
    http_response->set_code(net::HTTP_PERMANENT_REDIRECT);
    http_response->AddCustomHeader(
        "Location", destination.empty() ? "/empty.html" : destination);
    return http_response;
  }
};

// Validate that Sec-Fetch-Storage-Access header cannot be overridden by
// manually setting the value.
TEST_F(StorageAccessHeaderURLLoaderTest,
       DirectlyModifiedSecFetchStorageAccess) {
  ResourceRequest request =
      CreateResourceRequest("GET", test_server()->GetURL("/echo"));
  request.headers.SetHeader("Sec-Fetch-Storage-Access", "active");

  base::RunLoop delete_run_loop;
  mojo::PendingRemote<mojom::URLLoader> loader;
  std::unique_ptr<URLLoader> url_loader;
  context().mutable_factory_params().process_id =
      OriginatingProcessId::browser();
  url_loader = URLLoaderOptions().MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.InitWithNewPipeAndPassReceiver(), request,
      client()->CreateRemote());

  client()->RunUntilComplete();

  EXPECT_THAT(sent_request().headers,
              Not(Contains(Key("Sec-Fetch-Storage-Access"))));
}

TEST_F(StorageAccessHeaderURLLoaderTest, LoadNoStatus) {
  base::RunLoop delete_run_loop;
  ResourceRequest request = CreateResourceRequest(
      "GET", test_server_.GetURL("/set-header?Activate-Storage-Access: load"));

  test_network_delegate()->set_storage_access_status(std::nullopt);

  mojo::PendingRemote<mojom::URLLoader> loader;
  std::unique_ptr<URLLoader> url_loader;
  context().mutable_factory_params().process_id =
      OriginatingProcessId::browser();
  url_loader = URLLoaderOptions().MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.InitWithNewPipeAndPassReceiver(), request,
      client()->CreateRemote());

  client()->RunUntilComplete();
  delete_run_loop.Run();

  // TestNetworkDelegate always returns std::nullopt for the
  // GetStorageAccessStatus call, so the loader's `storage_access_status_` is
  // std::nullopt.
  EXPECT_FALSE(client()->response_head()->load_with_storage_access);
}

TEST_F(StorageAccessHeaderURLLoaderTest, LoadStatusNone) {
  base::RunLoop delete_run_loop;
  ResourceRequest request = CreateResourceRequest(
      "GET", test_server_.GetURL("/set-header?Activate-Storage-Access: load"));

  test_network_delegate()->set_storage_access_status(
      net::cookie_util::StorageAccessStatus::kNone);
  base::HistogramTester histogram_tester;

  mojo::PendingRemote<mojom::URLLoader> loader;
  std::unique_ptr<URLLoader> url_loader;
  context().mutable_factory_params().process_id =
      OriginatingProcessId::browser();
  url_loader = URLLoaderOptions().MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.InitWithNewPipeAndPassReceiver(), request,
      client()->CreateRemote());

  client()->RunUntilComplete();
  delete_run_loop.Run();

  EXPECT_FALSE(client()->response_head()->load_with_storage_access);
  histogram_tester.ExpectUniqueSample(
      "API.StorageAccessHeader.ActivateStorageAccessLoadOutcome",
      /*sample=*/
      net::cookie_util::ActivateStorageAccessLoadOutcome::kFailureInvalidStatus,
      /*expected_bucket_count=*/1);
}

TEST_F(StorageAccessHeaderURLLoaderTest, LoadStatusInactive) {
  base::RunLoop delete_run_loop;
  ResourceRequest request = CreateResourceRequest(
      "GET", test_server_.GetURL("/set-header?Activate-Storage-Access: load"));

  test_network_delegate()->set_storage_access_status(
      net::cookie_util::StorageAccessStatus::kInactive);

  mojo::PendingRemote<mojom::URLLoader> loader;
  std::unique_ptr<URLLoader> url_loader;
  context().mutable_factory_params().process_id =
      OriginatingProcessId::browser();
  url_loader = URLLoaderOptions().MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.InitWithNewPipeAndPassReceiver(), request,
      client()->CreateRemote());

  client()->RunUntilComplete();
  delete_run_loop.Run();

  EXPECT_TRUE(client()->response_head()->load_with_storage_access);
}

TEST_F(StorageAccessHeaderURLLoaderTest, LoadStatusActive) {
  base::RunLoop delete_run_loop;
  ResourceRequest request = CreateResourceRequest(
      "GET", test_server_.GetURL("/set-header?Activate-Storage-Access: load"));

  test_network_delegate()->set_storage_access_status(
      net::cookie_util::StorageAccessStatus::kActive);
  base::HistogramTester histogram_tester;

  mojo::PendingRemote<mojom::URLLoader> loader;
  std::unique_ptr<URLLoader> url_loader;
  context().mutable_factory_params().process_id =
      OriginatingProcessId::browser();
  url_loader = URLLoaderOptions().MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.InitWithNewPipeAndPassReceiver(), request,
      client()->CreateRemote());

  client()->RunUntilComplete();
  delete_run_loop.Run();

  EXPECT_TRUE(client()->response_head()->load_with_storage_access);
  histogram_tester.ExpectUniqueSample(
      "API.StorageAccessHeader.ActivateStorageAccessLoadOutcome",
      /*sample=*/net::cookie_util::ActivateStorageAccessLoadOutcome::kSuccess,
      /*expected_bucket_count=*/1);
}

TEST_F(StorageAccessHeaderURLLoaderTest, Load_StatusActive_IgnoredParam) {
  base::RunLoop delete_run_loop;
  ResourceRequest request = CreateResourceRequest(
      "GET",
      test_server_.GetURL("/set-header?Activate-Storage-Access: load;foo"));

  test_network_delegate()->set_storage_access_status(
      net::cookie_util::StorageAccessStatus::kActive);

  mojo::PendingRemote<mojom::URLLoader> loader;
  std::unique_ptr<URLLoader> url_loader;
  context().mutable_factory_params().process_id =
      OriginatingProcessId::browser();
  url_loader = URLLoaderOptions().MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.InitWithNewPipeAndPassReceiver(), request,
      client()->CreateRemote());

  client()->RunUntilComplete();
  delete_run_loop.Run();

  EXPECT_TRUE(client()->response_head()->load_with_storage_access);
}

TEST_F(StorageAccessHeaderURLLoaderTest, Load_StatusActive_IncorrectType) {
  base::RunLoop delete_run_loop;
  // This response will be a comma-separated list, rather than a single item, so
  // it's the wrong type and should be ignored.
  ResourceRequest request = CreateResourceRequest(
      "GET", test_server_.GetURL("/set-header?Activate-Storage-Access: "
                                 "load;bar&Activate-Storage-Access: load;foo"));

  test_network_delegate()->set_storage_access_status(
      net::cookie_util::StorageAccessStatus::kActive);

  mojo::PendingRemote<mojom::URLLoader> loader;
  std::unique_ptr<URLLoader> url_loader;
  context().mutable_factory_params().process_id =
      OriginatingProcessId::browser();
  url_loader = URLLoaderOptions().MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.InitWithNewPipeAndPassReceiver(), request,
      client()->CreateRemote());

  client()->RunUntilComplete();
  delete_run_loop.Run();

  EXPECT_FALSE(client()->response_head()->load_with_storage_access);
}

TEST_F(StorageAccessHeaderURLLoaderTest, RedirectWithLoad) {
  base::RunLoop delete_run_loop;
  ResourceRequest request = CreateResourceRequest(
      "GET", test_server_.GetURL(kStorageAccessRedirectLoadPath));

  test_network_delegate()->set_storage_access_status(
      net::cookie_util::StorageAccessStatus::kActive);

  mojo::PendingRemote<mojom::URLLoader> loader;
  std::unique_ptr<URLLoader> url_loader;
  context().mutable_factory_params().process_id =
      OriginatingProcessId::browser();
  url_loader = URLLoaderOptions().MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.InitWithNewPipeAndPassReceiver(), request,
      client()->CreateRemote());

  client()->RunUntilRedirectReceived();
  url_loader->FollowRedirect(/*headers_update_params=*/{},
                             /*new_url=*/std::nullopt);

  client()->RunUntilComplete();
  delete_run_loop.Run();

  // The redirect response included the `load` header, but the final response
  // did not, so the URLLoader should not propagate it.
  EXPECT_FALSE(client()->response_head()->load_with_storage_access);
}

// `URLLoader::ConfigureRequest` only calls
// `net::URLRequest::set_storage_access_status` if the request's credentials
// mode is `kInclude` but `URLLoader::ShouldSetLoadWithStorageAccess` calculates
// it anyway if the `Activate-Storage-Access: load` header is present. Once with
// the initial URL during `OnReceivedRedirect` and once more with the final URL
// during `FollowRedirect`. This test makes sure that the final response's
// `load_with_storage_access` is set properly when the request's credentials
// mode is NOT `kInclude` and a redirect is involved with `load` on both, but
// with different storage access status calculated for each request.
TEST_F(StorageAccessHeaderURLLoaderTest,
       OmitCredentials_RedirectWithLoadActive_DestinationLoadNone) {
  base::RunLoop delete_run_loop;

  GURL destination_url =
      test_server_.GetURL("/set-header?Activate-Storage-Access: load");
  ResourceRequest request = CreateResourceRequest(
      "GET", test_server_.GetURL(base::StrCat(
                 {kStorageAccessRedirectLoadPath, "?",
                  base::EscapeQueryParamValue(destination_url.spec(), true)})));
  request.credentials_mode = mojom::CredentialsMode::kOmit;

  test_network_delegate()->set_storage_access_status(
      net::cookie_util::StorageAccessStatus::kActive);

  mojo::PendingRemote<mojom::URLLoader> loader;
  std::unique_ptr<URLLoader> url_loader;
  context().mutable_factory_params().process_id =
      OriginatingProcessId::browser();
  url_loader = URLLoaderOptions().MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.InitWithNewPipeAndPassReceiver(), request,
      client()->CreateRemote());

  client()->RunUntilRedirectReceived();
  EXPECT_TRUE(client()->response_head()->load_with_storage_access);
  test_network_delegate()->set_storage_access_status(
      net::cookie_util::StorageAccessStatus::kNone);
  url_loader->FollowRedirect(/*headers_update_params=*/{},
                             /*new_url=*/std::nullopt);

  client()->RunUntilComplete();
  delete_run_loop.Run();

  EXPECT_FALSE(client()->response_head()->load_with_storage_access);
}

// `URLLoader::ConfigureRequest` only calls
// `net::URLRequest::set_storage_access_status` if the request's credentials
// mode is `kInclude` but `URLLoader::ShouldSetLoadWithStorageAccess` calculates
// it anyway if the `Activate-Storage-Access: load` header is present. Once with
// the initial URL during `OnReceivedRedirect` and once more with the final URL
// during `FollowRedirect`. This test makes sure that the final response's
// `load_with_storage_access` is set properly when the request's credentials
// mode is NOT `kInclude` and a redirect is involved with `load` on both, but
// with different storage access status calculated for each request.
TEST_F(StorageAccessHeaderURLLoaderTest,
       OmitCredentials_RedirectWithLoadNone_DestinationLoadActive) {
  base::RunLoop delete_run_loop;

  GURL destination_url =
      test_server_.GetURL("/set-header?Activate-Storage-Access: load");
  ResourceRequest request = CreateResourceRequest(
      "GET", test_server_.GetURL(base::StrCat(
                 {kStorageAccessRedirectLoadPath, "?",
                  base::EscapeQueryParamValue(destination_url.spec(), true)})));
  request.credentials_mode = mojom::CredentialsMode::kOmit;

  test_network_delegate()->set_storage_access_status(
      net::cookie_util::StorageAccessStatus::kNone);

  mojo::PendingRemote<mojom::URLLoader> loader;
  std::unique_ptr<URLLoader> url_loader;
  context().mutable_factory_params().process_id =
      OriginatingProcessId::browser();
  url_loader = URLLoaderOptions().MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.InitWithNewPipeAndPassReceiver(), request,
      client()->CreateRemote());

  client()->RunUntilRedirectReceived();
  EXPECT_FALSE(client()->response_head()->load_with_storage_access);
  test_network_delegate()->set_storage_access_status(
      net::cookie_util::StorageAccessStatus::kActive);
  url_loader->FollowRedirect(/*headers_update_params=*/{},
                             /*new_url=*/std::nullopt);

  client()->RunUntilComplete();
  delete_run_loop.Run();

  EXPECT_TRUE(client()->response_head()->load_with_storage_access);
}

class URLLoaderCookieSettingOverridesTest
    : public URLLoaderTest,
      public ::testing::WithParamInterface<
          std::tuple<bool, bool, net::StorageAccessApiStatus, std::string>> {
 public:
  URLLoaderCookieSettingOverridesTest() = default;

  ~URLLoaderCookieSettingOverridesTest() override = default;

  void SetUpRequest(ResourceRequest& request) {
    if (IsCors()) {
      request.mode = network::mojom::RequestMode::kCors;
    } else {
      // Request mode is `no-cors` by default.
      EXPECT_EQ(request.mode, network::mojom::RequestMode::kNoCors);
    }
    request.is_outermost_main_frame = IsOuterMostFrame();
    request.storage_access_api_status = StorageAccessApiStatus();
    request.request_initiator = Initiator();
    context().mutable_factory_params().is_outermost_main_frame =
        IsOuterMostFrame();
  }

  net::CookieSettingOverrides ExpectedCookieSettingOverrides(
      const ResourceRequest& request) const {
    net::CookieSettingOverrides overrides;
    if (IsCors() && IsOuterMostFrame()) {
      overrides.Put(
          net::CookieSettingOverride::kTopLevelStorageAccessGrantEligible);
    }
    switch (StorageAccessApiStatus()) {
      case net::StorageAccessApiStatus::kNone:
        break;
      case net::StorageAccessApiStatus::kAccessViaAPI:
        if (Initiator().IsSameOriginWith(request.url)) {
          overrides.Put(
              net::CookieSettingOverride::kStorageAccessGrantEligible);
        }
        break;
    }
    return overrides;
  }

  net::CookieSettingOverrides
  ExpectedCookieSettingOverridesForCrossOriginRedirect(
      const ResourceRequest& request) const {
    net::CookieSettingOverrides overrides =
        ExpectedCookieSettingOverrides(request);
    overrides.Remove(net::CookieSettingOverride::kStorageAccessGrantEligible);
    return overrides;
  }

  net::CookieSettingOverrides
  ExpectedCookieSettingOverridesForCrossSiteRedirect(
      const ResourceRequest& request) const {
    net::CookieSettingOverrides overrides =
        ExpectedCookieSettingOverrides(request);
    overrides.Remove(net::CookieSettingOverride::kStorageAccessGrantEligible);
    return overrides;
  }

 protected:
  bool IsCors() const { return std::get<0>(GetParam()); }
  bool IsOuterMostFrame() const { return std::get<1>(GetParam()); }
  net::StorageAccessApiStatus StorageAccessApiStatus() const {
    return std::get<2>(GetParam());
  }
  url::Origin Initiator() const {
    return url::Origin::Create(
        test_server()->GetURL(std::get<3>(GetParam()), "/"));
  }

 private:
  base::test::ScopedFeatureList features_;
};

// This test makes a request to an endpoint which does not redirect.
TEST_P(URLLoaderCookieSettingOverridesTest, NoRedirect) {
  const GURL url = test_server()->GetURL(kHostnameWithAliases, "/");

  ResourceRequest request = CreateResourceRequest("GET", url);
  SetUpRequest(request);

  EXPECT_EQ(LoadRequest(request), net::OK);

  EXPECT_THAT(test_network_delegate()->cookie_setting_overrides_records(),
              ElementsAre(ExpectedCookieSettingOverrides(request),
                          ExpectedCookieSettingOverrides(request)));
}

// This test makes a request to an endpoint that redirects to a cross-origin,
// same-site endpoint.
TEST_P(URLLoaderCookieSettingOverridesTest, CrossOriginSameSiteRedirect) {
  const GURL url = test_server()->GetURL(
      kHostnameWithAliases,
      "/server-redirect?" +
          test_server()->GetURL("example.test", "/simple_page.html").spec());

  ResourceRequest request = CreateResourceRequest("GET", url);
  SetUpRequest(request);

  set_expect_redirect();
  EXPECT_EQ(LoadRequest(request), net::OK);

  EXPECT_THAT(
      test_network_delegate()->cookie_setting_overrides_records(),
      ElementsAre(
          ExpectedCookieSettingOverrides(request),
          ExpectedCookieSettingOverrides(request),
          ExpectedCookieSettingOverridesForCrossOriginRedirect(request),
          ExpectedCookieSettingOverridesForCrossOriginRedirect(request)));
}

// This test makes a request to an endpoint which redirects to a cross-site
// endpoint.
TEST_P(URLLoaderCookieSettingOverridesTest, CrossSiteRedirect) {
  const GURL url = test_server()->GetURL(
      kHostnameWithAliases,
      "/server-redirect?" + test_server()->GetURL("other.test", "/").spec());

  ResourceRequest request = CreateResourceRequest("GET", url);
  SetUpRequest(request);

  set_expect_redirect();
  EXPECT_EQ(LoadRequest(request), net::OK);

  EXPECT_THAT(
      test_network_delegate()->cookie_setting_overrides_records(),
      ElementsAre(ExpectedCookieSettingOverrides(request),
                  ExpectedCookieSettingOverrides(request),
                  ExpectedCookieSettingOverridesForCrossSiteRedirect(request),
                  ExpectedCookieSettingOverridesForCrossSiteRedirect(request)));
}

// This test sends a request to an endpoint that is cross-site from the
// initiator, which redirects to an endpoint that is same-site (and same-origin)
// to the initiator. The second redirect leg should not have the
// `kStorageAccessGrantEligible` override, since that would include cookies on
// the request and therefore make a CSRF attack possible via that redirect.
TEST_P(URLLoaderCookieSettingOverridesTest, OnCrossSiteToSameSite) {
  if (!Initiator().DomainIs(kHostnameWithAliases)) {
    // This test sets its own request initiator below, so it effectively ignores
    // the `initiator()` test param. WLOG, we can skip all but one of the
    // instances of that param.
    GTEST_SKIP();
  }

  const GURL url = test_server()->GetURL(
      "cross-site.test",
      "/server-redirect?" +
          test_server()->GetURL(kHostnameWithAliases, "/empty.html").spec());

  ResourceRequest request = CreateResourceRequest("GET", url);
  SetUpRequest(request);
  request.request_initiator = test_server()->GetOrigin();

  set_expect_redirect();
  EXPECT_EQ(LoadRequest(request), net::OK);

  EXPECT_THAT(
      test_network_delegate()->cookie_setting_overrides_records(),
      ElementsAre(ExpectedCookieSettingOverridesForCrossSiteRedirect(request),
                  ExpectedCookieSettingOverridesForCrossSiteRedirect(request),
                  ExpectedCookieSettingOverridesForCrossSiteRedirect(request),
                  ExpectedCookieSettingOverridesForCrossSiteRedirect(request)));
}

TEST_F(URLLoaderTest, DevToolsCookieSettingOverrides_NotApplied) {
  GURL url("http://www.example.com.test/");
  base::RunLoop delete_run_loop;
  mojo::PendingRemote<mojom::URLLoader> loader;

  context().mutable_factory_params().process_id = kProcessId;
  // This override should only apply conditionally when devtools is enabled.
  context().mutable_factory_params().devtools_cookie_setting_overrides = {
      net::CookieSettingOverride::kForceDisableThirdPartyCookies};

  ResourceRequest request = CreateResourceRequest("GET", url);
  std::unique_ptr<URLLoader> url_loader = URLLoaderOptions().MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.InitWithNewPipeAndPassReceiver(), request,
      client()->CreateRemote());

  client()->RunUntilComplete();
  delete_run_loop.Run();

  const std::vector<net::CookieSettingOverrides> records =
      test_network_delegate()->cookie_setting_overrides_records();
  EXPECT_THAT(records, ElementsAre(net::CookieSettingOverrides(),
                                   net::CookieSettingOverrides()));
}

TEST_F(URLLoaderTest, DevToolsCookieSettingOverrides_Applied) {
  GURL url("http://www.example.com.test/");
  base::RunLoop delete_run_loop;
  mojo::PendingRemote<mojom::URLLoader> loader;

  net::CookieSettingOverrides devtools_overrides = {
      net::CookieSettingOverride::kForceDisableThirdPartyCookies};
  context().mutable_factory_params().process_id = kProcessId;
  // This override should only apply conditionally when devtools is enabled.
  context().mutable_factory_params().devtools_cookie_setting_overrides =
      devtools_overrides;

  ResourceRequest request = CreateResourceRequest("GET", url);
  // `devtools_request_id` is present, meaning devtools is enabled for this
  // request.
  request.devtools_request_id = "devtools_id";
  std::unique_ptr<URLLoader> url_loader = URLLoaderOptions().MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.InitWithNewPipeAndPassReceiver(), request,
      client()->CreateRemote());

  client()->RunUntilComplete();
  delete_run_loop.Run();

  const std::vector<net::CookieSettingOverrides> records =
      test_network_delegate()->cookie_setting_overrides_records();
  EXPECT_THAT(records, ElementsAre(devtools_overrides, devtools_overrides));
}

INSTANTIATE_TEST_SUITE_P(
    All,
    URLLoaderCookieSettingOverridesTest,
    testing::Combine(
        testing::Bool(),
        testing::Bool(),
        testing::Values(net::StorageAccessApiStatus::kNone,
                        net::StorageAccessApiStatus::kAccessViaAPI),
        testing::Values(
            // Same-origin initiator
            kHostnameWithAliases,
            // Same-site cross-origin initiator
            "example.test",
            // Cross-site initiator
            "other-origin.test")));

namespace {

enum class TestMode {
  kCredentialsModeOmit,
  kCredentialsModeOmitWorkaround,
  kCredentialsModeOmitWithFeatureFix,
};

}  // namespace

class URLLoaderParameterTest : public URLLoaderTest,
                               public ::testing::WithParamInterface<TestMode> {
 public:
  ~URLLoaderParameterTest() override = default;

 private:
  void SetUp() override {
    URLLoaderTest::SetUp();
    if (GetParam() == TestMode::kCredentialsModeOmitWithFeatureFix) {
      scoped_feature_list.InitAndEnableFeature(features::kOmitCorsClientCert);
    } else {
      scoped_feature_list.InitAndDisableFeature(features::kOmitCorsClientCert);
    }
  }
  base::test::ScopedFeatureList scoped_feature_list;
};

INSTANTIATE_TEST_SUITE_P(
    All,
    URLLoaderParameterTest,
    testing::Values(TestMode::kCredentialsModeOmit,
                    TestMode::kCredentialsModeOmitWorkaround,
                    TestMode::kCredentialsModeOmitWithFeatureFix));

TEST_F(URLLoaderTest, AcceptCHFrameNotAllowedHintWithFeature) {
  base::test::ScopedFeatureList feature_list;
  feature_list.InitAndEnableFeatureWithParameters(
      features::kOffloadAcceptCHFrameCheck,
      {{"AcceptCHFrameOffloadNotAllowedHints", "true"}});

  net::TransportInfo info = net::DefaultTransportInfo();
  info.accept_ch_frame = "Sec-CH-UA-Platform";

  const GURL url("http://accept-ch.test/");
  net::URLRequestFilter::GetInstance()->AddUrlInterceptor(
      url, std::make_unique<FakeTransportInfoInterceptor>(info));

  MockAcceptCHFrameObserver observer;
  set_accept_ch_frame_observer_for_next_request(&observer);

  network::ResourceRequest::TrustedParams::EnabledClientHints enabled_hints;
  enabled_hints.origin = url::Origin::Create(url);
  enabled_hints.is_outermost_main_frame = true;
  enabled_hints.hints = {network::mojom::WebClientHintsType::kUAArch};
  enabled_hints.not_allowed_hints = {
      network::mojom::WebClientHintsType::kUAPlatform};
  set_enabled_client_hints_for_next_request(std::move(enabled_hints));

  EXPECT_THAT(Load(url), IsOk());
  EXPECT_FALSE(observer.called());
}

TEST_F(URLLoaderTest, AcceptCHFrameNotAllowedHintWithoutFeature) {
  base::test::ScopedFeatureList feature_list;
  feature_list.InitAndEnableFeatureWithParameters(
      features::kOffloadAcceptCHFrameCheck,
      {{"AcceptCHFrameOffloadNotAllowedHints", "false"}});

  net::TransportInfo info = net::DefaultTransportInfo();
  info.accept_ch_frame = "Sec-CH-UA-Platform";

  const GURL url("http://accept-ch.test/");
  net::URLRequestFilter::GetInstance()->AddUrlInterceptor(
      url, std::make_unique<FakeTransportInfoInterceptor>(info));

  MockAcceptCHFrameObserver observer;
  set_accept_ch_frame_observer_for_next_request(&observer);

  network::ResourceRequest::TrustedParams::EnabledClientHints enabled_hints;
  enabled_hints.origin = url::Origin::Create(url);
  enabled_hints.is_outermost_main_frame = true;
  enabled_hints.hints = {network::mojom::WebClientHintsType::kUAArch};
  enabled_hints.not_allowed_hints = {
      network::mojom::WebClientHintsType::kUAPlatform};
  set_enabled_client_hints_for_next_request(std::move(enabled_hints));

  EXPECT_THAT(Load(url), IsOk());
  EXPECT_TRUE(observer.called());
  EXPECT_THAT(observer.accept_ch_frame(),
              ElementsAre(network::mojom::WebClientHintsType::kUAPlatform));
}

// Tests that a request with CredentialsMode::kOmit still sends client
// certificates when features::kOmitCorsClientCert is disabled, and when the
// feature is enabled client certificates are not sent. Also test that when
// CredentialsMode::kOmitBug_775438_Workaround is used client certificates are
// not sent as well. This should be removed when crbug.com/775438 is fixed.
TEST_P(URLLoaderParameterTest, CredentialsModeOmitRequireClientCert) {
  // Set up a server that requires certificates.
  net::SSLServerConfig ssl_config;
  ssl_config.client_cert_type =
      net::SSLServerConfig::ClientCertType::REQUIRE_CLIENT_CERT;
  net::EmbeddedTestServer test_server(net::EmbeddedTestServer::TYPE_HTTPS);
  test_server.SetSSLConfig(net::EmbeddedTestServer::CERT_OK, ssl_config);
  test_server.AddDefaultHandlers(
      base::FilePath(FILE_PATH_LITERAL("services/test/data")));
  ASSERT_TRUE(test_server.Start());

  // Make sure the client has valid certificates.
  std::unique_ptr<net::FakeClientCertIdentity> identity =
      net::FakeClientCertIdentity::CreateFromCertAndKeyFiles(
          net::GetTestCertsDirectory(), "client_1.pem", "client_1.pk8");
  ASSERT_TRUE(identity);
  scoped_refptr<TestSSLPrivateKey> private_key =
      base::MakeRefCounted<TestSSLPrivateKey>(identity->ssl_private_key());

  ClientCertAndHttpAuthObserver client_cert_observer;
  client_cert_observer.set_certificate_response(
      ClientCertAndHttpAuthObserver::CertificateResponse::
          VALID_CERTIFICATE_SIGNATURE);
  client_cert_observer.set_private_key(private_key);
  client_cert_observer.set_certificate(identity->certificate());

  ResourceRequest request =
      CreateResourceRequest("GET", test_server.GetURL("/simple_page.html"));
  if (GetParam() == TestMode::kCredentialsModeOmitWorkaround) {
    request.credentials_mode =
        mojom::CredentialsMode::kOmitBug_775438_Workaround;
  } else {
    request.credentials_mode = mojom::CredentialsMode::kOmit;
  }

  base::RunLoop delete_run_loop;
  mojo::Remote<mojom::URLLoader> loader;
  std::unique_ptr<URLLoader> url_loader;
  context().mutable_factory_params().process_id = kProcessId;
  context().mutable_factory_params().is_orb_enabled = false;
  URLLoaderOptions url_loader_options;
  url_loader_options.url_loader_network_observer = client_cert_observer.Bind();
  url_loader = url_loader_options.MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.BindNewPipeAndPassReceiver(), request, client()->CreateRemote());

  client()->RunUntilComplete();
  delete_run_loop.Run();
  if (GetParam() == TestMode::kCredentialsModeOmitWithFeatureFix ||
      GetParam() == TestMode::kCredentialsModeOmitWorkaround) {
    EXPECT_EQ(0, client_cert_observer.on_certificate_requested_counter());
    EXPECT_NE(net::OK, client()->completion_status().error_code);
  } else {
    EXPECT_EQ(1, client_cert_observer.on_certificate_requested_counter());
    EXPECT_EQ(net::OK, client()->completion_status().error_code);
  }
}

// Tests that a request with CredentialsMode::kOmitBug_775438_Workaround, and
// CredentialsMode::kOmit when features::kOmitCorsClientCert is enabled doesn't
// send client certificates with a server that optionally requires certificates.
TEST_P(URLLoaderParameterTest, CredentialsModeOmitOptionalClientCert) {
  // Set up a server that requires certificates.
  net::SSLServerConfig ssl_config;
  ssl_config.client_cert_type =
      net::SSLServerConfig::ClientCertType::OPTIONAL_CLIENT_CERT;
  net::EmbeddedTestServer test_server(net::EmbeddedTestServer::TYPE_HTTPS);
  test_server.SetSSLConfig(net::EmbeddedTestServer::CERT_OK, ssl_config);
  test_server.AddDefaultHandlers(
      base::FilePath(FILE_PATH_LITERAL("services/test/data")));
  ASSERT_TRUE(test_server.Start());

  // Make sure the client has valid certificates.
  std::unique_ptr<net::FakeClientCertIdentity> identity =
      net::FakeClientCertIdentity::CreateFromCertAndKeyFiles(
          net::GetTestCertsDirectory(), "client_1.pem", "client_1.pk8");
  ASSERT_TRUE(identity);
  scoped_refptr<TestSSLPrivateKey> private_key =
      base::MakeRefCounted<TestSSLPrivateKey>(identity->ssl_private_key());

  ClientCertAndHttpAuthObserver client_cert_observer;
  client_cert_observer.set_certificate_response(
      ClientCertAndHttpAuthObserver::CertificateResponse::
          VALID_CERTIFICATE_SIGNATURE);
  client_cert_observer.set_private_key(private_key);
  client_cert_observer.set_certificate(identity->certificate());

  ResourceRequest request =
      CreateResourceRequest("GET", test_server.GetURL("/simple_page.html"));
  if (GetParam() == TestMode::kCredentialsModeOmitWorkaround) {
    request.credentials_mode =
        mojom::CredentialsMode::kOmitBug_775438_Workaround;
  } else {
    request.credentials_mode = mojom::CredentialsMode::kOmit;
  }

  base::RunLoop delete_run_loop;
  mojo::Remote<mojom::URLLoader> loader;
  std::unique_ptr<URLLoader> url_loader;
  context().mutable_factory_params().process_id = kProcessId;
  context().mutable_factory_params().is_orb_enabled = false;
  URLLoaderOptions url_loader_options;
  url_loader_options.url_loader_network_observer = client_cert_observer.Bind();
  url_loader = url_loader_options.MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.BindNewPipeAndPassReceiver(), request, client()->CreateRemote());

  client()->RunUntilComplete();
  delete_run_loop.Run();
  if (GetParam() == TestMode::kCredentialsModeOmitWithFeatureFix ||
      GetParam() == TestMode::kCredentialsModeOmitWorkaround) {
    EXPECT_EQ(0, client_cert_observer.on_certificate_requested_counter());
  } else {
    EXPECT_EQ(1, client_cert_observer.on_certificate_requested_counter());
  }
  EXPECT_EQ(net::OK, client()->completion_status().error_code);
}

#endif  // !BUILDFLAG(IS_IOS)

TEST_F(URLLoaderTest, CookieReporting) {
  {
    TestURLLoaderClient loader_client;
    ResourceRequest request =
        CreateResourceRequest("GET", test_server()->GetURL("/set-cookie?a=b"));

    MockCookieObserver cookie_observer;
    base::RunLoop delete_run_loop;
    mojo::PendingRemote<mojom::URLLoader> loader;
    context().mutable_factory_params().process_id = kProcessId;
    context().mutable_factory_params().is_orb_enabled = false;
    URLLoaderOptions url_loader_options;
    url_loader_options.cookie_observer = cookie_observer.GetRemote();
    std::unique_ptr<URLLoader> url_loader = url_loader_options.MakeURLLoader(
        context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
        loader.InitWithNewPipeAndPassReceiver(), request,
        loader_client.CreateRemote());

    delete_run_loop.Run();
    loader_client.RunUntilComplete();
    EXPECT_EQ(net::OK, loader_client.completion_status().error_code);

    cookie_observer.WaitForCookies(1u);
    EXPECT_THAT(
        cookie_observer.observed_cookies(),
        testing::ElementsAre(MatchesCookieDetails(
            CookieAccessType::kChange,
            CookieOrLine("a=b", mojom::CookieOrLine::Tag::kCookie), true)));
  }

  {
    TestURLLoaderClient loader_client;
    ResourceRequest request =
        CreateResourceRequest("GET", test_server()->GetURL("/nocontent"));

    MockCookieObserver cookie_observer;
    base::RunLoop delete_run_loop;
    mojo::PendingRemote<mojom::URLLoader> loader;
    context().mutable_factory_params().process_id = kProcessId;
    context().mutable_factory_params().is_orb_enabled = false;

    URLLoaderOptions url_loader_options;
    url_loader_options.cookie_observer = cookie_observer.GetRemote();
    std::unique_ptr<URLLoader> url_loader = url_loader_options.MakeURLLoader(
        context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
        loader.InitWithNewPipeAndPassReceiver(), request,
        loader_client.CreateRemote());

    delete_run_loop.Run();
    loader_client.RunUntilComplete();
    EXPECT_EQ(net::OK, loader_client.completion_status().error_code);

    cookie_observer.WaitForCookies(1u);
    EXPECT_THAT(
        cookie_observer.observed_cookies(),
        testing::ElementsAre(MatchesCookieDetails(
            CookieAccessType::kRead,
            CookieOrLine("a=b", mojom::CookieOrLine::Tag::kCookie), true)));
  }
}

TEST_F(URLLoaderTest, CookieReportingRedirect) {
  MockCookieObserver cookie_observer(CookieAccessType::kChange);

  GURL dest_url = test_server()->GetURL("/nocontent");
  GURL redirecting_url =
      test_server()->GetURL("/server-redirect-with-cookie?" + dest_url.spec());

  TestURLLoaderClient loader_client;
  ResourceRequest request = CreateResourceRequest("GET", redirecting_url);

  base::RunLoop delete_run_loop;
  mojo::Remote<mojom::URLLoader> loader;
  context().mutable_factory_params().process_id = kProcessId;
  context().mutable_factory_params().is_orb_enabled = false;
  URLLoaderOptions url_loader_options;
  url_loader_options.cookie_observer = cookie_observer.GetRemote();
  std::unique_ptr<URLLoader> url_loader = url_loader_options.MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.BindNewPipeAndPassReceiver(), request,
      loader_client.CreateRemote());

  loader_client.RunUntilRedirectReceived();
  loader->FollowRedirect(/*headers_update_params=*/{},
                         /*new_url=*/std::nullopt);
  loader_client.RunUntilComplete();
  delete_run_loop.Run();
  EXPECT_EQ(net::OK, loader_client.completion_status().error_code);

  cookie_observer.WaitForCookies(1u);
  EXPECT_THAT(cookie_observer.observed_cookies(),
              testing::ElementsAre(MatchesCookieDetails(
                  CookieAccessType::kChange,
                  CookieOrLine("server-redirect=true",
                               mojom::CookieOrLine::Tag::kCookie),
                  true)));
  // Make sure that this has the pre-redirect URL, not the post-redirect one.
  EXPECT_EQ(redirecting_url, cookie_observer.observed_cookies()[0].url);
}

TEST_F(URLLoaderTest, CookieReportingAuth) {
  for (auto mode :
       {ClientCertAndHttpAuthObserver::CredentialsResponse::NO_CREDENTIALS,
        ClientCertAndHttpAuthObserver::CredentialsResponse::
            CORRECT_CREDENTIALS}) {
    MockCookieObserver cookie_observer(CookieAccessType::kChange);
    ClientCertAndHttpAuthObserver client_auth_observer;
    client_auth_observer.set_credentials_response(mode);

    GURL url = test_server()->GetURL(
        "/auth-basic?set-cookie-if-challenged&password=PASS");
    TestURLLoaderClient loader_client;
    ResourceRequest request = CreateResourceRequest("GET", url);

    base::RunLoop delete_run_loop;
    mojo::PendingRemote<mojom::URLLoader> loader;
    context().mutable_factory_params().process_id = kProcessId;
    context().mutable_factory_params().is_orb_enabled = false;
    URLLoaderOptions url_loader_options;
    url_loader_options.cookie_observer = cookie_observer.GetRemote();
    url_loader_options.url_loader_network_observer =
        client_auth_observer.Bind();
    std::unique_ptr<URLLoader> url_loader = url_loader_options.MakeURLLoader(
        context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
        loader.InitWithNewPipeAndPassReceiver(), request,
        loader_client.CreateRemote());

    loader_client.RunUntilComplete();
    delete_run_loop.Run();
    EXPECT_EQ(net::OK, loader_client.completion_status().error_code);

    cookie_observer.WaitForCookies(1u);
    EXPECT_THAT(cookie_observer.observed_cookies(),
                testing::ElementsAre(MatchesCookieDetails(
                    CookieAccessType::kChange,
                    CookieOrLine("got_challenged=true",
                                 mojom::CookieOrLine::Tag::kCookie),
                    true)));
  }
}

TEST_F(URLLoaderTest, RawRequestCookies) {
  {
    MockDevToolsObserver devtools_observer;
    TestURLLoaderClient loader_client;
    ResourceRequest request = CreateResourceRequest(
        "GET", test_server()->GetURL("/echoheader?cookie"));
    // Set the devtools id to trigger the RawResponse call
    request.devtools_request_id = "TEST";

    GURL cookie_url = test_server()->GetURL("/");
    auto cookie = net::CanonicalCookie::CreateForTesting(
        cookie_url, "a=b", base::Time::Now(), net::CookieSourceType::kOther);
    url_request_context()->cookie_store()->SetCanonicalCookieAsync(
        std::move(cookie), cookie_url, net::CookieOptions::MakeAllInclusive(),
        base::DoNothing(), /*cookie_access_result=*/std::nullopt);

    base::RunLoop delete_run_loop;
    mojo::PendingRemote<mojom::URLLoader> loader;
    context().mutable_factory_params().process_id = kProcessId;
    context().mutable_factory_params().is_orb_enabled = false;
    URLLoaderOptions url_loader_options;
    url_loader_options.devtools_observer = devtools_observer.Bind();
    std::unique_ptr<URLLoader> url_loader = url_loader_options.MakeURLLoader(
        context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
        loader.InitWithNewPipeAndPassReceiver(), request,
        loader_client.CreateRemote());

    delete_run_loop.Run();
    loader_client.RunUntilComplete();
    EXPECT_EQ(net::OK, loader_client.completion_status().error_code);

    devtools_observer.WaitUntilRawRequest(1u);
    EXPECT_EQ(200, devtools_observer.raw_response_http_status_code());
    EXPECT_EQ("a", devtools_observer.raw_request_cookies()[0].cookie.Name());
    EXPECT_EQ("b", devtools_observer.raw_request_cookies()[0].cookie.Value());
    EXPECT_TRUE(devtools_observer.raw_request_cookies()[0]
                    .access_result.status.IsInclude());

    EXPECT_EQ("TEST", devtools_observer.devtools_request_id());
  }
}

TEST_F(URLLoaderTest, RawRequestCookiesFlagged) {
  {
    MockDevToolsObserver devtools_observer;
    TestURLLoaderClient loader_client;
    ResourceRequest request = CreateResourceRequest(
        "GET", test_server()->GetURL("/echoheader?cookie"));
    // Set the devtools id to trigger the RawResponse call
    request.devtools_request_id = "TEST";

    // Set the path to an irrelevant url to block the cookie from sending
    GURL cookie_url = test_server()->GetURL("/");
    auto cookie = net::CanonicalCookie::CreateForTesting(
        cookie_url, "a=b;Path=/something-else", base::Time::Now(),
        net::CookieSourceType::kOther);
    url_request_context()->cookie_store()->SetCanonicalCookieAsync(
        std::move(cookie), cookie_url, net::CookieOptions::MakeAllInclusive(),
        base::DoNothing(), /*cookie_access_result=*/std::nullopt);

    base::RunLoop delete_run_loop;
    mojo::PendingRemote<mojom::URLLoader> loader;
    context().mutable_factory_params().process_id = kProcessId;
    context().mutable_factory_params().is_orb_enabled = false;
    URLLoaderOptions url_loader_options;
    url_loader_options.devtools_observer = devtools_observer.Bind();
    std::unique_ptr<URLLoader> url_loader = url_loader_options.MakeURLLoader(
        context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
        loader.InitWithNewPipeAndPassReceiver(), request,
        loader_client.CreateRemote());

    delete_run_loop.Run();
    loader_client.RunUntilComplete();
    EXPECT_EQ(net::OK, loader_client.completion_status().error_code);

    devtools_observer.WaitUntilRawRequest(1u);
    EXPECT_EQ(200, devtools_observer.raw_response_http_status_code());
    EXPECT_EQ("a", devtools_observer.raw_request_cookies()[0].cookie.Name());
    EXPECT_EQ("b", devtools_observer.raw_request_cookies()[0].cookie.Value());
    EXPECT_TRUE(devtools_observer.raw_request_cookies()[0]
                    .access_result.status.HasExactlyExclusionReasonsForTesting(
                        {net::CookieInclusionStatus::ExclusionReason::
                             EXCLUDE_NOT_ON_PATH}));

    EXPECT_EQ("TEST", devtools_observer.devtools_request_id());
  }
}

TEST_F(URLLoaderTest, RawResponseCookies) {
  {
    MockDevToolsObserver devtools_observer;
    TestURLLoaderClient loader_client;
    ResourceRequest request =
        CreateResourceRequest("GET", test_server()->GetURL("/set-cookie?a=b"));
    // Set the devtools id to trigger the RawResponse call
    request.devtools_request_id = "TEST";

    base::RunLoop delete_run_loop;
    mojo::PendingRemote<mojom::URLLoader> loader;
    context().mutable_factory_params().process_id = kProcessId;
    context().mutable_factory_params().is_orb_enabled = false;
    URLLoaderOptions url_loader_options;
    url_loader_options.devtools_observer = devtools_observer.Bind();
    std::unique_ptr<URLLoader> url_loader = url_loader_options.MakeURLLoader(
        context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
        loader.InitWithNewPipeAndPassReceiver(), request,
        loader_client.CreateRemote());

    delete_run_loop.Run();
    loader_client.RunUntilComplete();
    EXPECT_EQ(net::OK, loader_client.completion_status().error_code);

    devtools_observer.WaitUntilRawResponse(1u);
    EXPECT_EQ(200, devtools_observer.raw_response_http_status_code());
    EXPECT_EQ("a", devtools_observer.raw_response_cookies()[0].cookie->Name());
    EXPECT_EQ("b", devtools_observer.raw_response_cookies()[0].cookie->Value());
    EXPECT_TRUE(devtools_observer.raw_response_cookies()[0]
                    .access_result.status.IsInclude());

    EXPECT_EQ("TEST", devtools_observer.devtools_request_id());

    ASSERT_TRUE(devtools_observer.raw_response_headers());
    EXPECT_NE(devtools_observer.raw_response_headers()->find("Set-Cookie: a=b"),
              std::string::npos);
  }
}

TEST_F(URLLoaderTest, RawResponseCookiesInvalid) {
  {
    MockDevToolsObserver devtools_observer;
    TestURLLoaderClient loader_client;
    ResourceRequest request = CreateResourceRequest(
        "GET", test_server()->GetURL("/set-invalid-cookie"));
    // Set the devtools id to trigger the RawResponse call
    request.devtools_request_id = "TEST";

    base::RunLoop delete_run_loop;
    mojo::PendingRemote<mojom::URLLoader> loader;
    context().mutable_factory_params().process_id = kProcessId;
    context().mutable_factory_params().is_orb_enabled = false;
    URLLoaderOptions url_loader_options;
    url_loader_options.devtools_observer = devtools_observer.Bind();
    std::unique_ptr<URLLoader> url_loader = url_loader_options.MakeURLLoader(
        context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
        loader.InitWithNewPipeAndPassReceiver(), request,
        loader_client.CreateRemote());

    delete_run_loop.Run();
    loader_client.RunUntilComplete();
    EXPECT_EQ(net::OK, loader_client.completion_status().error_code);

    devtools_observer.WaitUntilRawResponse(1u);
    EXPECT_EQ(200, devtools_observer.raw_response_http_status_code());
    // On these failures the cookie object is not created
    EXPECT_FALSE(devtools_observer.raw_response_cookies()[0].cookie);
    EXPECT_TRUE(devtools_observer.raw_response_cookies()[0]
                    .access_result.status.HasExactlyExclusionReasonsForTesting(
                        {net::CookieInclusionStatus::ExclusionReason::
                             EXCLUDE_DISALLOWED_CHARACTER}));

    EXPECT_EQ("TEST", devtools_observer.devtools_request_id());
  }
}

TEST_F(URLLoaderTest, RawResponseCookiesRedirect) {
  // Check a valid cookie
  {
    MockDevToolsObserver devtools_observer;
    GURL dest_url = test_server()->GetURL("a.test", "/nocontent");
    GURL redirecting_url = test_server()->GetURL(
        "a.test", "/server-redirect-with-cookie?" + dest_url.spec());

    TestURLLoaderClient loader_client;
    ResourceRequest request = CreateResourceRequest("GET", redirecting_url);
    // Set the devtools id to trigger the RawResponse call
    request.devtools_request_id = "TEST";

    base::RunLoop delete_run_loop;
    mojo::Remote<mojom::URLLoader> loader;
    context().mutable_factory_params().process_id = kProcessId;
    context().mutable_factory_params().is_orb_enabled = false;

    URLLoaderOptions url_loader_options;
    url_loader_options.devtools_observer = devtools_observer.Bind();
    std::unique_ptr<URLLoader> url_loader = url_loader_options.MakeURLLoader(
        context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
        loader.BindNewPipeAndPassReceiver(), request,
        loader_client.CreateRemote());

    loader_client.RunUntilRedirectReceived();
    devtools_observer.WaitUntilRawResponse(1u);

    ASSERT_TRUE(devtools_observer.raw_response_headers());
    EXPECT_NE(devtools_observer.raw_response_headers()->find(
                  "Set-Cookie: server-redirect=true"),
              std::string::npos);

    loader->FollowRedirect(/*headers_update_params=*/{},
                           /*new_url=*/std::nullopt);
    loader_client.RunUntilComplete();
    delete_run_loop.Run();
    EXPECT_EQ(net::OK, loader_client.completion_status().error_code);

    devtools_observer.WaitUntilRawResponse(1u);
    EXPECT_EQ(204, devtools_observer.raw_response_http_status_code());
    EXPECT_EQ("server-redirect",
              devtools_observer.raw_response_cookies()[0].cookie->Name());
    EXPECT_EQ("true",
              devtools_observer.raw_response_cookies()[0].cookie->Value());
    EXPECT_TRUE(devtools_observer.raw_response_cookies()[0]
                    .access_result.status.IsInclude());

    EXPECT_EQ("TEST", devtools_observer.devtools_request_id());
  }

  // Check a flagged cookie (secure cookie over an insecure connection)
  {
    GURL dest_url = test_server()->GetURL("a.test", "/nocontent");
    GURL redirecting_url = test_server()->GetURL(
        "a.test", "/server-redirect-with-secure-cookie?" + dest_url.spec());

    MockDevToolsObserver devtools_observer;
    TestURLLoaderClient loader_client;
    ResourceRequest request = CreateResourceRequest("GET", redirecting_url);
    // Set the devtools id to trigger the RawResponse call
    request.devtools_request_id = "TEST";

    base::RunLoop delete_run_loop;
    mojo::Remote<mojom::URLLoader> loader;
    context().mutable_factory_params().process_id = kProcessId;
    context().mutable_factory_params().is_orb_enabled = false;
    URLLoaderOptions url_loader_options;
    url_loader_options.devtools_observer = devtools_observer.Bind();
    std::unique_ptr<URLLoader> url_loader = url_loader_options.MakeURLLoader(
        context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
        loader.BindNewPipeAndPassReceiver(), request,
        loader_client.CreateRemote());

    loader_client.RunUntilRedirectReceived();
    loader->FollowRedirect(/*headers_update_params=*/{},
                           /*new_url=*/std::nullopt);
    loader_client.RunUntilComplete();
    delete_run_loop.Run();
    EXPECT_EQ(net::OK, loader_client.completion_status().error_code);

    devtools_observer.WaitUntilRawResponse(1u);
    EXPECT_EQ(204, devtools_observer.raw_response_http_status_code());
    // On these failures the cookie object is created but not included.
    EXPECT_TRUE(
        devtools_observer.raw_response_cookies()[0].cookie->SecureAttribute());
    EXPECT_TRUE(devtools_observer.raw_response_cookies()[0]
                    .access_result.status.HasExactlyExclusionReasonsForTesting(
                        {net::CookieInclusionStatus::ExclusionReason::
                             EXCLUDE_SECURE_ONLY}));
  }
}

TEST_F(URLLoaderTest, RawResponseCookiesAuth) {
  // Check a valid cookie
  {
    MockDevToolsObserver devtools_observer;
    ClientCertAndHttpAuthObserver client_auth_observer;
    client_auth_observer.set_credentials_response(
        ClientCertAndHttpAuthObserver::CredentialsResponse::NO_CREDENTIALS);

    GURL url = test_server()->GetURL(
        "a.test", "/auth-basic?set-cookie-if-challenged&password=PASS");
    TestURLLoaderClient loader_client;
    ResourceRequest request = CreateResourceRequest("GET", url);
    // Set the devtools id to trigger the RawResponse call
    request.devtools_request_id = "TEST";

    base::RunLoop delete_run_loop;
    mojo::PendingRemote<mojom::URLLoader> loader;
    context().mutable_factory_params().process_id = kProcessId;
    context().mutable_factory_params().is_orb_enabled = false;
    URLLoaderOptions url_loader_options;
    url_loader_options.devtools_observer = devtools_observer.Bind();
    std::unique_ptr<URLLoader> url_loader = url_loader_options.MakeURLLoader(
        context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
        loader.InitWithNewPipeAndPassReceiver(), request,
        loader_client.CreateRemote());

    loader_client.RunUntilComplete();
    delete_run_loop.Run();
    EXPECT_EQ(net::OK, loader_client.completion_status().error_code);

    devtools_observer.WaitUntilRawResponse(1u);
    EXPECT_EQ(401, devtools_observer.raw_response_http_status_code());
    EXPECT_EQ("got_challenged",
              devtools_observer.raw_response_cookies()[0].cookie->Name());
    EXPECT_EQ("true",
              devtools_observer.raw_response_cookies()[0].cookie->Value());
    EXPECT_TRUE(devtools_observer.raw_response_cookies()[0]
                    .access_result.status.IsInclude());

    EXPECT_EQ("TEST", devtools_observer.devtools_request_id());
  }

  // Check a flagged cookie (secure cookie from insecure connection)
  {
    MockDevToolsObserver devtools_observer;
    ClientCertAndHttpAuthObserver client_auth_observer;
    client_auth_observer.set_credentials_response(
        ClientCertAndHttpAuthObserver::CredentialsResponse::NO_CREDENTIALS);

    GURL url = test_server()->GetURL(
        "a.test", "/auth-basic?set-secure-cookie-if-challenged&password=PASS");
    TestURLLoaderClient loader_client;
    ResourceRequest request = CreateResourceRequest("GET", url);
    // Set the devtools id to trigger the RawResponse call
    request.devtools_request_id = "TEST";

    base::RunLoop delete_run_loop;
    mojo::PendingRemote<mojom::URLLoader> loader;
    context().mutable_factory_params().process_id = kProcessId;
    context().mutable_factory_params().is_orb_enabled = false;
    URLLoaderOptions url_loader_options;
    url_loader_options.devtools_observer = devtools_observer.Bind();
    std::unique_ptr<URLLoader> url_loader = url_loader_options.MakeURLLoader(
        context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
        loader.InitWithNewPipeAndPassReceiver(), request,
        loader_client.CreateRemote());

    loader_client.RunUntilComplete();
    delete_run_loop.Run();
    EXPECT_EQ(net::OK, loader_client.completion_status().error_code);
    EXPECT_EQ(401, devtools_observer.raw_response_http_status_code());
    devtools_observer.WaitUntilRawResponse(1u);
    // On these failures the cookie object is created but not included.
    EXPECT_TRUE(
        devtools_observer.raw_response_cookies()[0].cookie->SecureAttribute());
    EXPECT_TRUE(devtools_observer.raw_response_cookies()[0]
                    .access_result.status.HasExactlyExclusionReasonsForTesting(
                        {net::CookieInclusionStatus::ExclusionReason::
                             EXCLUDE_SECURE_ONLY}));

    EXPECT_EQ("TEST", devtools_observer.devtools_request_id());
  }
}

TEST_F(URLLoaderTest, RawResponseQUIC) {
  {
    MockDevToolsObserver devtools_observer;
    TestURLLoaderClient loader_client;
    ResourceRequest request =
        CreateResourceRequest("GET", net::QuicSimpleTestServer::GetFileURL(""));

    // Set the devtools id to trigger the RawResponse call
    request.devtools_request_id = "TEST";

    base::RunLoop delete_run_loop;
    mojo::PendingRemote<mojom::URLLoader> loader;
    context().mutable_factory_params().process_id = kProcessId;
    context().mutable_factory_params().is_orb_enabled = false;
    URLLoaderOptions url_loader_options;
    url_loader_options.devtools_observer = devtools_observer.Bind();
    std::unique_ptr<URLLoader> url_loader = url_loader_options.MakeURLLoader(
        context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
        loader.InitWithNewPipeAndPassReceiver(), request,
        loader_client.CreateRemote());

    delete_run_loop.Run();
    loader_client.RunUntilComplete();
    ASSERT_EQ(net::OK, loader_client.completion_status().error_code);

    devtools_observer.WaitUntilRawResponse(0u);
    EXPECT_EQ(404, devtools_observer.raw_response_http_status_code());
    EXPECT_EQ("TEST", devtools_observer.devtools_request_id());

    // QUIC responses don't have raw header text, so there shouldn't be any here
    EXPECT_FALSE(devtools_observer.raw_response_headers());
  }
}

TEST_F(URLLoaderTest, EarlyHints) {
  const std::string kPath = "/hinted";
  const std::string kResponseBody = "content with hints";
  const std::string kPreloadPath = "/hello.txt";

  // Prepare a response with an Early Hints response.
  quiche::HttpHeaderBlock response_headers;
  response_headers[":status"] = "200";
  response_headers[":path"] = kPath;
  std::vector<quiche::HttpHeaderBlock> early_hints;
  quiche::HttpHeaderBlock hints_headers;
  std::string preload_link =
      base::StringPrintf("<%s>; rel=preload", kPreloadPath.c_str());
  hints_headers["link"] = preload_link;

  early_hints.push_back(std::move(hints_headers));
  net::QuicSimpleTestServer::AddResponseWithEarlyHints(
      kPath, response_headers, kResponseBody, early_hints);

  MockDevToolsObserver devtools_observer;
  URLLoaderOptions url_loader_options;
  url_loader_options.devtools_observer = devtools_observer.Bind();

  // Create a loader and a client to request `kPath`. The client should receive
  // an Early Hints which contains a preload link header.
  TestURLLoaderClient loader_client;
  ResourceRequest request = CreateResourceRequest(
      "GET", net::QuicSimpleTestServer::GetFileURL(kPath));
  request.devtools_request_id = "TEST";

  base::RunLoop delete_run_loop;
  mojo::PendingRemote<mojom::URLLoader> loader;
  context().mutable_factory_params().process_id = kProcessId;
  context().mutable_factory_params().is_orb_enabled = false;
  std::unique_ptr<URLLoader> url_loader = url_loader_options.MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.InitWithNewPipeAndPassReceiver(), request,
      loader_client.CreateRemote());

  delete_run_loop.Run();
  loader_client.RunUntilComplete();
  ASSERT_EQ(loader_client.completion_status().error_code, net::OK);

  ASSERT_EQ(loader_client.early_hints().size(), 1UL);
  const auto& hints = loader_client.early_hints()[0];
  ASSERT_EQ(hints->headers->link_headers.size(), 1UL);
  const auto& link_header = hints->headers->link_headers[0];
  EXPECT_EQ(link_header->href,
            net::QuicSimpleTestServer::GetFileURL(kPreloadPath));

  // Test the early hint headers sent to the devtools observer.
  devtools_observer.WaitUntilEarlyHints();
  const std::vector<network::mojom::HttpRawHeaderPairPtr>& early_hint_headers =
      devtools_observer.early_hint_headers();
  EXPECT_EQ(early_hint_headers.size(), 1UL);
  network::mojom::HttpRawHeaderPair header_content = *early_hint_headers[0];
  EXPECT_EQ(header_content.key, "link");
  EXPECT_EQ(header_content.value, preload_link);
}

TEST_F(URLLoaderTest, CookieReportingCategories) {
  net::test_server::EmbeddedTestServer https_server(
      net::test_server::EmbeddedTestServer::TYPE_HTTPS);
  https_server.SetSSLConfig(
      net::test_server::EmbeddedTestServer::CERT_TEST_NAMES);
  https_server.AddDefaultHandlers(
      base::FilePath(FILE_PATH_LITERAL("services/test/data")));
  ASSERT_TRUE(https_server.Start());

  // SameSite-by-default deprecation warning.
  {
    MockCookieObserver cookie_observer;
    TestURLLoaderClient loader_client;
    ResourceRequest request = CreateResourceRequest(
        "GET", https_server.GetURL("a.test", "/set-cookie?a=b;Secure"));
    // Make this a third-party request.
    url::Origin third_party_origin =
        url::Origin::Create(GURL("http://www.example.com"));
    request.site_for_cookies =
        net::SiteForCookies::FromOrigin(third_party_origin);
    request.trusted_params->isolation_info =
        net::IsolationInfo::CreateForInternalRequest(third_party_origin);

    base::RunLoop delete_run_loop;
    mojo::PendingRemote<mojom::URLLoader> loader;
    context().mutable_factory_params().process_id = kProcessId;
    context().mutable_factory_params().is_orb_enabled = false;
    URLLoaderOptions url_loader_options;
    url_loader_options.cookie_observer = cookie_observer.GetRemote();
    std::unique_ptr<URLLoader> url_loader = url_loader_options.MakeURLLoader(
        context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
        loader.InitWithNewPipeAndPassReceiver(), request,
        loader_client.CreateRemote());

    delete_run_loop.Run();
    loader_client.RunUntilComplete();
    EXPECT_EQ(net::OK, loader_client.completion_status().error_code);

    cookie_observer.WaitForCookies(1u);
    EXPECT_THAT(cookie_observer.observed_cookies(),
                testing::ElementsAre(MatchesCookieDetails(
                    CookieAccessType::kChange,
                    CookieOrLine("a=b", mojom::CookieOrLine::Tag::kCookie),
                    false /* is_included */)));
    EXPECT_TRUE(cookie_observer.observed_cookies()[0]
                    .status.HasExactlyExclusionReasonsForTesting(
                        {net::CookieInclusionStatus::ExclusionReason::
                             EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX}));
    EXPECT_TRUE(cookie_observer.observed_cookies()[0].status.HasWarningReason(
        net::CookieInclusionStatus::WarningReason::
            WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT));
  }

  // Blocked.
  {
    MockCookieObserver cookie_observer(CookieAccessType::kChange);
    TestURLLoaderClient loader_client;
    test_network_delegate()->set_cookie_options(
        net::TestNetworkDelegate::NO_SET_COOKIE);
    ResourceRequest request = CreateResourceRequest(
        "GET", https_server.GetURL("a.test", "/set-cookie?a=b;Secure"));
    // Make this a third-party request.
    url::Origin third_party_origin =
        url::Origin::Create(GURL("http://www.example.com"));
    request.site_for_cookies =
        net::SiteForCookies::FromOrigin(third_party_origin);
    request.trusted_params->isolation_info =
        net::IsolationInfo::CreateForInternalRequest(third_party_origin);

    base::RunLoop delete_run_loop;
    mojo::PendingRemote<mojom::URLLoader> loader;
    context().mutable_factory_params().process_id = kProcessId;
    context().mutable_factory_params().is_orb_enabled = false;
    URLLoaderOptions url_loader_options;
    url_loader_options.cookie_observer = cookie_observer.GetRemote();
    std::unique_ptr<URLLoader> url_loader = url_loader_options.MakeURLLoader(
        context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
        loader.InitWithNewPipeAndPassReceiver(), request,
        loader_client.CreateRemote());

    delete_run_loop.Run();
    loader_client.RunUntilComplete();
    EXPECT_EQ(net::OK, loader_client.completion_status().error_code);

    cookie_observer.WaitForCookies(1u);
    EXPECT_THAT(
        cookie_observer.observed_cookies(),
        testing::ElementsAre(MatchesCookieDetails(
            CookieAccessType::kChange,
            CookieOrLine("a=b", mojom::CookieOrLine::Tag::kCookie), false)));
    EXPECT_TRUE(cookie_observer.observed_cookies()[0]
                    .status.HasExactlyExclusionReasonsForTesting(
                        {net::CookieInclusionStatus::ExclusionReason::
                             EXCLUDE_USER_PREFERENCES}));

    test_network_delegate()->set_cookie_options(0);
  }

  // Not permitted by cookie rules, but not the sort of thing that's reported
  // to NetworkContextClient. Note: this uses HTTP, not HTTPS, unlike others;
  // and is in 1st-party context.
  {
    MockCookieObserver cookie_observer;
    TestURLLoaderClient loader_client;
    ResourceRequest request = CreateResourceRequest(
        "GET", test_server()->GetURL("a.test", "/set-cookie?a=b;Secure&d=e"));

    base::RunLoop delete_run_loop;
    mojo::PendingRemote<mojom::URLLoader> loader;
    context().mutable_factory_params().process_id = kProcessId;
    context().mutable_factory_params().is_orb_enabled = false;
    URLLoaderOptions url_loader_options;
    url_loader_options.cookie_observer = cookie_observer.GetRemote();
    std::unique_ptr<URLLoader> url_loader = url_loader_options.MakeURLLoader(
        context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
        loader.InitWithNewPipeAndPassReceiver(), request,
        loader_client.CreateRemote());

    delete_run_loop.Run();
    loader_client.RunUntilComplete();
    EXPECT_EQ(net::OK, loader_client.completion_status().error_code);

    cookie_observer.WaitForCookies(1u);
    EXPECT_THAT(
        cookie_observer.observed_cookies(),
        testing::ElementsAre(MatchesCookieDetails(
            CookieAccessType::kChange,
            CookieOrLine("d=e", mojom::CookieOrLine::Tag::kCookie), true)));
  }
}

namespace {

enum class SyncOrAsync { kSync, kAsync };

class MockTrustTokenRequestHelper : public TrustTokenRequestHelper {
 public:
  // |operation_synchrony| denotes whether to complete the |Begin|
  // and |Finalize| operations synchronously.
  //
  // |begin_done_flag|, if provided, will be set to true immediately before the
  // |Begin| operation returns.
  MockTrustTokenRequestHelper(
      std::optional<mojom::TrustTokenOperationStatus> on_begin,
      std::optional<mojom::TrustTokenOperationStatus> on_finalize,
      SyncOrAsync operation_synchrony,
      bool* begin_done_flag = nullptr)
      : on_begin_(on_begin),
        on_finalize_(on_finalize),
        operation_synchrony_(operation_synchrony),
        begin_done_flag_(begin_done_flag) {}

  ~MockTrustTokenRequestHelper() override {
    DCHECK(!on_begin_.has_value())
        << "Begin operation was expected but not performed.";
    DCHECK(!on_finalize_.has_value())
        << "Finalize operation was expected but not performed.";
  }

  MockTrustTokenRequestHelper(const MockTrustTokenRequestHelper&) = delete;
  MockTrustTokenRequestHelper& operator=(const MockTrustTokenRequestHelper&) =
      delete;

  // TrustTokenRequestHelper:
  void Begin(const GURL& url,
             base::OnceCallback<void(std::optional<net::HttpRequestHeaders>,
                                     mojom::TrustTokenOperationStatus)> done)
      override {
    DCHECK(on_begin_.has_value());

    // Clear storage to crash if the method gets called a second time.
    mojom::TrustTokenOperationStatus result = *on_begin_;
    on_begin_.reset();
    std::optional<net::HttpRequestHeaders> headers;
    if (result == mojom::TrustTokenOperationStatus::kOk) {
      headers.emplace();
      headers->SetHeader(kTrustTokensSecTrustTokenHeader, "mock-pst-value");
      headers->SetHeader(kTrustTokensSecTrustTokenVersionHeader,
                         "mock-pst-version");
    }

    switch (operation_synchrony_) {
      case SyncOrAsync::kSync: {
        OnDoneBeginning(
            base::BindOnce(std::move(done), std::move(headers), result));
        return;
      }
      case SyncOrAsync::kAsync: {
        base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
            FROM_HERE,
            base::BindOnce(
                &MockTrustTokenRequestHelper::OnDoneBeginning,
                base::Unretained(this),
                base::BindOnce(std::move(done), std::move(headers), result)));
        return;
      }
    }
  }

  void Finalize(net::HttpResponseHeaders& response_headers,
                base::OnceCallback<void(mojom::TrustTokenOperationStatus)> done)
      override {
    DCHECK(on_finalize_.has_value());

    // Clear storage to crash if the method gets called a second time.
    mojom::TrustTokenOperationStatus result = *on_finalize_;
    on_finalize_.reset();

    switch (operation_synchrony_) {
      case SyncOrAsync::kSync: {
        std::move(done).Run(result);
        return;
      }
      case SyncOrAsync::kAsync: {
        base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
            FROM_HERE, base::BindOnce(std::move(done), result));
        return;
      }
    }
  }

  mojom::TrustTokenOperationResultPtr CollectOperationResultWithStatus(
      mojom::TrustTokenOperationStatus status) override {
    mojom::TrustTokenOperationResultPtr operation_result =
        mojom::TrustTokenOperationResult::New();
    operation_result->status = status;
    return operation_result;
  }

 private:
  void OnDoneBeginning(base::OnceClosure done) {
    if (begin_done_flag_) {
      EXPECT_FALSE(*begin_done_flag_);
      *begin_done_flag_ = true;
    }

    std::move(done).Run();
  }

  // Store mocked function results in Optionals to hit a CHECK failure if a mock
  // method is called without having had a return value specified.
  std::optional<mojom::TrustTokenOperationStatus> on_begin_;
  std::optional<mojom::TrustTokenOperationStatus> on_finalize_;

  SyncOrAsync operation_synchrony_;

  raw_ptr<bool> begin_done_flag_;
};

class NoopTrustTokenKeyCommitmentGetter : public TrustTokenKeyCommitmentGetter {
 public:
  NoopTrustTokenKeyCommitmentGetter() = default;
  void Get(const url::Origin& origin,
           base::OnceCallback<void(mojom::TrustTokenKeyCommitmentResultPtr)>
               on_done) const override {}
};

base::NoDestructor<NoopTrustTokenKeyCommitmentGetter>
    noop_key_commitment_getter{};

mojom::NetworkContextClient* ReturnNullNetworkContextClient() {
  return nullptr;
}

class MockTrustTokenRequestHelperFactory
    : public TrustTokenRequestHelperFactory {
 public:
  MockTrustTokenRequestHelperFactory(
      mojom::TrustTokenOperationStatus creation_failure_error,
      SyncOrAsync sync_or_async)
      : TrustTokenRequestHelperFactory(
            nullptr,
            noop_key_commitment_getter.get(),
            base::BindRepeating(&ReturnNullNetworkContextClient),
            {}),
        sync_or_async_(sync_or_async),
        creation_failure_error_(creation_failure_error) {}

  MockTrustTokenRequestHelperFactory(
      std::optional<mojom::TrustTokenOperationStatus> on_begin,
      std::optional<mojom::TrustTokenOperationStatus> on_finalize,
      SyncOrAsync sync_or_async,
      bool* begin_done_flag)
      : TrustTokenRequestHelperFactory(
            nullptr,
            noop_key_commitment_getter.get(),
            base::BindRepeating(&ReturnNullNetworkContextClient),
            {}),
        sync_or_async_(sync_or_async),
        helper_(
            std::make_unique<MockTrustTokenRequestHelper>(on_begin,
                                                          on_finalize,
                                                          sync_or_async,
                                                          begin_done_flag)) {}

  void CreateTrustTokenHelperForRequest(
      const url::Origin& top_frame_origin,
      const net::HttpRequestHeaders& headers,
      const mojom::TrustTokenParams& params,
      const net::NetLogWithSource& net_log,
      base::OnceCallback<void(TrustTokenStatusOrRequestHelper)> done) override {
    if (creation_failure_error_) {
      switch (sync_or_async_) {
        case SyncOrAsync::kSync: {
          std::move(done).Run(std::move(*creation_failure_error_));
          return;
        }
        case SyncOrAsync::kAsync:
          base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
              FROM_HERE, base::BindOnce(std::move(done),
                                        std::move(*creation_failure_error_)));
          return;
      }
    }

    switch (sync_or_async_) {
      case SyncOrAsync::kSync: {
        std::move(done).Run(std::move(helper_));
        return;
      }
      case SyncOrAsync::kAsync:
        base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
            FROM_HERE, base::BindOnce(std::move(done), std::move(helper_)));
        return;
    }

    NOTREACHED();
  }

 private:
  SyncOrAsync sync_or_async_;
  std::optional<mojom::TrustTokenOperationStatus> creation_failure_error_;
  std::unique_ptr<TrustTokenRequestHelper> helper_;
};

class MockTrustTokenDevToolsObserver : public MockDevToolsObserver {
 public:
  MockTrustTokenDevToolsObserver() = default;
  ~MockTrustTokenDevToolsObserver() override = default;

  void OnTrustTokenOperationDone(
      const std::string& devtool_request_id,
      network::mojom::TrustTokenOperationResultPtr result) override {
    // Event should be only triggered once.
    EXPECT_FALSE(trust_token_operation_status_.has_value());
    trust_token_operation_status_ = result->status;
  }

  const std::optional<mojom::TrustTokenOperationStatus>
  trust_token_operation_status() const {
    return trust_token_operation_status_;
  }

 private:
  std::optional<mojom::TrustTokenOperationStatus>
      trust_token_operation_status_ = std::nullopt;
};

class ExpectBypassCacheInterceptor : public net::URLRequestInterceptor {
 public:
  std::unique_ptr<net::URLRequestJob> MaybeInterceptRequest(
      net::URLRequest* request) const override {
    EXPECT_TRUE(request->load_flags() & net::LOAD_BYPASS_CACHE);
    return nullptr;
  }
};

class ExpectCookieSettingOverridesURLRequestInterceptor
    : public net::URLRequestInterceptor {
 public:
  explicit ExpectCookieSettingOverridesURLRequestInterceptor(
      net::CookieSettingOverrides cookie_setting_overrides,
      bool* was_intercepted)
      : cookie_setting_overrides_(cookie_setting_overrides),
        was_intercepted_(was_intercepted) {}

  // net::URLRequestInterceptor:
  std::unique_ptr<net::URLRequestJob> MaybeInterceptRequest(
      net::URLRequest* request) const override {
    EXPECT_FALSE(*was_intercepted_);
    EXPECT_EQ(request->cookie_setting_overrides(), cookie_setting_overrides_);
    *was_intercepted_ = true;
    return nullptr;
  }

 private:
  const net::CookieSettingOverrides cookie_setting_overrides_;
  const raw_ptr<bool> was_intercepted_;
};

}  // namespace

class URLLoaderSyncOrAsyncTrustTokenOperationTest
    : public URLLoaderTest,
      public ::testing::WithParamInterface<SyncOrAsync> {
 public:
  void OnServerReceivedRequest(const net::test_server::HttpRequest&) override {
    EXPECT_TRUE(outbound_trust_token_operation_was_successful_);
  }

 protected:
  ResourceRequest CreateTrustTokenResourceRequest() {
    GURL request_url = test_server()->GetURL("/simple_page.html");
    ResourceRequest request = CreateResourceRequest("GET", request_url);
    request.trust_token_params =
        OptionalTrustTokenParams(mojom::TrustTokenParams::New());
    // Set the devtools id to trigger the OnTrustTokenOperationDone call.
    request.devtools_request_id = "TEST";

    // Any Trust Token URLRequest that makes it to Start() should have the
    // BYPASS_CACHE flag set.
    net::URLRequestFilter::GetInstance()->AddUrlInterceptor(
        request_url, std::make_unique<ExpectBypassCacheInterceptor>());
    return request;
  }

  // Maintain a flag, set by the mock trust token request helper, denoting
  // whether we've successfully executed the outbound Trust Tokens operation.
  // This is used to make URLLoader does not send its main request before it
  // has completed the outbound part of its Trust Tokens operation (this
  // involves checking preconditions and potentially annotating the request with
  // Trust Tokens-related request headers).
  bool outbound_trust_token_operation_was_successful_ = false;
};

INSTANTIATE_TEST_SUITE_P(WithSyncAndAsyncOperations,
                         URLLoaderSyncOrAsyncTrustTokenOperationTest,
                         ::testing::Values(SyncOrAsync::kSync,
                                           SyncOrAsync::kAsync));

// An otherwise-successful request with an associated Trust Tokens operation
// whose Begin and Finalize steps are both successful should succeed overall.
TEST_P(URLLoaderSyncOrAsyncTrustTokenOperationTest,
       HandlesTrustTokenOperationSuccess) {
  base::HistogramTester histogram_tester;
  ResourceRequest request = CreateTrustTokenResourceRequest();

  base::RunLoop delete_run_loop;
  mojo::PendingRemote<mojom::URLLoader> loader_remote;
  std::unique_ptr<URLLoader> url_loader;
  context().mutable_factory_params().process_id =
      OriginatingProcessId::browser();
  MockTrustTokenDevToolsObserver devtools_observer;

  URLLoaderOptions url_loader_options;
  MockTrustTokenObserver trust_token_observer;
  url_loader_options.trust_token_observer = trust_token_observer.GetRemote();
  url_loader_options.trust_token_helper_factory =
      std::make_unique<MockTrustTokenRequestHelperFactory>(
          mojom::TrustTokenOperationStatus::kOk /* on_begin */,
          mojom::TrustTokenOperationStatus::kOk /* on_finalize */, GetParam(),
          &outbound_trust_token_operation_was_successful_);
  url_loader_options.devtools_observer = devtools_observer.Bind();
  url_loader = url_loader_options.MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader_remote.InitWithNewPipeAndPassReceiver(), request,
      client()->CreateRemote());

  client()->RunUntilComplete();
  delete_run_loop.Run();

  histogram_tester.ExpectUniqueSample(
      "Net.TrustTokens.OperationOutcome.Issuance",
      mojom::TrustTokenOperationStatus::kOk, 1);

  EXPECT_EQ(client()->completion_status().error_code, net::OK);
  EXPECT_EQ(client()->completion_status().trust_token_operation_status,
            mojom::TrustTokenOperationStatus::kOk);
  // Verify the DevTools event was fired and it has the right status.
  EXPECT_EQ(devtools_observer.trust_token_operation_status(),
            mojom::TrustTokenOperationStatus::kOk);
  // The page should still have loaded.
  base::FilePath file = GetTestFilePath("simple_page.html");
  std::string expected;
  if (!base::ReadFileToString(file, &expected)) {
    ADD_FAILURE() << "File not found: " << file.value();
    return;
  }
  EXPECT_EQ(ReadBody(), expected);

  EXPECT_FALSE(client()->response_head()->headers->raw_headers().empty());

  trust_token_observer.WaitForTrustTokens(1u);
  EXPECT_THAT(
      trust_token_observer.observed_tokens(),
      testing::ElementsAre(MatchesTrustTokenDetails(
          test_server()->GetOrigin(), test_server()->GetOrigin(), false)));
}

// A request with an associated Trust Tokens operation whose Begin step returns
// kAlreadyExists should return a success result immediately, without completing
// the load.
//
// (This is the case exactly when the request is for token redemption, and the
// Trust Tokens logic determines that there is already a cached redemption
// record stored locally, obviating the need to execute a redemption
// operation.)
TEST_P(URLLoaderSyncOrAsyncTrustTokenOperationTest,
       HandlesTrustTokenRedemptionRecordCacheHit) {
  ResourceRequest request = CreateTrustTokenResourceRequest();

  base::RunLoop delete_run_loop;
  mojo::PendingRemote<mojom::URLLoader> loader_remote;
  std::unique_ptr<URLLoader> url_loader;
  context().mutable_factory_params().process_id =
      OriginatingProcessId::browser();
  MockTrustTokenDevToolsObserver devtools_observer;

  URLLoaderOptions url_loader_options;
  MockTrustTokenObserver trust_token_observer;
  url_loader_options.trust_token_observer = trust_token_observer.GetRemote();
  url_loader_options.trust_token_helper_factory =
      std::make_unique<MockTrustTokenRequestHelperFactory>(
          mojom::TrustTokenOperationStatus::kAlreadyExists /* on_begin */,
          std::nullopt /* on_finalize */, GetParam(),
          &outbound_trust_token_operation_was_successful_);
  url_loader_options.devtools_observer = devtools_observer.Bind();
  url_loader = url_loader_options.MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader_remote.InitWithNewPipeAndPassReceiver(), request,
      client()->CreateRemote());

  client()->RunUntilComplete();
  delete_run_loop.Run();

  EXPECT_EQ(client()->completion_status().error_code,
            net::ERR_TRUST_TOKEN_OPERATION_SUCCESS_WITHOUT_SENDING_REQUEST);
  EXPECT_EQ(client()->completion_status().trust_token_operation_status,
            mojom::TrustTokenOperationStatus::kAlreadyExists);
  // Verify the DevTools event was fired and it has the right status.
  EXPECT_EQ(devtools_observer.trust_token_operation_status(),
            mojom::TrustTokenOperationStatus::kAlreadyExists);

  EXPECT_FALSE(client()->response_head());
  EXPECT_FALSE(client()->response_body().is_valid());

  trust_token_observer.WaitForTrustTokens(1u);
  EXPECT_THAT(
      trust_token_observer.observed_tokens(),
      testing::ElementsAre(MatchesTrustTokenDetails(
          test_server()->GetOrigin(), test_server()->GetOrigin(), false)));
}

// When a request's associated Trust Tokens operation's Begin step fails, the
// request itself should fail immediately.
TEST_P(URLLoaderSyncOrAsyncTrustTokenOperationTest,
       HandlesTrustTokenBeginFailure) {
  base::HistogramTester histogram_tester;
  ResourceRequest request = CreateTrustTokenResourceRequest();

  base::RunLoop delete_run_loop;
  mojo::PendingRemote<mojom::URLLoader> loader_remote;
  std::unique_ptr<URLLoader> url_loader;
  context().mutable_factory_params().process_id =
      OriginatingProcessId::browser();
  MockTrustTokenDevToolsObserver devtools_observer;

  URLLoaderOptions url_loader_options;
  MockTrustTokenObserver trust_token_observer;
  url_loader_options.trust_token_observer = trust_token_observer.GetRemote();
  url_loader_options.trust_token_helper_factory =
      std::make_unique<MockTrustTokenRequestHelperFactory>(
          mojom::TrustTokenOperationStatus::kFailedPrecondition /* on_begin */,
          std::nullopt /* on_finalize */, GetParam(),
          &outbound_trust_token_operation_was_successful_);
  url_loader_options.devtools_observer = devtools_observer.Bind();
  url_loader = url_loader_options.MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader_remote.InitWithNewPipeAndPassReceiver(), request,
      client()->CreateRemote());

  client()->RunUntilComplete();
  delete_run_loop.Run();

  histogram_tester.ExpectUniqueSample(
      "Net.TrustTokens.OperationOutcome.Issuance",
      mojom::TrustTokenOperationStatus::kFailedPrecondition, 1);

  EXPECT_EQ(client()->completion_status().error_code,
            net::ERR_TRUST_TOKEN_OPERATION_FAILED);
  EXPECT_EQ(client()->completion_status().trust_token_operation_status,
            mojom::TrustTokenOperationStatus::kFailedPrecondition);
  // Verify the DevTools event was fired and it has the right status.
  EXPECT_EQ(devtools_observer.trust_token_operation_status(),
            mojom::TrustTokenOperationStatus::kFailedPrecondition);

  EXPECT_FALSE(client()->response_head());
  EXPECT_FALSE(client()->response_body().is_valid());

  trust_token_observer.WaitForTrustTokens(1u);
  EXPECT_THAT(
      trust_token_observer.observed_tokens(),
      testing::ElementsAre(MatchesTrustTokenDetails(
          test_server()->GetOrigin(), test_server()->GetOrigin(), false)));
}

// When a request's associated Trust Tokens operation's Begin step succeeds but
// its Finalize step fails, the request itself should fail.
TEST_P(URLLoaderSyncOrAsyncTrustTokenOperationTest,
       HandlesTrustTokenFinalizeFailure) {
  ResourceRequest request = CreateTrustTokenResourceRequest();

  base::RunLoop delete_run_loop;
  mojo::PendingRemote<mojom::URLLoader> loader_remote;
  std::unique_ptr<URLLoader> url_loader;
  context().mutable_factory_params().process_id =
      OriginatingProcessId::browser();
  MockTrustTokenDevToolsObserver devtools_observer;

  URLLoaderOptions url_loader_options;
  MockTrustTokenObserver trust_token_observer;
  url_loader_options.trust_token_observer = trust_token_observer.GetRemote();
  url_loader_options.trust_token_helper_factory =
      std::make_unique<MockTrustTokenRequestHelperFactory>(
          mojom::TrustTokenOperationStatus::kOk /* on_begin */,
          mojom::TrustTokenOperationStatus::kBadResponse /* on_finalize */,
          GetParam(), &outbound_trust_token_operation_was_successful_);
  url_loader_options.devtools_observer = devtools_observer.Bind();
  url_loader = url_loader_options.MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader_remote.InitWithNewPipeAndPassReceiver(), request,
      client()->CreateRemote());

  client()->RunUntilComplete();
  delete_run_loop.Run();
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(client()->completion_status().error_code,
            net::ERR_TRUST_TOKEN_OPERATION_FAILED);
  EXPECT_EQ(client()->completion_status().trust_token_operation_status,
            mojom::TrustTokenOperationStatus::kBadResponse);
  // Verify the DevTools event was fired and it has the right status.
  EXPECT_EQ(devtools_observer.trust_token_operation_status(),
            mojom::TrustTokenOperationStatus::kBadResponse);

  trust_token_observer.WaitForTrustTokens(1u);
  EXPECT_THAT(
      trust_token_observer.observed_tokens(),
      testing::ElementsAre(MatchesTrustTokenDetails(
          test_server()->GetOrigin(), test_server()->GetOrigin(), false)));
}

// When URLLoader receives a  request parameterized to perform a Trust Tokens
// operation but fails to create a trust token request helper (because a
// universal Trust Tokens precondition is violated, for instance), the request
// should fail entirely.
TEST_P(URLLoaderSyncOrAsyncTrustTokenOperationTest,
       HandlesTrustTokenRequestHelperCreationFailure) {
  ResourceRequest request = CreateTrustTokenResourceRequest();

  base::RunLoop delete_run_loop;
  mojo::PendingRemote<mojom::URLLoader> loader_remote;
  std::unique_ptr<URLLoader> url_loader;
  context().mutable_factory_params().process_id =
      OriginatingProcessId::browser();
  MockTrustTokenDevToolsObserver devtools_observer;

  URLLoaderOptions url_loader_options;
  MockTrustTokenObserver trust_token_observer;
  url_loader_options.trust_token_observer = trust_token_observer.GetRemote();
  url_loader_options.trust_token_helper_factory =
      std::make_unique<MockTrustTokenRequestHelperFactory>(
          mojom::TrustTokenOperationStatus::
              kInternalError /* helper_creation_error */,
          GetParam());
  url_loader_options.devtools_observer = devtools_observer.Bind();
  url_loader = url_loader_options.MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader_remote.InitWithNewPipeAndPassReceiver(), request,
      client()->CreateRemote());

  client()->RunUntilComplete();
  delete_run_loop.Run();

  EXPECT_EQ(client()->completion_status().error_code,
            net::ERR_TRUST_TOKEN_OPERATION_FAILED);
  EXPECT_EQ(client()->completion_status().trust_token_operation_status,
            mojom::TrustTokenOperationStatus::kInternalError);
  // Verify the DevTools event was fired and it has the right status.
  EXPECT_EQ(devtools_observer.trust_token_operation_status(),
            mojom::TrustTokenOperationStatus::kInternalError);

  trust_token_observer.WaitForTrustTokens(1u);
  EXPECT_THAT(
      trust_token_observer.observed_tokens(),
      testing::ElementsAre(MatchesTrustTokenDetails(
          test_server()->GetOrigin(), test_server()->GetOrigin(), false)));
}

// When URLLoader receives a request that is blocked by policy, the request
// should fail entirely and report a blocked event to the observer.
TEST_P(URLLoaderSyncOrAsyncTrustTokenOperationTest,
       HandlesTrustTokenRequestHelperCreationBlocked) {
  ResourceRequest request = CreateTrustTokenResourceRequest();

  base::RunLoop delete_run_loop;
  mojo::PendingRemote<mojom::URLLoader> loader_remote;
  std::unique_ptr<URLLoader> url_loader;
  context().mutable_factory_params().process_id =
      OriginatingProcessId::browser();
  MockTrustTokenDevToolsObserver devtools_observer;

  URLLoaderOptions url_loader_options;
  MockTrustTokenObserver trust_token_observer;
  url_loader_options.trust_token_observer = trust_token_observer.GetRemote();
  url_loader_options.trust_token_helper_factory =
      std::make_unique<MockTrustTokenRequestHelperFactory>(
          mojom::TrustTokenOperationStatus::
              kUnauthorized /* helper_creation_error */,
          GetParam());
  url_loader_options.devtools_observer = devtools_observer.Bind();
  url_loader = url_loader_options.MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader_remote.InitWithNewPipeAndPassReceiver(), request,
      client()->CreateRemote());

  client()->RunUntilComplete();
  delete_run_loop.Run();

  EXPECT_EQ(client()->completion_status().error_code,
            net::ERR_TRUST_TOKEN_OPERATION_FAILED);
  EXPECT_EQ(client()->completion_status().trust_token_operation_status,
            mojom::TrustTokenOperationStatus::kUnauthorized);
  // Verify the DevTools event was fired and it has the right status.
  EXPECT_EQ(devtools_observer.trust_token_operation_status(),
            mojom::TrustTokenOperationStatus::kUnauthorized);

  trust_token_observer.WaitForTrustTokens(1u);
  EXPECT_THAT(
      trust_token_observer.observed_tokens(),
      testing::ElementsAre(MatchesTrustTokenDetails(
          test_server()->GetOrigin(), test_server()->GetOrigin(), true)));
}

// Request headers attached by the Trust Tokens helper should not be forwarded
// to a cross-origin redirect target.
TEST_P(URLLoaderSyncOrAsyncTrustTokenOperationTest,
       RemovesTrustTokenHeadersOnCrossOriginRedirect) {
  GURL url = test_server()->GetURL(
      "/server-redirect?" +
      test_server()->GetURL("other.test", "/echo").spec());
  ResourceRequest request = CreateResourceRequest("GET", url);
  request.trust_token_params =
      OptionalTrustTokenParams(mojom::TrustTokenParams::New());

  base::RunLoop delete_run_loop;
  mojo::Remote<mojom::URLLoader> loader;
  std::unique_ptr<URLLoader> url_loader;
  context().mutable_factory_params().process_id =
      OriginatingProcessId::browser();

  URLLoaderOptions url_loader_options;
  url_loader_options.trust_token_helper_factory =
      std::make_unique<MockTrustTokenRequestHelperFactory>(
          mojom::TrustTokenOperationStatus::kOk /* on_begin */,
          std::nullopt /* on_finalize */, GetParam(),
          &outbound_trust_token_operation_was_successful_);
  url_loader = url_loader_options.MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.BindNewPipeAndPassReceiver(), request, client()->CreateRemote());

  client()->RunUntilRedirectReceived();

  const auto& request_headers1 = sent_request().headers;
  EXPECT_NE(request_headers1.end(),
            request_headers1.find(kTrustTokensSecTrustTokenHeader));
  EXPECT_NE(request_headers1.end(),
            request_headers1.find(kTrustTokensSecTrustTokenVersionHeader));

  loader->FollowRedirect(/*headers_update_params=*/{},
                         /*new_url=*/std::nullopt);
  client()->RunUntilComplete();
  delete_run_loop.Run();

  const auto& request_headers2 = sent_request().headers;
  EXPECT_EQ(request_headers2.end(),
            request_headers2.find(kTrustTokensSecTrustTokenHeader));
  EXPECT_EQ(request_headers2.end(),
            request_headers2.find(kTrustTokensSecTrustTokenVersionHeader));

  EXPECT_EQ(client()->completion_status().error_code,
            net::ERR_TRUST_TOKEN_OPERATION_FAILED);
  EXPECT_EQ(client()->completion_status().trust_token_operation_status,
            mojom::TrustTokenOperationStatus::kBadResponse);
}

// Request headers attached by the Trust Tokens helper should be retained on a
// same-origin redirect.
TEST_P(URLLoaderSyncOrAsyncTrustTokenOperationTest,
       RetainsTrustTokenHeadersOnSameOriginRedirect) {
  GURL url = test_server()->GetURL("/server-redirect?" +
                                   test_server()->GetURL("/echo").spec());
  ResourceRequest request = CreateResourceRequest("GET", url);
  request.trust_token_params =
      OptionalTrustTokenParams(mojom::TrustTokenParams::New());

  base::RunLoop delete_run_loop;
  mojo::Remote<mojom::URLLoader> loader;
  std::unique_ptr<URLLoader> url_loader;
  context().mutable_factory_params().process_id =
      OriginatingProcessId::browser();

  URLLoaderOptions url_loader_options;
  url_loader_options.trust_token_helper_factory =
      std::make_unique<MockTrustTokenRequestHelperFactory>(
          mojom::TrustTokenOperationStatus::kOk /* on_begin */,
          mojom::TrustTokenOperationStatus::kOk /* on_finalize */, GetParam(),
          &outbound_trust_token_operation_was_successful_);
  url_loader = url_loader_options.MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.BindNewPipeAndPassReceiver(), request, client()->CreateRemote());

  client()->RunUntilRedirectReceived();

  const auto& request_headers1 = sent_request().headers;
  EXPECT_NE(request_headers1.end(),
            request_headers1.find(kTrustTokensSecTrustTokenHeader));
  EXPECT_NE(request_headers1.end(),
            request_headers1.find(kTrustTokensSecTrustTokenVersionHeader));

  loader->FollowRedirect(/*headers_update_params=*/{},
                         /*new_url=*/std::nullopt);
  client()->RunUntilComplete();
  delete_run_loop.Run();

  const auto& request_headers2 = sent_request().headers;
  EXPECT_NE(request_headers2.end(),
            request_headers2.find(kTrustTokensSecTrustTokenHeader));
  EXPECT_NE(request_headers2.end(),
            request_headers2.find(kTrustTokensSecTrustTokenVersionHeader));
}

TEST_F(URLLoaderTest, OnRawRequestClientSecurityStateFactory) {
  MockDevToolsObserver devtools_observer;
  ResourceRequest request =
      CreateResourceRequest("GET", test_server()->GetURL("/simple_page.html"));
  request.devtools_request_id = "fake-id";

  auto client_security_state = mojom::ClientSecurityState::New();
  client_security_state->is_web_secure_context = false;
  client_security_state->local_network_access_request_policy =
      mojom::LocalNetworkAccessRequestPolicy::kAllow;
  client_security_state->ip_address_space = mojom::IPAddressSpace::kPublic;
  context().mutable_factory_params().client_security_state =
      std::move(client_security_state);
  context().mutable_factory_params().process_id = kProcessId;
  context().mutable_factory_params().is_orb_enabled = false;

  base::RunLoop delete_run_loop;
  mojo::PendingRemote<mojom::URLLoader> loader;
  URLLoaderOptions url_loader_options;
  MockTrustTokenObserver trust_token_observer;
  url_loader_options.trust_token_observer = trust_token_observer.GetRemote();
  url_loader_options.devtools_observer = devtools_observer.Bind();
  std::unique_ptr<URLLoader> url_loader = url_loader_options.MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.InitWithNewPipeAndPassReceiver(), request,
      client()->CreateRemote());

  delete_run_loop.Run();
  client()->RunUntilComplete();
  EXPECT_EQ(net::OK, client()->completion_status().error_code);

  devtools_observer.WaitUntilRawRequest(0);
  ASSERT_TRUE(devtools_observer.client_security_state());
  EXPECT_EQ(devtools_observer.client_security_state()
                ->local_network_access_request_policy,
            mojom::LocalNetworkAccessRequestPolicy::kAllow);
  EXPECT_EQ(devtools_observer.client_security_state()->is_web_secure_context,
            false);
  EXPECT_EQ(devtools_observer.client_security_state()->ip_address_space,
            mojom::IPAddressSpace::kPublic);
}

TEST_F(URLLoaderTest, OnRawRequestClientSecurityStateRequest) {
  MockDevToolsObserver devtools_observer;
  ResourceRequest request =
      CreateResourceRequest("GET", test_server()->GetURL("/simple_page.html"));
  request.devtools_request_id = "fake-id";
  auto client_security_state = mojom::ClientSecurityState::New();
  client_security_state->is_web_secure_context = false;
  client_security_state->local_network_access_request_policy =
      mojom::LocalNetworkAccessRequestPolicy::kAllow;
  client_security_state->ip_address_space = mojom::IPAddressSpace::kPublic;
  request.trusted_params->client_security_state =
      std::move(client_security_state);

  context().mutable_factory_params().process_id = kProcessId;
  context().mutable_factory_params().is_orb_enabled = false;

  base::RunLoop delete_run_loop;
  mojo::PendingRemote<mojom::URLLoader> loader;
  URLLoaderOptions url_loader_options;
  url_loader_options.devtools_observer = devtools_observer.Bind();
  std::unique_ptr<URLLoader> url_loader = url_loader_options.MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.InitWithNewPipeAndPassReceiver(), request,
      client()->CreateRemote());
  delete_run_loop.Run();
  client()->RunUntilComplete();
  EXPECT_EQ(net::OK, client()->completion_status().error_code);

  devtools_observer.WaitUntilRawRequest(0);
  ASSERT_TRUE(devtools_observer.client_security_state());
  EXPECT_EQ(devtools_observer.client_security_state()
                ->local_network_access_request_policy,
            mojom::LocalNetworkAccessRequestPolicy::kAllow);
  EXPECT_EQ(devtools_observer.client_security_state()->is_web_secure_context,
            false);
  EXPECT_EQ(devtools_observer.client_security_state()->ip_address_space,
            mojom::IPAddressSpace::kPublic);
}

TEST_F(URLLoaderTest, OnRawRequestClientSecurityStateNotPresent) {
  MockDevToolsObserver devtools_observer;
  ResourceRequest request =
      CreateResourceRequest("GET", test_server()->GetURL("/simple_page.html"));
  request.devtools_request_id = "fake-id";

  context().mutable_factory_params().process_id = kProcessId;
  context().mutable_factory_params().is_orb_enabled = false;

  base::RunLoop delete_run_loop;
  mojo::PendingRemote<mojom::URLLoader> loader;
  URLLoaderOptions url_loader_options;
  url_loader_options.devtools_observer = devtools_observer.Bind();
  std::unique_ptr<URLLoader> url_loader = url_loader_options.MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.InitWithNewPipeAndPassReceiver(), request,
      client()->CreateRemote());
  delete_run_loop.Run();
  client()->RunUntilComplete();
  EXPECT_EQ(net::OK, client()->completion_status().error_code);

  devtools_observer.WaitUntilRawRequest(0);
  ASSERT_FALSE(devtools_observer.client_security_state());
}

TEST_F(URLLoaderTest, OnRawResponseIPAddressSpace) {
  MockDevToolsObserver devtools_observer;
  ResourceRequest request =
      CreateResourceRequest("GET", test_server()->GetURL("/simple_page.html"));
  request.devtools_request_id = "fake-id";

  context().mutable_factory_params().process_id = kProcessId;
  context().mutable_factory_params().is_orb_enabled = false;

  base::RunLoop delete_run_loop;
  mojo::PendingRemote<mojom::URLLoader> loader;
  URLLoaderOptions url_loader_options;
  url_loader_options.devtools_observer = devtools_observer.Bind();
  std::unique_ptr<URLLoader> url_loader = url_loader_options.MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.InitWithNewPipeAndPassReceiver(), request,
      client()->CreateRemote());
  delete_run_loop.Run();
  client()->RunUntilComplete();
  EXPECT_EQ(net::OK, client()->completion_status().error_code);

  devtools_observer.WaitUntilRawResponse(0);
  ASSERT_EQ(devtools_observer.resource_address_space(),
            mojom::IPAddressSpace::kLoopback);
}

TEST_F(URLLoaderMockSocketTest, OrbDoesNotCloseSocketsWhenResourcesNotBlocked) {
  orb_enabled_ = true;

  const net::MockRead kReads[] = {
      net::MockRead(net::SYNCHRONOUS, 1,
                    "HTTP/1.1 200 OK\r\n"
                    "Connection: keep-alive\r\n"
                    "Content-Length: 5\r\n\r\n"),
      net::MockRead(net::SYNCHRONOUS, 2, "Hello"),
  };

  net::SequencedSocketData socket_data_connect(kAsyncMockConnect, {}, {});
  net::SequencedSocketData socket_data_reads_writes(kReads, kOriginTestWrites);
  socket_factory_.AddSocketDataProvider(&socket_data_connect);
  socket_factory_.AddSocketDataProvider(&socket_data_reads_writes);

  GURL url("http://origin.test/");
  url::Origin initiator =
      url::Origin::Create(GURL("http://other-origin.test/"));

  ResourceRequest request = CreateResourceRequest("GET", url);
  request.mode = mojom::RequestMode::kCors;
  request.request_initiator = initiator;
  std::string body;
  EXPECT_EQ(net::OK, LoadRequest(request, &body));
  EXPECT_EQ(body, "Hello");

  // Socket should still be alive, in the socket pool.
  EXPECT_TRUE(socket_data_reads_writes.socket());
}

TEST_F(URLLoaderMockSocketTest, OrbClosesSocketOnReceivingHeaders) {
  orb_enabled_ = true;

  const net::MockRead kReads[] = {
      net::MockRead(net::SYNCHRONOUS, 1,
                    "HTTP/1.1 200 OK\r\n"
                    "Connection: keep-alive\r\n"
                    "Content-Type: text/html\r\n"
                    "X-Content-Type-Options: nosniff\r\n"
                    "Content-Length: 23\r\n\r\n"),
      net::MockRead(net::SYNCHRONOUS, 2, "This should not be read"),
  };

  net::SequencedSocketData socket_data_connect(kAsyncMockConnect, {}, {});
  net::SequencedSocketData socket_data_reads_writes(kReads, kOriginTestWrites);
  socket_factory_.AddSocketDataProvider(&socket_data_connect);
  socket_factory_.AddSocketDataProvider(&socket_data_reads_writes);

  GURL url("http://origin.test/");
  url::Origin initiator =
      url::Origin::Create(GURL("http://other-origin.test/"));

  ResourceRequest request = CreateResourceRequest("GET", url);
  request.mode = mojom::RequestMode::kNoCors;
  request.request_initiator = initiator;
  std::string body;
  EXPECT_EQ(net::OK, LoadRequest(request, &body));
  EXPECT_TRUE(body.empty());

  // Socket should have been destroyed, so it will not be reused.
  EXPECT_FALSE(socket_data_reads_writes.socket());
}

TEST_F(URLLoaderMockSocketTest,
       OrbDoesNotCloseSocketsWhenResourcesNotBlockedAfterSniffingMimeType) {
  orb_enabled_ = true;

  const net::MockRead kReads[] = {
      net::MockRead(net::SYNCHRONOUS, 1,
                    "HTTP/1.1 200 OK\r\n"
                    "Connection: keep-alive\r\n"
                    "Content-Type: application/json\r\n"
                    "Content-Length: 17\r\n\r\n"),
      net::MockRead(net::SYNCHRONOUS, 2, "Not actually JSON"),
  };

  net::SequencedSocketData socket_data_connect(kAsyncMockConnect, {}, {});
  net::SequencedSocketData socket_data_reads_writes(kReads, kOriginTestWrites);
  socket_factory_.AddSocketDataProvider(&socket_data_connect);
  socket_factory_.AddSocketDataProvider(&socket_data_reads_writes);

  GURL url("http://origin.test/");
  url::Origin initiator =
      url::Origin::Create(GURL("http://other-origin.test/"));

  ResourceRequest request = CreateResourceRequest("GET", url);
  request.mode = mojom::RequestMode::kCors;
  request.request_initiator = initiator;
  std::string body;
  EXPECT_EQ(net::OK, LoadRequest(request, &body));
  EXPECT_EQ("Not actually JSON", body);

  // Socket should still be alive, in the socket pool.
  EXPECT_TRUE(socket_data_reads_writes.socket());
}

TEST_F(URLLoaderMockSocketTest, OrbClosesSocketOnSniffingMimeType) {
  orb_enabled_ = true;

  const net::MockRead kReads[] = {
      net::MockRead(net::SYNCHRONOUS, 1,
                    "HTTP/1.1 200 OK\r\n"
                    "Connection: keep-alive\r\n"
                    "Content-Type: application/json\r\n"
                    "Content-Length: 9\r\n\r\n"),
      net::MockRead(net::SYNCHRONOUS, 2, "{\"x\" : 3}"),
  };

  net::SequencedSocketData socket_data_connect(kAsyncMockConnect, {}, {});
  net::SequencedSocketData socket_data_reads_writes(kReads, kOriginTestWrites);
  socket_factory_.AddSocketDataProvider(&socket_data_connect);
  socket_factory_.AddSocketDataProvider(&socket_data_reads_writes);

  GURL url("http://origin.test/");
  url::Origin initiator =
      url::Origin::Create(GURL("http://other-origin.test/"));

  ResourceRequest request = CreateResourceRequest("GET", url);
  request.mode = mojom::RequestMode::kNoCors;
  request.request_initiator = initiator;
  std::string body;
  EXPECT_EQ(net::OK, LoadRequest(request, &body));
  EXPECT_TRUE(body.empty());

  // Socket should have been destroyed, so it will not be reused.
  EXPECT_FALSE(socket_data_reads_writes.socket());
}

TEST_F(URLLoaderMockSocketTest, CorpClosesSocket) {
  auto client_security_state = NewSecurityState();
  client_security_state->cross_origin_embedder_policy.value =
      mojom::CrossOriginEmbedderPolicyValue::kRequireCorp;
  client_security_state->local_network_access_request_policy =
      mojom::LocalNetworkAccessRequestPolicy::kAllow;
  set_factory_client_security_state(std::move(client_security_state));

  const net::MockRead kReads[] = {
      net::MockRead(net::SYNCHRONOUS, 1,
                    "HTTP/1.1 200 OK\r\n"
                    "Connection: keep-alive\r\n"
                    "Content-Type: test/plain\r\n"
                    "Content-Length: 23\r\n\r\n"),
      net::MockRead(net::SYNCHRONOUS, 2, "This should not be read"),
  };

  net::SequencedSocketData socket_data_connect(kAsyncMockConnect, {}, {});
  net::SequencedSocketData socket_data_reads_writes(kReads, kOriginTestWrites);
  socket_factory_.AddSocketDataProvider(&socket_data_connect);
  socket_factory_.AddSocketDataProvider(&socket_data_reads_writes);

  GURL url("http://origin.test/");
  url::Origin initiator =
      url::Origin::Create(GURL("http://other-origin.test/"));

  ResourceRequest request = CreateResourceRequest("GET", url);
  request.mode = mojom::RequestMode::kNoCors;
  request.request_initiator = initiator;
  EXPECT_EQ(net::ERR_BLOCKED_BY_RESPONSE, LoadRequest(request));

  // Socket should have been destroyed, so it will not be reused.
  EXPECT_FALSE(socket_data_reads_writes.socket());
}

class URLLoaderMockSocketAuctionOnlyTest
    : public URLLoaderMockSocketTest,
      public testing::WithParamInterface<std::string> {};

TEST_P(URLLoaderMockSocketAuctionOnlyTest,
       FetchAuctionOnlySignalsFromRendererClosesSocket) {
  auto client_security_state = NewSecurityState();
  client_security_state->local_network_access_request_policy =
      mojom::LocalNetworkAccessRequestPolicy::kAllow;
  set_factory_client_security_state(std::move(client_security_state));

  const std::string first_read = base::StringPrintf(
      "HTTP/1.1 200 OK\r\n"
      "Connection: keep-alive\r\n"
      "%s"
      "Content-Type: text/plain\r\n"
      "Content-Length: 23\r\n\r\n",
      GetParam().c_str());
  const net::MockRead kReads[] = {
      net::MockRead(net::SYNCHRONOUS, 1, first_read),
      net::MockRead(net::SYNCHRONOUS, 2, "This should not be read"),
  };

  net::SequencedSocketData socket_data_connect(kAsyncMockConnect, {}, {});
  net::SequencedSocketData socket_data_reads_writes(kReads, kOriginTestWrites);
  socket_factory_.AddSocketDataProvider(&socket_data_connect);
  socket_factory_.AddSocketDataProvider(&socket_data_reads_writes);

  GURL url("http://origin.test/");
  url::Origin initiator = url::Origin::Create(url);

  ResourceRequest request = CreateResourceRequest("GET", url);
  request.mode = mojom::RequestMode::kNoCors;
  request.request_initiator = initiator;

  EXPECT_EQ(net::ERR_BLOCKED_BY_RESPONSE, LoadRequest(request, /*body=*/nullptr,
                                                      /*is_trusted=*/false));

  // Socket should have been destroyed, so it will not be reused.
  EXPECT_FALSE(socket_data_reads_writes.socket());
}

TEST_P(URLLoaderMockSocketAuctionOnlyTest,
       FetchAuctionOnlySignalsFromBrowserProcessSucceeds) {
  auto client_security_state = NewSecurityState();
  client_security_state->local_network_access_request_policy =
      mojom::LocalNetworkAccessRequestPolicy::kAllow;
  set_factory_client_security_state(std::move(client_security_state));

  const std::string first_read = base::StringPrintf(
      "HTTP/1.1 200 OK\r\n"
      "Connection: keep-alive\r\n"
      "%s"
      "Content-Type: text/plain\r\n"
      "Content-Length: 23\r\n\r\n",
      GetParam().c_str());
  const net::MockRead kReads[] = {
      net::MockRead(net::SYNCHRONOUS, 1, first_read),
      net::MockRead(net::SYNCHRONOUS, 2, "This should not be read"),
  };

  net::SequencedSocketData socket_data_connect(kAsyncMockConnect, {}, {});
  net::SequencedSocketData socket_data_reads_writes(kReads, kOriginTestWrites);
  socket_factory_.AddSocketDataProvider(&socket_data_connect);
  socket_factory_.AddSocketDataProvider(&socket_data_reads_writes);

  GURL url("http://origin.test/");
  url::Origin initiator = url::Origin::Create(url);

  ResourceRequest request = CreateResourceRequest("GET", url);
  request.mode = mojom::RequestMode::kNoCors;
  request.request_initiator = initiator;
  EXPECT_EQ(net::OK,
            LoadRequest(request, /*body=*/nullptr, /*is_trusted=*/true));
  EXPECT_TRUE(socket_data_reads_writes.socket());
}

// TODO(crbug.com/40269364): Remove old names once API users have migrated to
// new names.
INSTANTIATE_TEST_SUITE_P(
    All,
    URLLoaderMockSocketAuctionOnlyTest,
    testing::Values(
        "Ad-Auction-Only: true\r\n",
        "X-FLEDGE-Auction-Only: true\r\n",
        "Ad-Auction-Only: true\r\nX-FLEDGE-Auction-Only: true\r\n"));

TEST_F(URLLoaderMockSocketTest,
       LocalNetworkAccessRequestPolicyDoesNotCloseSocket) {
  auto client_security_state = NewSecurityState();
  client_security_state->local_network_access_request_policy =
      mojom::LocalNetworkAccessRequestPolicy::kBlock;
  set_factory_client_security_state(std::move(client_security_state));

  // No data should be read or written. Trying to do so will assert.
  net::SequencedSocketData socket_data_no_reads_no_writes;
  net::SequencedSocketData socket_data_connect(kAsyncMockConnect, {}, {});
  socket_factory_.AddSocketDataProvider(&socket_data_connect);
  socket_factory_.AddSocketDataProvider(&socket_data_no_reads_no_writes);

  GURL url("http://origin.test/");
  url::Origin initiator =
      url::Origin::Create(GURL("http://other-origin.test/"));

  ResourceRequest request = CreateResourceRequest("GET", url);
  request.mode = mojom::RequestMode::kNoCors;
  request.request_initiator = initiator;
  EXPECT_EQ(net::ERR_BLOCKED_BY_LOCAL_NETWORK_ACCESS_CHECKS,
            LoadRequest(request));

  // Socket should not be closed, since it can be reused.
  EXPECT_TRUE(socket_data_no_reads_no_writes.socket());
}

TEST_F(URLLoaderMockSocketTest, SniffMime) {
  const std::string_view kTestHtml = "<html><body>hello world</body></html>";
  const net::MockRead kReads[] = {
      net::MockRead(net::SYNCHRONOUS, /*seq=*/1, "HTTP/1.1 200 OK\r\n\r\n"),
      net::MockRead(net::SYNCHRONOUS, kTestHtml,
                    /*result=*/0,
                    /*seq=*/2),
      net::MockRead(net::SYNCHRONOUS, net::OK, /*seq=*/3)};
  net::SequencedSocketData socket_data_connect(kAsyncMockConnect, {}, {});
  net::SequencedSocketData socket_data_reads_writes(kReads, kOriginTestWrites);
  socket_factory_.AddSocketDataProvider(&socket_data_connect);
  socket_factory_.AddSocketDataProvider(&socket_data_reads_writes);
  ResourceRequest request =
      CreateResourceRequest("GET", GURL("http://origin.test/"));
  set_sniff();
  std::string body;
  EXPECT_EQ(net::OK, LoadRequest(request, &body));
  EXPECT_TRUE(did_mime_sniff());
  EXPECT_EQ(mime_type(), "text/html");
  EXPECT_EQ(body, kTestHtml);
}

// Regression test for https://crbug.com/404165029. Ensures MIME sniffing works
// correctly with incremental body reads, addressing a bug where the sniffing
// hint was not properly maintained.
TEST_F(URLLoaderMockSocketTest, SniffMimeByteByByteRead) {
  const std::string_view kTestHtml = "<html><body>hello world</body></html>";
  std::vector<net::MockRead> reads;
  reads.emplace_back(net::SYNCHRONOUS, /*seq=*/reads.size() + 1,
                     "HTTP/1.1 200 OK\r\n\r\n");
  for (size_t i = 0; i < kTestHtml.size(); ++i) {
    reads.emplace_back(net::SYNCHRONOUS, kTestHtml.substr(i, 1),
                       /*result=*/0, /*seq=*/reads.size() + 1);
  }
  reads.emplace_back(net::SYNCHRONOUS, net::OK, /*seq=*/reads.size() + 1);
  net::SequencedSocketData socket_data_connect(kAsyncMockConnect, {}, {});
  net::SequencedSocketData socket_data_reads_writes(reads, kOriginTestWrites);
  socket_factory_.AddSocketDataProvider(&socket_data_connect);
  socket_factory_.AddSocketDataProvider(&socket_data_reads_writes);
  ResourceRequest request =
      CreateResourceRequest("GET", GURL("http://origin.test/"));
  set_sniff();
  std::string body;
  EXPECT_EQ(net::OK, LoadRequest(request, &body));
  EXPECT_TRUE(did_mime_sniff());
  EXPECT_EQ(mime_type(), "text/html");
  EXPECT_EQ(body, kTestHtml);
}

TEST_F(URLLoaderMockSocketTest, CompressedResponseSniffMime) {
  const std::string_view kTestHtml = "<html><body>hello world</body></html>";
  const auto compressed = net::CompressGzip(kTestHtml);
  const net::MockRead kReads[] = {
      net::MockRead(net::SYNCHRONOUS, /*seq=*/1,
                    "HTTP/1.1 200 OK\r\n"
                    "Content-Encoding: gzip\r\n\r\n"),
      net::MockRead(net::SYNCHRONOUS, base::as_string_view(compressed),
                    /*result=*/0,
                    /*seq=*/2),
      net::MockRead(net::SYNCHRONOUS, net::OK, /*seq=*/3)};
  net::SequencedSocketData socket_data_connect(kAsyncMockConnect, {}, {});
  net::SequencedSocketData socket_data_reads_writes(kReads, kOriginTestWrites);
  socket_factory_.AddSocketDataProvider(&socket_data_connect);
  socket_factory_.AddSocketDataProvider(&socket_data_reads_writes);
  ResourceRequest request =
      CreateResourceRequest("GET", GURL("http://origin.test/"));
  set_sniff();
  std::string body;
  EXPECT_EQ(net::OK, LoadRequest(request, &body));
  EXPECT_TRUE(did_mime_sniff());
  EXPECT_EQ(mime_type(), "text/html");
  EXPECT_EQ(body, kTestHtml);
}

TEST_F(URLLoaderMockSocketTest,
       CompressedResponseClienteSideDecodingSniffMimeSync) {
  const std::string_view kTestHtml = "<html><body>hello world</body></html>";
  const auto compressed = net::CompressGzip(kTestHtml);
  const net::MockRead kReads[] = {
      net::MockRead(net::SYNCHRONOUS, /*seq=*/1,
                    "HTTP/1.1 200 OK\r\n"
                    "Content-Encoding: gzip\r\n\r\n"),
      net::MockRead(net::SYNCHRONOUS, base::as_string_view(compressed),
                    /*result=*/0,
                    /*seq=*/2),
      net::MockRead(net::SYNCHRONOUS, net::OK, /*seq=*/3)};
  net::SequencedSocketData socket_data_connect(kAsyncMockConnect, {}, {});
  net::SequencedSocketData socket_data_reads_writes(kReads, kOriginTestWrites);
  socket_factory_.AddSocketDataProvider(&socket_data_connect);
  socket_factory_.AddSocketDataProvider(&socket_data_reads_writes);
  ResourceRequest request =
      CreateResourceRequest("GET", GURL("http://origin.test/"));
  set_sniff();
  // Set the flag for ClientSideContentDecoding.
  request.client_side_content_decoding_enabled = true;
  std::string body;
  EXPECT_EQ(net::OK, LoadRequest(request, &body));
  EXPECT_TRUE(did_mime_sniff());
  EXPECT_EQ(mime_type(), "text/html");

  EXPECT_THAT(body, base::as_string_view(compressed));

  EXPECT_THAT(client()->response_head()->client_side_content_decoding_types,
              ElementsAre(net::SourceStreamType::kGzip));
}

TEST_F(URLLoaderMockSocketTest,
       CompressedResponseClienteSideDecodingSniffMimeAsync) {
  const std::string_view kTestHtml = "<html><body>hello world</body></html>";
  const auto compressed = net::CompressGzip(kTestHtml);
  const net::MockRead kReads[] = {
      net::MockRead(net::ASYNC, /*seq=*/1,
                    "HTTP/1.1 200 OK\r\n"
                    "Content-Encoding: gzip\r\n\r\n"),
      net::MockRead(net::ASYNC, base::as_string_view(compressed),
                    /*result=*/0,
                    /*seq=*/2),
      net::MockRead(net::ASYNC, net::OK, /*seq=*/3)};
  net::SequencedSocketData socket_data_connect(kAsyncMockConnect, {}, {});
  net::SequencedSocketData socket_data_reads_writes(kReads, kOriginTestWrites);
  socket_factory_.AddSocketDataProvider(&socket_data_connect);
  socket_factory_.AddSocketDataProvider(&socket_data_reads_writes);
  ResourceRequest request =
      CreateResourceRequest("GET", GURL("http://origin.test/"));
  set_sniff();
  // Set the flag for ClientSideContentDecoding.
  request.client_side_content_decoding_enabled = true;
  std::string body;
  EXPECT_EQ(net::OK, LoadRequest(request, &body));
  EXPECT_TRUE(did_mime_sniff());
  EXPECT_EQ(mime_type(), "text/html");

  EXPECT_THAT(body, base::as_string_view(compressed));

  EXPECT_THAT(client()->response_head()->client_side_content_decoding_types,
              ElementsAre(net::SourceStreamType::kGzip));
}

TEST_F(URLLoaderMockSocketTest,
       CompressedResponseClienteSideDecodingSniffMimeAsyncDelaySniff) {
  const std::string_view kTestHtml = "<html><body>hello world</body></html>";
  // SniffForHTML() in mime_sniffer.cc sniffs the head 512 bytes. So add spaces
  // to delay the completion of sniffing by padding the beginning with spaces to
  // make the total 512 bytes.
  const std::string large_space_and_html =
      base::StrCat({std::string(512 - kTestHtml.size(), ' '), kTestHtml});
  const auto compressed = net::CompressGzip(large_space_and_html);
  std::vector<net::MockRead> reads;
  reads.emplace_back(net::ASYNC, /*seq=*/1,
                     "HTTP/1.1 200 OK\r\n"
                     "Content-Encoding: gzip\r\n\r\n");
  for (size_t i = 0; i < compressed.size(); ++i) {
    reads.emplace_back(net::ASYNC,
                       base::as_string_view(compressed).substr(i, 1),
                       /*result=*/0, /*seq=*/i + 2);
  }
  reads.emplace_back(net::ASYNC, net::OK, /*seq=*/compressed.size() + 2);
  net::SequencedSocketData socket_data_connect(kAsyncMockConnect, {}, {});
  net::SequencedSocketData socket_data_reads_writes(reads, kOriginTestWrites);
  socket_data_reads_writes.set_receive_buffer_size(1);
  socket_factory_.AddSocketDataProvider(&socket_data_connect);
  socket_factory_.AddSocketDataProvider(&socket_data_reads_writes);
  ResourceRequest request =
      CreateResourceRequest("GET", GURL("http://origin.test/"));
  set_sniff();
  // Set the flag for ClientSideContentDecoding.
  request.client_side_content_decoding_enabled = true;
  std::string body;
  EXPECT_EQ(net::OK, LoadRequest(request, &body));
  EXPECT_TRUE(did_mime_sniff());
  EXPECT_EQ(mime_type(), "text/html");

  EXPECT_THAT(body, base::as_string_view(compressed));

  EXPECT_THAT(client()->response_head()->client_side_content_decoding_types,
              ElementsAre(net::SourceStreamType::kGzip));
}

TEST_F(URLLoaderMockSocketTest,
       CompressedResponseClienteSideDecodingSniffMimeSyncError) {
  const net::MockRead kReads[] = {
      net::MockRead(net::SYNCHRONOUS, /*seq=*/1,
                    "HTTP/1.1 200 OK\r\n"
                    "Content-Encoding: gzip\r\n\r\n"),
      net::MockRead(net::SYNCHRONOUS, /*result=*/net::ERR_FAILED,
                    /*seq=*/2)};
  net::SequencedSocketData socket_data_connect(kAsyncMockConnect, {}, {});
  net::SequencedSocketData socket_data_reads_writes(kReads, kOriginTestWrites);
  socket_factory_.AddSocketDataProvider(&socket_data_connect);
  socket_factory_.AddSocketDataProvider(&socket_data_reads_writes);
  ResourceRequest request =
      CreateResourceRequest("GET", GURL("http://origin.test/"));
  set_sniff();
  // Set the flag for ClientSideContentDecoding.
  request.client_side_content_decoding_enabled = true;
  std::string body;
  EXPECT_EQ(net::ERR_FAILED, LoadRequest(request, &body));
  EXPECT_TRUE(body.empty());
}

TEST_F(URLLoaderMockSocketTest,
       CompressedResponseClienteSideDecodingSniffMimeAsyncError) {
  const net::MockRead kReads[] = {
      net::MockRead(net::ASYNC, /*seq=*/1,
                    "HTTP/1.1 200 OK\r\n"
                    "Content-Encoding: gzip\r\n\r\n"),
      net::MockRead(net::ASYNC, /*result=*/net::ERR_FAILED,
                    /*seq=*/2)};
  net::SequencedSocketData socket_data_connect(kAsyncMockConnect, {}, {});
  net::SequencedSocketData socket_data_reads_writes(kReads, kOriginTestWrites);
  socket_factory_.AddSocketDataProvider(&socket_data_connect);
  socket_factory_.AddSocketDataProvider(&socket_data_reads_writes);
  ResourceRequest request =
      CreateResourceRequest("GET", GURL("http://origin.test/"));
  set_sniff();
  // Set the flag for ClientSideContentDecoding.
  request.client_side_content_decoding_enabled = true;
  std::string body;
  EXPECT_EQ(net::ERR_FAILED, LoadRequest(request, &body));
  EXPECT_TRUE(body.empty());
}

TEST_F(URLLoaderMockSocketTest,
       CompressedResponseClienteSideDecodingSniffMimeSyncDecodeError) {
  const net::MockRead kReads[] = {
      net::MockRead(net::SYNCHRONOUS, /*seq=*/1,
                    "HTTP/1.1 200 OK\r\n"
                    "Content-Encoding: gzip\r\n\r\n"),
      net::MockRead(net::SYNCHRONOUS, /*seq=*/2,
                    "this is an invalid gzipped data")};
  net::SequencedSocketData socket_data_connect(kAsyncMockConnect, {}, {});
  net::SequencedSocketData socket_data_reads_writes(kReads, kOriginTestWrites);
  socket_factory_.AddSocketDataProvider(&socket_data_connect);
  socket_factory_.AddSocketDataProvider(&socket_data_reads_writes);
  ResourceRequest request =
      CreateResourceRequest("GET", GURL("http://origin.test/"));
  set_sniff();
  // Set the flag for ClientSideContentDecoding.
  request.client_side_content_decoding_enabled = true;
  std::string body;
  EXPECT_EQ(net::ERR_CONTENT_DECODING_FAILED, LoadRequest(request, &body));
  EXPECT_TRUE(body.empty());
}

TEST_F(URLLoaderMockSocketTest,
       CompressedResponseClienteSideDecodingSniffMimeAsyncDecodeError) {
  const net::MockRead kReads[] = {
      net::MockRead(net::ASYNC, /*seq=*/1,
                    "HTTP/1.1 200 OK\r\n"
                    "Content-Encoding: gzip\r\n\r\n"),
      net::MockRead(net::ASYNC, /*seq=*/2, "this is an invalid gzipped data")};
  net::SequencedSocketData socket_data_connect(kAsyncMockConnect, {}, {});
  net::SequencedSocketData socket_data_reads_writes(kReads, kOriginTestWrites);
  socket_factory_.AddSocketDataProvider(&socket_data_connect);
  socket_factory_.AddSocketDataProvider(&socket_data_reads_writes);
  ResourceRequest request =
      CreateResourceRequest("GET", GURL("http://origin.test/"));
  set_sniff();
  // Set the flag for ClientSideContentDecoding.
  request.client_side_content_decoding_enabled = true;
  std::string body;
  EXPECT_EQ(net::ERR_CONTENT_DECODING_FAILED, LoadRequest(request, &body));
  EXPECT_TRUE(body.empty());
}

TEST_F(URLLoaderMockSocketTest,
       CompressedResponseClienteSideDecodingSniffMimeEmpty) {
  const net::MockRead kReads[] = {
      net::MockRead(net::ASYNC, /*seq=*/1,
                    "HTTP/1.1 200 OK\r\n"
                    "Content-Encoding: gzip\r\n\r\n"),
      net::MockRead(net::ASYNC, /*result=*/net::OK, /*seq=*/2)};
  net::SequencedSocketData socket_data_connect(kAsyncMockConnect, {}, {});
  net::SequencedSocketData socket_data_reads_writes(kReads, kOriginTestWrites);
  socket_factory_.AddSocketDataProvider(&socket_data_connect);
  socket_factory_.AddSocketDataProvider(&socket_data_reads_writes);
  ResourceRequest request =
      CreateResourceRequest("GET", GURL("http://origin.test/"));
  set_sniff();
  // Set the flag for ClientSideContentDecoding.
  request.client_side_content_decoding_enabled = true;
  std::string body;
  EXPECT_EQ(net::OK, LoadRequest(request, &body));
  EXPECT_TRUE(body.empty());
}

TEST_F(URLLoaderMockSocketTest,
       CompressedResponseClienteSideDecodingSniffMimeSyncCancelAfterResponse) {
  const std::string_view kTestHtml = "<html><body>hello world</body></html>";
  const auto compressed = net::CompressGzip(kTestHtml);
  const net::MockRead kReads[] = {
      net::MockRead(net::SYNCHRONOUS, /*seq=*/1,
                    "HTTP/1.1 200 OK\r\n"
                    "Content-Encoding: gzip\r\n\r\n"),
      net::MockRead(net::SYNCHRONOUS, base::as_string_view(compressed),
                    /*result=*/0,
                    /*seq=*/2),
      net::MockRead(net::SYNCHRONOUS, net::OK, /*seq=*/3)};
  net::SequencedSocketData socket_data_connect(kAsyncMockConnect, {}, {});
  net::SequencedSocketData socket_data_reads_writes(kReads, kOriginTestWrites);
  socket_factory_.AddSocketDataProvider(&socket_data_connect);
  socket_factory_.AddSocketDataProvider(&socket_data_reads_writes);
  ResourceRequest request =
      CreateResourceRequest("GET", GURL("http://origin.test/"));
  // Set the flag for ClientSideContentDecoding.
  request.client_side_content_decoding_enabled = true;

  URLLoaderOptions url_loader_options;
  url_loader_options.options = mojom::kURLLoadOptionSniffMimeType;
  url_loader_options.sync_url_loader_client = client_.GetSyncClientWeakPtr();
  std::unique_ptr<URLLoader> url_loader;
  mojo::Remote<mojom::URLLoader> loader;
  base::RunLoop delete_run_loop;
  url_loader = url_loader_options.MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.BindNewPipeAndPassReceiver(), request, client_.CreateRemote());
  client_.SetResponseReceivedCallback(
      base::BindLambdaForTesting([&]() { client_.response_body_release(); }));
  delete_run_loop.Run();
}

TEST_F(URLLoaderMockSocketTest,
       CompressedResponseClienteSideDecodingOrbClosesSocketOnSniffingMimeType) {
  orb_enabled_ = true;

  const auto compressed = net::CompressGzip("{\"x\" : 3}");
  const std::string first_read = base::StringPrintf(
      "HTTP/1.1 200 OK\r\n"
      "Connection: keep-alive\r\n"
      "Content-Encoding: gzip\r\n"
      "Content-Type: application/json\r\n"
      "Content-Length: %zu\r\n\r\n",
      compressed.size());
  const net::MockRead kReads[] = {
      net::MockRead(net::SYNCHRONOUS, 1, first_read),
      net::MockRead(net::SYNCHRONOUS, base::as_string_view(compressed),
                    /*result=*/0,
                    /*seq=*/2)};

  net::SequencedSocketData socket_data_connect(kAsyncMockConnect, {}, {});
  net::SequencedSocketData socket_data_reads_writes(kReads, kOriginTestWrites);
  socket_factory_.AddSocketDataProvider(&socket_data_connect);
  socket_factory_.AddSocketDataProvider(&socket_data_reads_writes);

  GURL url("http://origin.test/");
  url::Origin initiator =
      url::Origin::Create(GURL("http://other-origin.test/"));

  ResourceRequest request = CreateResourceRequest("GET", url);
  request.mode = mojom::RequestMode::kNoCors;
  request.request_initiator = initiator;
  // Set the flag for ClientSideContentDecoding.
  request.client_side_content_decoding_enabled = true;
  std::string body;
  EXPECT_EQ(net::OK, LoadRequest(request, &body));
  EXPECT_TRUE(body.empty());

  // Socket should have been destroyed, so it will not be reused.
  EXPECT_FALSE(socket_data_reads_writes.socket());
}

// Tests the code path where client-side decompression is enabled and the
// underlying compressed data (corresponding to a chunk of data decompressed by
// the PartialDecoder) is larger than the Mojo data pipe's capacity.
TEST_F(URLLoaderMockSocketTest,
       CompressedResponseClienteSideDecodingOrbBodyLargerThanMojoPipe) {
  orb_enabled_ = true;
  const auto data_pipe_size = GetDataPipeDefaultAllocationSize(
      DataPipeAllocationSize::kLargerSizeIfPossible);
  // Configures the PartialDecoder's internal buffer size to be larger than the
  // Mojo data pipe. This ensures that when the PartialDecoder accumulates
  // enough decompressed data to exceed the Mojo pipe size, the corresponding
  // compressed data will also be larger than the pipe, triggering the specific
  // code path we want to test.
  partial_decoder_decoding_buffer_size_ = data_pipe_size + 100;

  const std::vector<uint8_t> raw_data = CreateRandomBytesWithSeed(
      /*seed=*/1234, /*size=*/data_pipe_size * 2);
  const auto compressed = net::CompressGzip(base::as_string_view(raw_data));
  // Verify that the compressed data is indeed larger than the Mojo pipe's
  // capacity, which is a prerequisite for the test scenario.
  EXPECT_GT(compressed.size(), data_pipe_size);
  const std::string first_read = base::StringPrintf(
      "HTTP/1.1 200 OK\r\n"
      "Content-Encoding: gzip\r\n"
      "Content-Type: application/json\r\n"
      "Content-Length: %zu\r\n\r\n",
      compressed.size());
  const net::MockRead kReads[] = {
      net::MockRead(net::SYNCHRONOUS, 1, first_read),
      net::MockRead(net::SYNCHRONOUS, base::as_string_view(compressed),
                    /*result=*/0,
                    /*seq=*/2)};

  net::SequencedSocketData socket_data_connect(kAsyncMockConnect, {}, {});
  net::SequencedSocketData socket_data_reads_writes(kReads, kOriginTestWrites);
  socket_factory_.AddSocketDataProvider(&socket_data_connect);
  socket_factory_.AddSocketDataProvider(&socket_data_reads_writes);

  GURL url("http://origin.test/");
  url::Origin initiator =
      url::Origin::Create(GURL("http://other-origin.test/"));

  ResourceRequest request = CreateResourceRequest("GET", url);
  request.mode = mojom::RequestMode::kNoCors;
  request.request_initiator = initiator;
  request.client_side_content_decoding_enabled = true;
  std::string body;
  EXPECT_EQ(net::OK, LoadRequest(request, &body));
  // The body might be empty if ORB blocks the response. If not blocked, we
  // expect the compressed content.
  if (!body.empty()) {
    EXPECT_THAT(body, base::as_string_view(compressed));
  }
}

TEST_F(URLLoaderMockSocketTest,
       CompressedResponseClienteSideDecodingOrbNotBlocked) {
  orb_enabled_ = true;
  const std::string_view kTestData = "            ";
  const auto compressed = net::CompressGzip(kTestData);
  const std::string first_read = base::StringPrintf(
      "HTTP/1.1 200 OK\r\n"
      "Connection: keep-alive\r\n"
      "Content-Encoding: gzip\r\n"
      "Content-Type: application/json\r\n"
      "Content-Length: %zu\r\n\r\n",
      compressed.size());
  const net::MockRead kReads[] = {
      net::MockRead(net::SYNCHRONOUS, 1, first_read),
      net::MockRead(net::SYNCHRONOUS, base::as_string_view(compressed),
                    /*result=*/0,
                    /*seq=*/2)};

  net::SequencedSocketData socket_data_connect(kAsyncMockConnect, {}, {});
  net::SequencedSocketData socket_data_reads_writes(kReads, kOriginTestWrites);
  socket_factory_.AddSocketDataProvider(&socket_data_connect);
  socket_factory_.AddSocketDataProvider(&socket_data_reads_writes);

  GURL url("http://origin.test/");
  url::Origin initiator =
      url::Origin::Create(GURL("http://other-origin.test/"));

  ResourceRequest request = CreateResourceRequest("GET", url);
  request.mode = mojom::RequestMode::kNoCors;
  request.request_initiator = initiator;
  request.client_side_content_decoding_enabled = true;
  std::string body;
  EXPECT_EQ(net::OK, LoadRequest(request, &body));
  EXPECT_THAT(body, base::as_string_view(compressed));
}

TEST_F(URLLoaderTest, WithDnsAliases) {
  GURL url(test_server_.GetURL(kHostnameWithAliases, "/echo"));

  EXPECT_EQ(net::OK, Load(url));
  ASSERT_TRUE(client_.response_head());
  EXPECT_THAT(client_.response_head()->dns_aliases,
              testing::ElementsAre("alias1", "alias2", "host"));
}

TEST_F(URLLoaderTest, NoAdditionalDnsAliases) {
  GURL url(test_server_.GetURL(kHostnameWithoutAliases, "/echo"));

  EXPECT_EQ(net::OK, Load(url));
  ASSERT_TRUE(client_.response_head());
  EXPECT_THAT(client_.response_head()->dns_aliases,
              testing::ElementsAre(kHostnameWithoutAliases));
}

TEST_F(URLLoaderTest,
       LocalNetworkRequestPolicyReportsOnLocalNetworkRequestWarn) {
  url::Origin initiator =
      url::Origin::Create(GURL("http://other-origin.test/"));

  ResourceRequest request =
      CreateResourceRequest("GET", test_server()->GetURL("/simple_page.html"));
  request.mode = mojom::RequestMode::kNoCors;
  request.request_initiator = initiator;
  request.devtools_request_id = "fake-id";

  auto client_security_state = NewSecurityState();
  client_security_state->is_web_secure_context = false;
  client_security_state->local_network_access_request_policy =
      mojom::LocalNetworkAccessRequestPolicy::kWarn;
  client_security_state->ip_address_space = mojom::IPAddressSpace::kPublic;
  set_factory_client_security_state(std::move(client_security_state));

  MockDevToolsObserver devtools_observer;
  set_devtools_observer_for_next_request(&devtools_observer);

  EXPECT_EQ(net::OK, LoadRequest(request));

  devtools_observer.WaitUntilLocalNetworkRequest();
  ASSERT_TRUE(devtools_observer.local_network_request_params());
  auto& params = *devtools_observer.local_network_request_params();
  ASSERT_TRUE(params.client_security_state);
  auto& state = params.client_security_state;
  EXPECT_EQ(state->local_network_access_request_policy,
            mojom::LocalNetworkAccessRequestPolicy::kWarn);
  EXPECT_EQ(state->is_web_secure_context, false);
  EXPECT_EQ(state->ip_address_space, mojom::IPAddressSpace::kPublic);
  EXPECT_EQ(params.resource_address_space, mojom::IPAddressSpace::kLoopback);
  EXPECT_EQ(params.devtools_request_id, "fake-id");
  EXPECT_TRUE(params.is_warning);
  EXPECT_THAT(params.url.spec(), testing::HasSubstr("simple_page.html"));
}

TEST_F(URLLoaderTest,
       LocalNetworkRequestPolicyReportsOnLocalNetworkRequestBlock) {
  url::Origin initiator =
      url::Origin::Create(GURL("http://other-origin.test/"));

  ResourceRequest request =
      CreateResourceRequest("GET", test_server()->GetURL("/simple_page.html"));
  request.mode = mojom::RequestMode::kNoCors;
  request.request_initiator = initiator;
  request.devtools_request_id = "fake-id";

  auto client_security_state = NewSecurityState();
  client_security_state->is_web_secure_context = false;
  client_security_state->local_network_access_request_policy =
      mojom::LocalNetworkAccessRequestPolicy::kBlock;
  client_security_state->ip_address_space = mojom::IPAddressSpace::kPublic;
  set_factory_client_security_state(std::move(client_security_state));

  MockDevToolsObserver devtools_observer;
  set_devtools_observer_for_next_request(&devtools_observer);

  EXPECT_EQ(net::ERR_BLOCKED_BY_LOCAL_NETWORK_ACCESS_CHECKS,
            LoadRequest(request));

  devtools_observer.WaitUntilLocalNetworkRequest();
  ASSERT_TRUE(devtools_observer.local_network_request_params());
  auto& params = *devtools_observer.local_network_request_params();
  ASSERT_TRUE(params.client_security_state);
  auto& state = params.client_security_state;
  EXPECT_EQ(state->local_network_access_request_policy,
            mojom::LocalNetworkAccessRequestPolicy::kBlock);
  EXPECT_EQ(state->is_web_secure_context, false);
  EXPECT_EQ(state->ip_address_space, mojom::IPAddressSpace::kPublic);
  EXPECT_EQ(params.resource_address_space, mojom::IPAddressSpace::kLoopback);
  EXPECT_EQ(params.devtools_request_id, "fake-id");
  EXPECT_FALSE(params.is_warning);
  EXPECT_THAT(params.url.spec(), testing::HasSubstr("simple_page.html"));
}

TEST_F(URLLoaderTest,
       LocalNetworkRequestPolicyReportsOnLocalNetworkRequestAllow) {
  url::Origin initiator =
      url::Origin::Create(GURL("http://other-origin.test/"));

  ResourceRequest request =
      CreateResourceRequest("GET", test_server()->GetURL("/simple_page.html"));
  request.mode = mojom::RequestMode::kNoCors;
  request.request_initiator = initiator;
  request.devtools_request_id = "fake-id";

  auto client_security_state = NewSecurityState();
  client_security_state->is_web_secure_context = false;
  client_security_state->local_network_access_request_policy =
      mojom::LocalNetworkAccessRequestPolicy::kAllow;
  client_security_state->ip_address_space = mojom::IPAddressSpace::kPublic;
  set_factory_client_security_state(std::move(client_security_state));

  MockDevToolsObserver devtools_observer;
  set_devtools_observer_for_next_request(&devtools_observer);

  EXPECT_EQ(net::OK, LoadRequest(request));

  // Check that OnLocalNetworkRequest wasn't triggered.
  devtools_observer.WaitUntilRawResponse(0);
  EXPECT_FALSE(devtools_observer.local_network_request_params());
}

namespace {

// A mock URLRequestJob that simulates the requirement of platform-specific
// local network access permission.
class URLRequestPlatformLocalNetworkAccessPermissionJob
    : public net::URLRequestJob {
 public:
  explicit URLRequestPlatformLocalNetworkAccessPermissionJob(
      net::URLRequest* request)
      : net::URLRequestJob(request) {}

  void Start() override {
    base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
        FROM_HERE,
        base::BindOnce(
            &URLRequestPlatformLocalNetworkAccessPermissionJob::StartAsync,
            weak_factory_.GetWeakPtr()));
  }

  void SetPlatformLocalNetworkAccessGranted() override {
    NotifyHeadersComplete();
  }

  void CancelPlatformLocalNetworkAccessRequest() override {
    NotifyStartError(net::ERR_LOCAL_NETWORK_PERMISSION_MISSING);
  }

 private:
  void StartAsync() { NotifyPlatformLocalNetworkAccessPermissionRequired(); }

  base::WeakPtrFactory<URLRequestPlatformLocalNetworkAccessPermissionJob>
      weak_factory_{this};
};

// An interceptor that creates
// URLRequestPlatformLocalNetworkAccessPermissionJob.
class PlatformLocalNetworkAccessPermissionInterceptor
    : public net::URLRequestInterceptor {
 public:
  std::unique_ptr<net::URLRequestJob> MaybeInterceptRequest(
      net::URLRequest* request) const override {
    return std::make_unique<URLRequestPlatformLocalNetworkAccessPermissionJob>(
        request);
  }
};

}  // namespace

TEST_F(URLLoaderTest, PlatformLocalNetworkPermissionWithoutObserver) {
  // Do not set network observer.
  GURL url("http://fake-endpoint");
  net::URLRequestFilter::GetInstance()->AddUrlInterceptor(
      url, std::make_unique<PlatformLocalNetworkAccessPermissionInterceptor>());

  ResourceRequest request = CreateCrossOriginResourceRequest();
  request.url = url;

  EXPECT_EQ(net::ERR_LOCAL_NETWORK_PERMISSION_MISSING, LoadRequest(request));
}

TEST_F(URLLoaderTest, PlatformLocalNetworkPermissionDenied) {
  TestURLLoaderNetworkObserver observer;
  observer.set_platform_local_network_permission_response(false);
  set_network_observer_for_next_request(&observer);

  GURL url("http://fake-endpoint");
  net::URLRequestFilter::GetInstance()->AddUrlInterceptor(
      url, std::make_unique<PlatformLocalNetworkAccessPermissionInterceptor>());

  ResourceRequest request = CreateCrossOriginResourceRequest();
  request.url = url;

  EXPECT_NE(net::OK, LoadRequest(request));
}

TEST_F(URLLoaderTest, PlatformLocalNetworkPermissionGranted) {
  TestURLLoaderNetworkObserver observer;
  observer.set_platform_local_network_permission_response(true);
  set_network_observer_for_next_request(&observer);

  GURL url("http://fake-endpoint");
  net::URLRequestFilter::GetInstance()->AddUrlInterceptor(
      url, std::make_unique<PlatformLocalNetworkAccessPermissionInterceptor>());

  ResourceRequest request = CreateCrossOriginResourceRequest();
  request.url = url;

  EXPECT_EQ(net::OK, LoadRequest(request));
}

// An empty ACCEPT_CH frame should skip the client call.
TEST_F(URLLoaderFakeTransportInfoTest, AcceptCHFrameEmptyString) {
  net::TransportInfo info = net::DefaultTransportInfo();
  info.accept_ch_frame = "";

  const GURL url("http://fake-endpoint");

  net::URLRequestFilter::GetInstance()->AddUrlInterceptor(
      url, std::make_unique<FakeTransportInfoInterceptor>(info));

  MockAcceptCHFrameObserver accept_ch_frame_observer;
  set_accept_ch_frame_observer_for_next_request(&accept_ch_frame_observer);

  // Despite its name, IsError(OK) asserts that the matched value is OK.
  EXPECT_THAT(Load(url), IsError(net::OK));
  EXPECT_FALSE(accept_ch_frame_observer.called());
}

TEST_F(URLLoaderFakeTransportInfoTest, AcceptCHFrameParseString) {
  net::TransportInfo info = net::DefaultTransportInfo();
  info.accept_ch_frame = "Sec-CH-UA-Platform";

  const GURL url("http://fake-endpoint");

  net::URLRequestFilter::GetInstance()->AddUrlInterceptor(
      url, std::make_unique<FakeTransportInfoInterceptor>(info));

  MockAcceptCHFrameObserver accept_ch_frame_observer;
  set_accept_ch_frame_observer_for_next_request(&accept_ch_frame_observer);

  // Despite its name, IsError(OK) asserts that the matched value is OK.
  EXPECT_THAT(Load(url), IsError(net::OK));
  EXPECT_THAT(
      accept_ch_frame_observer.accept_ch_frame(),
      testing::ElementsAreArray({mojom::WebClientHintsType::kUAPlatform}));
}

TEST_F(URLLoaderFakeTransportInfoTest, AcceptCHFrameRemoveDuplicates) {
  net::TransportInfo info = net::DefaultTransportInfo();
  info.accept_ch_frame = "Sec-CH-UA-Platform, Sec-CH-UA-Model";

  net::HttpRequestHeaders headers;
  headers.SetHeader("Sec-CH-UA-Model", "foo");
  set_additional_headers(headers);

  const GURL url("http://fake-endpoint");

  net::URLRequestFilter::GetInstance()->AddUrlInterceptor(
      url, std::make_unique<FakeTransportInfoInterceptor>(info));

  MockAcceptCHFrameObserver accept_ch_frame_observer;
  set_accept_ch_frame_observer_for_next_request(&accept_ch_frame_observer);

  EXPECT_THAT(Load(url), IsError(net::OK));
  // Headers should be de-dupped.
  EXPECT_THAT(
      accept_ch_frame_observer.accept_ch_frame(),
      testing::ElementsAreArray({mojom::WebClientHintsType::kUAPlatform}));
}

TEST_F(URLLoaderFakeTransportInfoTest, AcceptCHFrameIgnoreMalformed) {
  net::TransportInfo info = net::DefaultTransportInfo();
  // Non-existent hint.
  info.accept_ch_frame = "Foo";

  const GURL url("http://fake-endpoint");

  net::URLRequestFilter::GetInstance()->AddUrlInterceptor(
      url, std::make_unique<FakeTransportInfoInterceptor>(info));

  MockAcceptCHFrameObserver accept_ch_frame_observer;
  set_accept_ch_frame_observer_for_next_request(&accept_ch_frame_observer);

  // Despite its name, IsError(OK) asserts that the matched value is OK.
  EXPECT_THAT(Load(url), IsError(net::OK));
  EXPECT_FALSE(accept_ch_frame_observer.called());
}

// Test that a request that triggers both Local Network Access checks and
// ACCEPT_CH frame processing is handled correctly.
TEST_F(URLLoaderFakeTransportInfoTest, LocalNetworkAccessAndAcceptCHFrame) {
  // Set up enforcement of Local Network Access checks.
  base::test::ScopedFeatureList feature_list(
      features::kLocalNetworkAccessChecks);
  auto client_security_state = NewSecurityState();
  client_security_state->ip_address_space = mojom::IPAddressSpace::kPublic;
  client_security_state->local_network_access_request_policy =
      mojom::LocalNetworkAccessRequestPolicy::kPermissionBlock;
  set_factory_client_security_state(std::move(client_security_state));

  // Simulate that the permission request was granted.
  TestLNAPermissionURLLoaderNetworkObserver observer(
      mojom::LocalNetworkAccessResult::kGranted);
  set_network_observer_for_next_request(&observer);

  // Set up ACCEPT_CH frame.
  net::TransportInfo info = net::DefaultTransportInfo();
  info.accept_ch_frame = "Sec-CH-UA-Platform";

  // Trigger a cross-origin resource request that goes to a target URL that will
  // have an ACCEPT_CH frame.
  ResourceRequest request = CreateCrossOriginResourceRequest();
  net::URLRequestFilter::GetInstance()->AddUrlInterceptor(
      request.url, std::make_unique<FakeTransportInfoInterceptor>(info));
  MockAcceptCHFrameObserver accept_ch_frame_observer;
  set_accept_ch_frame_observer_for_next_request(&accept_ch_frame_observer);

  // Despite its name, IsError(OK) asserts that the matched value is OK.
  EXPECT_EQ(net::OK, LoadRequest(request));
  EXPECT_THAT(
      accept_ch_frame_observer.accept_ch_frame(),
      testing::ElementsAreArray({mojom::WebClientHintsType::kUAPlatform}));
}

TEST_F(URLLoaderTest, CookieSettingOverridesCopiedToURLRequest) {
  GURL url = test_server()->GetURL("/simple_page.html");
  net::CookieSettingOverrides cookie_setting_overrides =
      net::CookieSettingOverrides::All();
  // The overrides are not allowed to start out with the
  // `kStorageAccessGrantEligible` or `kStorageAccessGrantEligibleViaHeader`
  // overrides present.
  cookie_setting_overrides.Remove(
      net::CookieSettingOverride::kStorageAccessGrantEligible);
  cookie_setting_overrides.Remove(
      net::CookieSettingOverride::kStorageAccessGrantEligibleViaHeader);

  set_cookie_setting_overrides(cookie_setting_overrides);
  bool was_intercepted = false;
  net::URLRequestFilter::GetInstance()->AddUrlInterceptor(
      url, std::make_unique<ExpectCookieSettingOverridesURLRequestInterceptor>(
               cookie_setting_overrides, &was_intercepted));

  EXPECT_THAT(Load(url), IsOk());
  EXPECT_TRUE(was_intercepted);
}

TEST_F(URLLoaderTest, ReadAndDiscardBody) {
  const std::string file = "simple_page.html";
  const GURL url = test_server()->GetURL("/" + file);
  std::optional<int64_t> file_size = base::GetFileSize(GetTestFilePath(file));
  ASSERT_THAT(file_size, Optional(Ge(0)));
  const base::ByteSize actual_size(base::as_unsigned(file_size.value()));

  TestURLLoaderClient loader_client;
  ResourceRequest request = CreateResourceRequest("GET", url);
  SetUpContext(url, /*is_trusted=*/true);
  URLLoaderOptions url_loader_options;
  url_loader_options.options = mojom::kURLLoadOptionReadAndDiscardBody;
  std::unique_ptr<URLLoader> url_loader;
  base::RunLoop delete_run_loop;
  mojo::Remote<mojom::URLLoader> loader;
  url_loader = url_loader_options.MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.BindNewPipeAndPassReceiver(), request,
      loader_client.CreateRemote());
  loader_client.RunUntilResponseReceived();

  // Response body should not be set.
  EXPECT_FALSE(loader_client.response_body().is_valid());

  loader_client.RunUntilComplete();
  const auto& completion_status = loader_client.completion_status();
  EXPECT_EQ(completion_status.error_code, net::OK);
  EXPECT_EQ(completion_status.decoded_body_length, actual_size);
  EXPECT_EQ(completion_status.encoded_body_length, actual_size);

  delete_run_loop.Run();
}

// These tests verify that LoadTimingInternalInfo is only set for trustworthy
// loaders.

TEST_F(URLLoaderTest, SetLoadTimingInternalInfoForTrustedLoaders) {
  GURL url = test_server()->GetURL("/hello.html");

  ResourceRequest request = CreateResourceRequest("GET", url);
  ASSERT_TRUE(request.trusted_params);

  base::RunLoop delete_run_loop;
  mojo::PendingRemote<mojom::URLLoader> loader;
  std::unique_ptr<URLLoader> url_loader;
  context().mutable_factory_params().process_id =
      OriginatingProcessId::browser();
  url_loader = URLLoaderOptions().MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.InitWithNewPipeAndPassReceiver(), request,
      client()->CreateRemote());

  client()->RunUntilResponseBodyArrived();
  EXPECT_TRUE(client()->response_head()->load_timing_internal_info);
}

TEST_F(URLLoaderTest, DoNotSetLoadTimingInternalInfoForUntrustedLoaders) {
  GURL url = test_server()->GetURL("/hello.html");

  ResourceRequest request = CreateResourceRequest("GET", url);
  // Clear trusted_params.
  request.trusted_params = std::nullopt;

  base::RunLoop delete_run_loop;
  mojo::PendingRemote<mojom::URLLoader> loader;
  std::unique_ptr<URLLoader> url_loader;
  context().mutable_factory_params().process_id =
      OriginatingProcessId::browser();
  url_loader = URLLoaderOptions().MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.InitWithNewPipeAndPassReceiver(), request,
      client()->CreateRemote());

  client()->RunUntilResponseBodyArrived();
  EXPECT_FALSE(client()->response_head()->load_timing_internal_info);
}

TEST_F(URLLoaderTest, AcceptCHFrameHintsAlreadyEnabledSkipsObserver) {
  base::test::ScopedFeatureList feature_list;
  feature_list.InitAndEnableFeature(features::kOffloadAcceptCHFrameCheck);

  // 1. Prepare TransportInfo with the ACCEPT_CH frame.
  net::TransportInfo info = net::DefaultTransportInfo();
  info.accept_ch_frame = "Sec-CH-UA-Platform";

  const GURL url("https://fake-endpoint");
  net::URLRequestFilter::GetInstance()->AddUrlInterceptor(
      url, std::make_unique<FakeTransportInfoInterceptor>(info));

  // 2. Set up MockAcceptCHFrameObserver.
  MockAcceptCHFrameObserver accept_ch_frame_observer;
  set_accept_ch_frame_observer_for_next_request(&accept_ch_frame_observer);

  // 3. Set enabled_client_hints.
  network::ResourceRequest::TrustedParams::EnabledClientHints
      enabled_client_hints;
  enabled_client_hints.origin = url::Origin::Create(url);
  enabled_client_hints.is_outermost_main_frame = true;
  enabled_client_hints.hints = std::vector<mojom::WebClientHintsType>{
      mojom::WebClientHintsType::kUAPlatform};
  set_enabled_client_hints_for_next_request(enabled_client_hints);

  // 4. Load, expecting net::OK.
  EXPECT_THAT(Load(url), IsOk());

  // 5. the observer should not be called because NeedsObserverCheck() returns
  // false.
  EXPECT_FALSE(accept_ch_frame_observer.called());
}

TEST_F(URLLoaderTest, AcceptCHFrameNewHintsCallsObserver) {
  base::test::ScopedFeatureList feature_list;
  feature_list.InitAndEnableFeature(features::kOffloadAcceptCHFrameCheck);

  net::TransportInfo info = net::DefaultTransportInfo();
  info.accept_ch_frame = "Sec-CH-UA-Platform";

  const GURL url("https://fake-endpoint");
  net::URLRequestFilter::GetInstance()->AddUrlInterceptor(
      url, std::make_unique<FakeTransportInfoInterceptor>(info));

  MockAcceptCHFrameObserver accept_ch_frame_observer;
  set_accept_ch_frame_observer_for_next_request(&accept_ch_frame_observer);

  // Ensure the client hints is an empty, and not hitting the hints.
  network::ResourceRequest::TrustedParams::EnabledClientHints
      enabled_client_hints;
  enabled_client_hints.origin = url::Origin::Create(url);
  set_enabled_client_hints_for_next_request(enabled_client_hints);

  EXPECT_THAT(Load(url), IsOk());

  // The observer should not be called because `NeedsObserverCheck()`
  // returns true.
  EXPECT_TRUE(accept_ch_frame_observer.called());
  EXPECT_THAT(accept_ch_frame_observer.accept_ch_frame(),
              testing::ElementsAre(mojom::WebClientHintsType::kUAPlatform));
}

// Tests that for loading a cached local network resource, the kRetryDueToCache
// LNA permission result is mapped to the correct error code to trigger a retry
// over the network.
//
// This test uses a FakeTransportInfo, which means this does not test the
// underlying HTTP/cache layers.
TEST_F(URLLoaderFakeTransportInfoTest,
       LocalNetworkAccessCachedResourceRetryOverNetwork) {
  base::test::ScopedFeatureList feature_list(
      features::kLocalNetworkAccessChecks);
  auto client_security_state = NewSecurityState();
  client_security_state->ip_address_space = mojom::IPAddressSpace::kPublic;
  client_security_state->local_network_access_request_policy =
      mojom::LocalNetworkAccessRequestPolicy::kPermissionBlock;
  set_factory_client_security_state(std::move(client_security_state));

  // Simulate a cached resource and that the permission request would ask.
  net::TransportInfo info = net::DefaultTransportInfo();
  info.type = net::TransportType::kCached;
  auto interceptor = std::make_unique<FakeTransportInfoInterceptor>(info);
  net::URLRequestFilter::GetInstance()->AddUrlInterceptor(
      GURL("http://fake-endpoint"), std::move(interceptor));

  TestLNAPermissionURLLoaderNetworkObserver observer(
      mojom::LocalNetworkAccessResult::kRetryDueToCache);
  set_network_observer_for_next_request(&observer);

  ResourceRequest request = CreateCrossOriginResourceRequest();

  // RetryDueToCache should get mapped to the LNA error code that will signal to
  // the HTTP cache to send the request to the network.
  EXPECT_EQ(
      net::ERR_CACHED_IP_ADDRESS_SPACE_BLOCKED_BY_LOCAL_NETWORK_ACCESS_POLICY,
      LoadRequest(request));
}

// Tests that a local network request loaded directly (not cached) should result
// in a regular LNA error code.
//
// This test uses a FakeTransportInfo, which means this does not test the
// underlying HTTP/cache layers.
TEST_F(URLLoaderFakeTransportInfoTest,
       LocalNetworkAccessNonCachedResourceNoRetry) {
  base::test::ScopedFeatureList feature_list(
      features::kLocalNetworkAccessChecks);
  auto client_security_state = NewSecurityState();
  client_security_state->ip_address_space = mojom::IPAddressSpace::kPublic;
  client_security_state->local_network_access_request_policy =
      mojom::LocalNetworkAccessRequestPolicy::kPermissionBlock;
  set_factory_client_security_state(std::move(client_security_state));

  // Simulate a direct network request and that the permission request would be
  // denied.
  net::TransportInfo info = net::DefaultTransportInfo();
  info.type = net::TransportType::kDirect;
  auto interceptor = std::make_unique<FakeTransportInfoInterceptor>(info);
  net::URLRequestFilter::GetInstance()->AddUrlInterceptor(
      GURL("http://fake-endpoint"), std::move(interceptor));

  TestLNAPermissionURLLoaderNetworkObserver observer(
      mojom::LocalNetworkAccessResult::kDenied);
  set_network_observer_for_next_request(&observer);

  ResourceRequest request = CreateCrossOriginResourceRequest();

  EXPECT_EQ(net::ERR_BLOCKED_BY_LOCAL_NETWORK_ACCESS_CHECKS,
            LoadRequest(request));
}


#if BUILDFLAG(IS_ANDROID)
TEST_F(URLLoaderTest, SocketTaggingWorks) {
  if (!net::CanGetTaggedBytes()) {
    GTEST_SKIP() << "Skipping test - GetTaggedBytes unsupported.";
  }
  GURL url = test_server()->GetURL("/empty.html");
  ResourceRequest request = CreateResourceRequest("GET", url);
  request.request_initiator = url::Origin::Create(url);
  int32_t tag_val = 0x12345678;
  uint64_t old_traffic = net::GetTaggedBytes(tag_val);
  request.socket_tag = net::SocketTag(-1, tag_val);

  EXPECT_EQ(net::OK, LoadRequest(request));
  EXPECT_GT(net::GetTaggedBytes(tag_val), old_traffic);
}
#endif

TEST_F(URLLoaderTest, ParseUnencodedDigest) {
  base::RunLoop delete_run_loop;
  ResourceRequest request = CreateResourceRequest(
      "GET", test_server_.GetURL(
                 "/set-header?" +
                 base::EscapeQueryParamValue(
                     "Unencoded-Digest: "
                     "sha-256=:uU0nuZNNPgilLlLX2n2r+sSE7+N6U4DukIj3rOLvzek=:",
                     /*use_plus=*/false)));

  mojo::PendingRemote<mojom::URLLoader> loader;
  std::unique_ptr<URLLoader> url_loader;
  url_loader = URLLoaderOptions().MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.InitWithNewPipeAndPassReceiver(), request,
      client()->CreateRemote());

  client()->RunUntilComplete();
  delete_run_loop.Run();

  ASSERT_TRUE(client()->response_head()->unencoded_digests->issues.empty());
  ASSERT_FALSE(client()->response_head()->unencoded_digests->digests.empty());
  std::optional<IntegrityMetadata> expected =
      IntegrityMetadata::CreateFromBase64(
          network::mojom::IntegrityAlgorithm::kSha256,
          "uU0nuZNNPgilLlLX2n2r+sSE7+N6U4DukIj3rOLvzek=");
  ASSERT_TRUE(expected);
  EXPECT_EQ(expected, client()->response_head()->unencoded_digests->digests[0]);
}

class ExpectIgnoreUnsafeMethodForSameSiteLax
    : public net::URLRequestInterceptor {
 public:
  explicit ExpectIgnoreUnsafeMethodForSameSiteLax(bool expected_value)
      : expected_value_(expected_value) {}

  std::unique_ptr<net::URLRequestJob> MaybeInterceptRequest(
      net::URLRequest* request) const override {
    EXPECT_EQ(expected_value_,
              request->ignore_unsafe_method_for_same_site_lax());
    return nullptr;
  }

 private:
  const bool expected_value_;
};

TEST_F(URLLoaderTest, IgnoreUnsafeMethodForSameSiteLaxIsTrue) {
  base::test::ScopedFeatureList feature_list;
  feature_list.InitAndEnableFeature(features::kSendSameSiteLaxForFedCM);

  GURL request_url = test_server()->GetURL("/simple_page.html");
  ResourceRequest request = CreateResourceRequest("POST", request_url);
  request.destination = mojom::RequestDestination::kWebIdentity;
  request.redirect_mode = mojom::RedirectMode::kError;

  net::URLRequestFilter::GetInstance()->AddUrlInterceptor(
      request_url,
      std::make_unique<ExpectIgnoreUnsafeMethodForSameSiteLax>(true));
  EXPECT_THAT(LoadRequest(request), IsOk());
}

TEST_F(URLLoaderTest, IgnoreUnsafeMethodForSameSiteLaxIsFalseWithoutFlag) {
  // Feature flag not enabled.
  GURL request_url = test_server()->GetURL("/simple_page.html");
  ResourceRequest request = CreateResourceRequest("POST", request_url);
  request.destination = mojom::RequestDestination::kWebIdentity;
  request.redirect_mode = mojom::RedirectMode::kError;

  net::URLRequestFilter::GetInstance()->AddUrlInterceptor(
      request_url,
      std::make_unique<ExpectIgnoreUnsafeMethodForSameSiteLax>(false));
  EXPECT_THAT(LoadRequest(request), IsOk());
}

TEST_F(URLLoaderTest,
       IgnoreUnsafeMethodForSameSiteLaxIsFalseForNonWebidentity) {
  base::test::ScopedFeatureList feature_list;
  feature_list.InitAndEnableFeature(features::kSendSameSiteLaxForFedCM);

  GURL request_url = test_server()->GetURL("/simple_page.html");
  ResourceRequest request = CreateResourceRequest("POST", request_url);
  request.redirect_mode = mojom::RedirectMode::kError;

  net::URLRequestFilter::GetInstance()->AddUrlInterceptor(
      request_url,
      std::make_unique<ExpectIgnoreUnsafeMethodForSameSiteLax>(false));
  EXPECT_THAT(LoadRequest(request), IsOk());
}

TEST_F(URLLoaderTest, PerformSyntheticResponseFallbackFailure) {
  GURL request_url("https://example.com/fallback");
  ResourceRequest request = CreateResourceRequest("GET", request_url);

  // Set up expected headers for synthetic response.
  std::string expected_headers_str =
      "HTTP/1.1 200 OK\n"
      "Content-type: text/html\n"
      "\n";
  request.trusted_params->expected_response_headers_for_synthetic_response =
      base::MakeRefCounted<net::HttpResponseHeaders>(
          net::HttpUtil::AssembleRawHeaders(expected_headers_str));

  // Set up an interceptor that returns DIFFERENT headers to trigger fallback.
  std::string actual_headers_str =
      "HTTP/1.1 200 OK\n"
      "Content-type: text/plain\n"
      "\n";
  net::URLRequestFilter::GetInstance()->AddUrlInterceptor(
      request_url, std::make_unique<SyntheticResponseFallbackInterceptor>(
                       actual_headers_str, "actual body"));

  // Create a data pipe with a very small buffer to cause
  // WriteSyntheticResponseFallbackBody to fail.
  // The fallback body is 45 bytes, so 32 bytes should be enough to cause failure.
  mojo::ScopedDataPipeProducerHandle producer;
  mojo::ScopedDataPipeConsumerHandle consumer;
  MojoCreateDataPipeOptions options;
  options.struct_size = sizeof(MojoCreateDataPipeOptions);
  options.flags = MOJO_CREATE_DATA_PIPE_FLAG_NONE;
  options.element_num_bytes = 1;
  options.capacity_num_bytes = 32;
  ASSERT_EQ(MOJO_RESULT_OK, mojo::CreateDataPipe(&options, producer, consumer));

  request.trusted_params->response_body_stream =
      base::MakeRefCounted<network::SharedDataPipeProducerHandle>(
          std::move(producer));

  // Load the request and expect it to fail with net::ERR_INSUFFICIENT_RESOURCES.
  EXPECT_EQ(net::ERR_INSUFFICIENT_RESOURCES, LoadRequest(request));
}

TEST_F(URLLoaderTest, LogsRequestedUrlLengthForLongUrls) {
  base::HistogramTester histogram_tester;
  std::string long_path(8200, 'a');
  GURL long_url = test_server()->GetURL("/" + long_path);

  ResourceRequest request = CreateResourceRequest("GET", long_url);
  EXPECT_EQ(LoadRequest(request), net::OK);

  histogram_tester.ExpectUniqueSample(
      "Net.RequestedUrlLength", long_url.GetWithoutRef().spec().length(), 1);
}

TEST_F(URLLoaderTest, DoesNotLogRequestedUrlLengthForShortUrls) {
  base::HistogramTester histogram_tester;
  size_t base_len = test_server()->GetURL("/").spec().length();
  std::string path(1000 - base_len, 'a');
  GURL short_url = test_server()->GetURL("/" + path);
  ASSERT_EQ(1000u, short_url.spec().length());

  ResourceRequest request = CreateResourceRequest("GET", short_url);
  EXPECT_EQ(LoadRequest(request), net::OK);

  histogram_tester.ExpectTotalCount("Net.RequestedUrlLength", 0);
}

TEST_F(URLLoaderTest,
       PrivateVerificationTokens_TokenRemovedWhenCookiesPresent) {
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndEnableFeature(
      net::features::kEnablePrivateVerificationTokens);

  GURL cookie_url = test_server()->GetURL("/");
  auto cookie = net::CanonicalCookie::CreateForTesting(
      cookie_url, "foo=bar", base::Time::Now(), net::CookieSourceType::kOther);
  base::RunLoop run_loop;
  url_request_context()->cookie_store()->SetCanonicalCookieAsync(
      std::move(cookie), cookie_url, net::CookieOptions::MakeAllInclusive(),
      base::BindLambdaForTesting([&](net::CookieAccessResult result) {
        EXPECT_TRUE(result.status.IsInclude());
        run_loop.Quit();
      }),
      /*cookie_access_result=*/std::nullopt);
  run_loop.Run();

  ResourceRequest request = CreateResourceRequest(
      "GET",
      test_server()->GetURL("/echoheader?Sec-Private-Verification-Token"));
  request.headers.SetHeader(
      net::HttpRequestHeaders::kSecPrivateVerificationToken, "test_token");

  std::string body;
  EXPECT_EQ(LoadRequest(request, &body), net::OK);
  EXPECT_EQ("None", body);
  ASSERT_TRUE(client_.response_head());
  EXPECT_TRUE(client_.response_head()->pvt_token_removed_due_to_cookies);
}

TEST_F(URLLoaderTest,
       PrivateVerificationTokens_TokenRetainedWhenNoCookiesPresent) {
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndEnableFeature(
      net::features::kEnablePrivateVerificationTokens);

  ResourceRequest request = CreateResourceRequest(
      "GET",
      test_server()->GetURL("/echoheader?Sec-Private-Verification-Token"));
  request.headers.SetHeader(
      net::HttpRequestHeaders::kSecPrivateVerificationToken, "test_token");

  std::string body;
  EXPECT_EQ(LoadRequest(request, &body), net::OK);
  EXPECT_EQ("test_token", body);
  ASSERT_TRUE(client_.response_head());
  EXPECT_FALSE(client_.response_head()->pvt_token_removed_due_to_cookies);
}

TEST_F(URLLoaderTest,
       PrivateVerificationTokens_FeatureDisabled_TokenNotRemoved) {
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndDisableFeature(
      net::features::kEnablePrivateVerificationTokens);

  GURL cookie_url = test_server()->GetURL("/");
  auto cookie = net::CanonicalCookie::CreateForTesting(
      cookie_url, "foo=bar", base::Time::Now(), net::CookieSourceType::kOther);
  base::RunLoop run_loop;
  url_request_context()->cookie_store()->SetCanonicalCookieAsync(
      std::move(cookie), cookie_url, net::CookieOptions::MakeAllInclusive(),
      base::BindLambdaForTesting([&](net::CookieAccessResult result) {
        EXPECT_TRUE(result.status.IsInclude());
        run_loop.Quit();
      }),
      /*cookie_access_result=*/std::nullopt);
  run_loop.Run();

  ResourceRequest request = CreateResourceRequest(
      "GET",
      test_server()->GetURL("/echoheader?Sec-Private-Verification-Token"));
  request.headers.SetHeader(
      net::HttpRequestHeaders::kSecPrivateVerificationToken, "test_token");

  std::string body;
  EXPECT_EQ(LoadRequest(request, &body), net::OK);
  EXPECT_EQ("test_token", body);
  ASSERT_TRUE(client_.response_head());
  EXPECT_FALSE(client_.response_head()->pvt_token_removed_due_to_cookies);
}

TEST_F(URLLoaderTest,
       PrivateVerificationTokens_TokenRemovedWhenCookiesFromBrowserPresent) {
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndEnableFeature(
      net::features::kEnablePrivateVerificationTokens);

  ResourceRequest request = CreateResourceRequest(
      "GET",
      test_server()->GetURL("/echoheader?Sec-Private-Verification-Token"));
  request.trusted_params.emplace();
  request.trusted_params->allow_cookies_from_browser = true;
  request.headers.SetHeader(net::HttpRequestHeaders::kCookie,
                            "browser_cookie=val");
  request.headers.SetHeader(
      net::HttpRequestHeaders::kSecPrivateVerificationToken, "test_token");

  std::string body;
  EXPECT_EQ(LoadRequest(request, &body), net::OK);
  EXPECT_EQ("None", body);
  ASSERT_TRUE(client_.response_head());
  EXPECT_TRUE(client_.response_head()->pvt_token_removed_due_to_cookies);
}

TEST_F(URLLoaderTest,
       PrivateVerificationTokens_Redirect_TokenRemovedOnFirstLegOnly) {
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndEnableFeature(
      net::features::kEnablePrivateVerificationTokens);

  GURL cookie_url = test_server()->GetURL("/server-redirect");
  auto cookie = net::CanonicalCookie::CreateForTesting(
      cookie_url, "foo=bar", base::Time::Now(), net::CookieSourceType::kOther);
  base::RunLoop run_loop;
  url_request_context()->cookie_store()->SetCanonicalCookieAsync(
      std::move(cookie), cookie_url, net::CookieOptions::MakeAllInclusive(),
      base::BindLambdaForTesting([&](net::CookieAccessResult result) {
        EXPECT_TRUE(result.status.IsInclude());
        run_loop.Quit();
      }),
      /*cookie_access_result=*/std::nullopt);
  run_loop.Run();

  ResourceRequest request = CreateResourceRequest(
      "GET",
      test_server()->GetURL(
          "/server-redirect?/echoheader?Sec-Private-Verification-Token"));
  request.headers.SetHeader(
      net::HttpRequestHeaders::kSecPrivateVerificationToken, "test_token");

  base::RunLoop delete_run_loop;
  mojo::Remote<mojom::URLLoader> loader;
  std::unique_ptr<URLLoader> url_loader;
  context().mutable_factory_params().process_id =
      OriginatingProcessId::browser();
  context().mutable_factory_params().is_orb_enabled = false;
  url_loader = URLLoaderOptions().MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.BindNewPipeAndPassReceiver(), request, client()->CreateRemote());

  client()->RunUntilRedirectReceived();
  ASSERT_TRUE(client()->response_head());
  // The token was removed on leg 1 due to cookies being present on
  // /server-redirect.
  EXPECT_TRUE(client()->response_head()->pvt_token_removed_due_to_cookies);

  loader->FollowRedirect(/*headers_update_params=*/{},
                         /*new_url=*/std::nullopt);
  client()->ClearHasReceivedRedirect();
  client()->RunUntilResponseBodyArrived();
  std::string body = ReadBody();
  client()->RunUntilComplete();

  EXPECT_EQ("None", body);
  ASSERT_TRUE(client()->response_head());
  // The redirect hop reset the flag, and leg 2 did not remove the token due to
  // cookies.
  EXPECT_FALSE(client()->response_head()->pvt_token_removed_due_to_cookies);
}

TEST_F(
    URLLoaderTest,
    PrivateVerificationTokens_AuthChallenge_TokenRemovedPersistedAcrossRestarts) {
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndEnableFeature(
      net::features::kEnablePrivateVerificationTokens);

  net::test_server::EmbeddedTestServer auth_server;
  auth_server.AddDefaultHandlers();

  // Monitor all requests to ensure the token is never sent on the wire.
  // We expect no token on either the first attempt or the post-auth retry,
  // because cookies are present on the domain, causing the token to be stripped
  // proactively.
  bool auth_request_received = false;
  auth_server.RegisterRequestMonitor(base::BindLambdaForTesting(
      [&](const net::test_server::HttpRequest& request) {
        if (request.relative_url.find("/auth-basic") == 0) {
          auth_request_received = true;
          EXPECT_FALSE(request.headers.contains(
              net::HttpRequestHeaders::kSecPrivateVerificationToken));
        }
      }));

  ASSERT_TRUE(auth_server.Start());

  GURL cookie_url = auth_server.GetURL("/");
  auto cookie = net::CanonicalCookie::CreateForTesting(
      cookie_url, "foo=bar", base::Time::Now(), net::CookieSourceType::kOther);
  base::RunLoop run_loop;
  url_request_context()->cookie_store()->SetCanonicalCookieAsync(
      std::move(cookie), cookie_url, net::CookieOptions::MakeAllInclusive(),
      base::BindLambdaForTesting([&](net::CookieAccessResult result) {
        EXPECT_TRUE(result.status.IsInclude());
        run_loop.Quit();
      }),
      /*cookie_access_result=*/std::nullopt);
  run_loop.Run();

  ClientCertAndHttpAuthObserver client_auth_observer;
  client_auth_observer.set_credentials_response(
      ClientCertAndHttpAuthObserver::CredentialsResponse::CORRECT_CREDENTIALS);

  ResourceRequest request =
      CreateResourceRequest("GET", auth_server.GetURL(kTestAuthURL));
  request.headers.SetHeader(
      net::HttpRequestHeaders::kSecPrivateVerificationToken, "test_token");

  base::RunLoop delete_run_loop;
  mojo::Remote<mojom::URLLoader> loader;
  context().mutable_factory_params().process_id = kProcessId;
  context().mutable_factory_params().is_orb_enabled = false;
  URLLoaderOptions url_loader_options;
  url_loader_options.url_loader_network_observer = client_auth_observer.Bind();
  std::unique_ptr<URLLoader> url_loader = url_loader_options.MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.BindNewPipeAndPassReceiver(), request, client()->CreateRemote());

  client()->RunUntilComplete();
  EXPECT_TRUE(client()->has_received_completion());
  // Verify that an authentication challenge was encountered and resolved.
  EXPECT_TRUE(auth_request_received);
  EXPECT_EQ(1, client_auth_observer.on_auth_required_call_counter());
  ASSERT_TRUE(client()->response_head());
  // The token removal flag persisted across the internal auth retry restart.
  EXPECT_TRUE(client()->response_head()->pvt_token_removed_due_to_cookies);
}

TEST_F(URLLoaderTest,
       PrivateVerificationTokens_Redirect_NoCookies_TokenStrippedOnRedirect) {
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndEnableFeature(
      net::features::kEnablePrivateVerificationTokens);

  ResourceRequest request = CreateResourceRequest(
      "GET",
      test_server()->GetURL(
          "/server-redirect?/echoheader?Sec-Private-Verification-Token"));
  request.headers.SetHeader(
      net::HttpRequestHeaders::kSecPrivateVerificationToken, "test_token");

  base::RunLoop delete_run_loop;
  mojo::Remote<mojom::URLLoader> loader;
  std::unique_ptr<URLLoader> url_loader;
  context().mutable_factory_params().process_id =
      OriginatingProcessId::browser();
  context().mutable_factory_params().is_orb_enabled = false;
  url_loader = URLLoaderOptions().MakeURLLoader(
      context(), DeleteLoaderCallback(&delete_run_loop, &url_loader),
      loader.BindNewPipeAndPassReceiver(), request, client()->CreateRemote());

  client()->RunUntilRedirectReceived();
  ASSERT_TRUE(client()->response_head());
  // On leg 1, no cookies were present, so the token was not removed due to
  // cookies.
  EXPECT_FALSE(client()->response_head()->pvt_token_removed_due_to_cookies);

  // Follow redirect without providing any removed_headers in parameters.
  loader->FollowRedirect(/*headers_update_params=*/{},
                         /*new_url=*/std::nullopt);
  client()->ClearHasReceivedRedirect();
  client()->RunUntilResponseBodyArrived();
  std::string body = ReadBody();
  client()->RunUntilComplete();

  // The server receives no token header on leg 2 because
  // URLLoader::FollowRedirect() automatically stripped the single-hop
  // Sec-Private-Verification-Token header.
  EXPECT_EQ("None", body);
  ASSERT_TRUE(client()->response_head());
  // The token was not removed due to cookies on leg 2.
  EXPECT_FALSE(client()->response_head()->pvt_token_removed_due_to_cookies);
}

}  // namespace network
