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

#include <stddef.h>

#include <memory>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/location.h"
#include "base/macros.h"
#include "base/optional.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/task/post_task.h"
#include "base/task/task_traits.h"
#include "base/test/scoped_feature_list.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/timer/timer.h"
#include "base/unguessable_token.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/download/download_manager_impl.h"
#include "content/browser/download/download_resource_handler.h"
#include "content/browser/frame_host/navigation_request_info.h"
#include "content/browser/loader/detachable_resource_handler.h"
#include "content/browser/loader/navigation_url_loader.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/browser/loader/resource_loader.h"
#include "content/browser/loader/resource_message_filter.h"
#include "content/browser/loader/resource_request_info_impl.h"
#include "content/browser/loader_delegate_impl.h"
#include "content/common/appcache_interfaces.h"
#include "content/common/child_process_host_impl.h"
#include "content/common/navigation_params.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/global_request_id.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/resource_context.h"
#include "content/public/browser/resource_dispatcher_host_delegate.h"
#include "content/public/browser/resource_request_info.h"
#include "content/public/browser/resource_throttle.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/common/child_process_host.h"
#include "content/public/common/content_features.h"
#include "content/public/common/process_type.h"
#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/public/test/test_renderer_host.h"
#include "content/public/test/test_utils.h"
#include "content/test/test_content_browser_client.h"
#include "content/test/test_navigation_url_loader_delegate.h"
#include "mojo/public/cpp/system/data_pipe_utils.h"
#include "net/base/chunked_upload_data_stream.h"
#include "net/base/completion_once_callback.h"
#include "net/base/elements_upload_data_stream.h"
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
#include "net/base/request_priority.h"
#include "net/base/upload_bytes_element_reader.h"
#include "net/http/http_util.h"
#include "net/test/cert_test_util.h"
#include "net/test/test_data_directory.h"
#include "net/test/url_request/url_request_failed_job.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_job.h"
#include "net/url_request/url_request_job_factory.h"
#include "net/url_request/url_request_simple_job.h"
#include "net/url_request/url_request_test_job.h"
#include "net/url_request/url_request_test_util.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/resource_scheduler.h"
#include "services/network/resource_scheduler_params_manager.h"
#include "services/network/test/test_url_loader_client.h"
#include "storage/browser/blob/shareable_file_reference.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/mojom/appcache/appcache.mojom.h"

// TODO(eroman): Write unit tests for SafeBrowsing that exercise
//               SafeBrowsingResourceHandler.

using storage::ShareableFileReference;

namespace content {

static network::ResourceRequest CreateResourceRequest(const char* method,
                                                      ResourceType type,
                                                      const GURL& url) {
  network::ResourceRequest request;
  request.method = std::string(method);
  request.url = url;
  request.site_for_cookies = url;  // bypass third-party cookie blocking
  request.request_initiator =
      url::Origin::Create(url);  // ensure initiator is set
  request.referrer_policy = Referrer::GetDefaultReferrerPolicy();
  request.load_flags = 0;
  request.plugin_child_id = -1;
  request.resource_type = type;
  request.appcache_host_id = blink::mojom::kAppCacheNoHostId;
  request.should_reset_appcache = false;
  request.render_frame_id = 0;
  request.is_main_frame = true;
  request.transition_type = ui::PAGE_TRANSITION_LINK;
  request.allow_download = true;
  request.keepalive = (type == RESOURCE_TYPE_PING);
  return request;
}

// This is used to create a filter matching a specified child id.
class TestFilterSpecifyingChild : public ResourceMessageFilter {
 public:
  TestFilterSpecifyingChild(TestBrowserContext* browser_context, int process_id)
      : ResourceMessageFilter(
            process_id,
            nullptr,
            nullptr,
            nullptr,
            nullptr,
            nullptr,
            browser_context->GetSharedCorsOriginAccessList(),
            base::Bind(&TestFilterSpecifyingChild::GetContexts,
                       base::Unretained(this)),
            base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO})),
        resource_context_(browser_context->GetResourceContext()),
        url_request_context_(browser_context->GetRequestContext()) {
    InitializeForTest();
    set_peer_process_for_testing(base::Process::Current());
  }

  // ResourceMessageFilter override
  bool Send(IPC::Message* msg) override {
    NOTREACHED();
    return true;
  }

  ResourceContext* resource_context() { return resource_context_; }

 protected:
  ~TestFilterSpecifyingChild() override {}

 private:
  void GetContexts(ResourceType resource_type,
                   ResourceContext** resource_context,
                   net::URLRequestContext** request_context) {
    *resource_context = resource_context_;
    *request_context = url_request_context_->GetURLRequestContext();
  }

  ResourceContext* resource_context_;
  scoped_refptr<net::URLRequestContextGetter> url_request_context_;

  DISALLOW_COPY_AND_ASSIGN(TestFilterSpecifyingChild);
};

class TestFilter : public TestFilterSpecifyingChild {
 public:
  explicit TestFilter(TestBrowserContext* browser_context)
      : TestFilterSpecifyingChild(
            browser_context,
            ChildProcessHostImpl::GenerateChildProcessUniqueId()) {
    ChildProcessSecurityPolicyImpl::GetInstance()->Add(child_id(),
                                                       browser_context);
  }

 protected:
  ~TestFilter() override {
    ChildProcessSecurityPolicyImpl::GetInstance()->Remove(child_id());
  }
};

// This class is a variation on URLRequestTestJob in that it does
// not complete start upon entry, only when specifically told to.
class URLRequestTestDelayedStartJob : public net::URLRequestTestJob {
 public:
  URLRequestTestDelayedStartJob(net::URLRequest* request,
                                net::NetworkDelegate* network_delegate)
      : net::URLRequestTestJob(request, network_delegate) {
    Init();
  }
  URLRequestTestDelayedStartJob(net::URLRequest* request,
                                net::NetworkDelegate* network_delegate,
                                const std::string& response_headers,
                                const std::string& response_data,
                                bool auto_advance)
      : net::URLRequestTestJob(request,
                               network_delegate,
                               response_headers,
                               response_data,
                               auto_advance) {
    Init();
  }

  // Do nothing until you're told to.
  void Start() override {}

  // Finish starting a URL request whose job is an instance of
  // URLRequestTestDelayedStartJob.  It is illegal to call this routine
  // with a URLRequest that does not use URLRequestTestDelayedStartJob.
  static void CompleteStart(net::URLRequest* request) {
    for (URLRequestTestDelayedStartJob* job = list_head_;
         job;
         job = job->next_) {
      if (job->request() == request) {
        job->net::URLRequestTestJob::Start();
        return;
      }
    }
    NOTREACHED();
  }

  static bool DelayedStartQueueEmpty() {
    return !list_head_;
  }

  static void ClearQueue() {
    if (list_head_) {
      LOG(ERROR)
          << "Unreleased entries on URLRequestTestDelayedStartJob delay queue"
          << "; may result in leaks.";
      list_head_ = nullptr;
    }
  }

 protected:
  ~URLRequestTestDelayedStartJob() override {
    for (URLRequestTestDelayedStartJob** job = &list_head_; *job;
         job = &(*job)->next_) {
      if (*job == this) {
        *job = (*job)->next_;
        return;
      }
    }
    NOTREACHED();
  }

 private:
  void Init() {
    next_ = list_head_;
    list_head_ = this;
  }

  static URLRequestTestDelayedStartJob* list_head_;
  URLRequestTestDelayedStartJob* next_;
};

URLRequestTestDelayedStartJob* URLRequestTestDelayedStartJob::list_head_ =
    nullptr;

// This class is a variation on URLRequestTestJob in that it
// returns IO_pending errors before every read, not just the first one.
class URLRequestTestDelayedCompletionJob : public net::URLRequestTestJob {
 public:
  URLRequestTestDelayedCompletionJob(net::URLRequest* request,
                                     net::NetworkDelegate* network_delegate)
      : net::URLRequestTestJob(request, network_delegate) {}
  URLRequestTestDelayedCompletionJob(net::URLRequest* request,
                                     net::NetworkDelegate* network_delegate,
                                     bool auto_advance)
      : net::URLRequestTestJob(request, network_delegate, auto_advance) {}
  URLRequestTestDelayedCompletionJob(net::URLRequest* request,
                                     net::NetworkDelegate* network_delegate,
                                     const std::string& response_headers,
                                     const std::string& response_data,
                                     bool auto_advance)
      : net::URLRequestTestJob(request,
                               network_delegate,
                               response_headers,
                               response_data,
                               auto_advance) {}

 protected:
  ~URLRequestTestDelayedCompletionJob() override {}

 private:
  bool NextReadAsync() override { return true; }
};

// This class is a variation on URLRequestTestJob that ensures that no read is
// asked of this job.
class URLRequestMustNotReadTestJob : public net::URLRequestTestJob {
 public:
  URLRequestMustNotReadTestJob(net::URLRequest* request,
                               net::NetworkDelegate* network_delegate,
                               const std::string& response_headers,
                               const std::string& response_data)
      : net::URLRequestTestJob(request,
                               network_delegate,
                               response_headers,
                               response_data,
                               false) {}

  int ReadRawData(net::IOBuffer* buf, int buf_size) override {
    EXPECT_TRUE(false) << "The job should have been cancelled before trying to "
                          "read the response body.";
    return 0;
  }
};

class URLRequestBigJob : public net::URLRequestSimpleJob {
 public:
  URLRequestBigJob(net::URLRequest* request,
                   net::NetworkDelegate* network_delegate)
      : net::URLRequestSimpleJob(request, network_delegate) {
  }

  // URLRequestSimpleJob implementation:
  int GetData(std::string* mime_type,
              std::string* charset,
              std::string* data,
              net::CompletionOnceCallback callback) const override {
    *mime_type = "text/plain";
    *charset = "UTF-8";

    std::string text;
    int count;
    if (!ParseURL(request_->url(), &text, &count))
      return net::ERR_INVALID_URL;

    data->reserve(text.size() * count);
    for (int i = 0; i < count; ++i)
      data->append(text);

    return net::OK;
  }

 private:
  ~URLRequestBigJob() override {}

  // big-job:substring,N
  static bool ParseURL(const GURL& url, std::string* text, int* count) {
    std::vector<std::string> parts = base::SplitString(
        url.path(), ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);

    if (parts.size() != 2)
      return false;

    *text = parts[0];
    return base::StringToInt(parts[1], count);
  }
};

// URLRequestJob used to test GetLoadInfoForAllRoutes.  The LoadState and
// UploadProgress values are set for the jobs at the time of creation, and
// the jobs will never actually do anything.
class URLRequestLoadInfoJob : public net::URLRequestJob {
 public:
  URLRequestLoadInfoJob(net::URLRequest* request,
                        net::NetworkDelegate* network_delegate,
                        const net::LoadState& load_state)
      : net::URLRequestJob(request, network_delegate),
        load_state_(load_state) {}

  // net::URLRequestJob implementation:
  void Start() override {}
  net::LoadState GetLoadState() const override { return load_state_; }

 private:
  ~URLRequestLoadInfoJob() override {}

  // big-job:substring,N
  static bool ParseURL(const GURL& url, std::string* text, int* count) {
    std::vector<std::string> parts = base::SplitString(
        url.path(), ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);

    if (parts.size() != 2)
      return false;

    *text = parts[0];
    return base::StringToInt(parts[1], count);
  }

  const net::LoadState load_state_;
};

class ResourceDispatcherHostTest;

class TestURLRequestJobFactory : public net::URLRequestJobFactory {
 public:
  explicit TestURLRequestJobFactory(ResourceDispatcherHostTest* test_fixture)
      : test_fixture_(test_fixture),
        hang_after_start_(false),
        delay_start_(false),
        delay_complete_(false),
        must_not_read_(false),
        url_request_jobs_created_count_(0) {}

  void HandleScheme(const std::string& scheme) {
    supported_schemes_.insert(scheme);
  }

  int url_request_jobs_created_count() const {
    return url_request_jobs_created_count_;
  }

  // When set, jobs will hang eternally once started.
  void SetHangAfterStartJobGeneration(bool hang_after_start) {
    hang_after_start_ = hang_after_start;
  }

  void SetDelayedStartJobGeneration(bool delay_job_start) {
    delay_start_ = delay_job_start;
  }

  void SetDelayedCompleteJobGeneration(bool delay_job_complete) {
    delay_complete_ = delay_job_complete;
  }

  void SetMustNotReadJobGeneration(bool must_not_read) {
    must_not_read_ = must_not_read;
  }

  net::URLRequestJob* MaybeCreateJobWithProtocolHandler(
      const std::string& scheme,
      net::URLRequest* request,
      net::NetworkDelegate* network_delegate) const override;

  net::URLRequestJob* MaybeInterceptRedirect(
      net::URLRequest* request,
      net::NetworkDelegate* network_delegate,
      const GURL& location) const override;

  net::URLRequestJob* MaybeInterceptResponse(
      net::URLRequest* request,
      net::NetworkDelegate* network_delegate) const override;

  bool IsHandledProtocol(const std::string& scheme) const override {
    return supported_schemes_.count(scheme) > 0;
  }

  bool IsSafeRedirectTarget(const GURL& location) const override {
    return false;
  }

 private:
  ResourceDispatcherHostTest* test_fixture_;
  bool hang_after_start_;
  bool delay_start_;
  bool delay_complete_;
  bool must_not_read_;
  mutable int url_request_jobs_created_count_;
  std::set<std::string> supported_schemes_;

  DISALLOW_COPY_AND_ASSIGN(TestURLRequestJobFactory);
};

// Associated with an URLRequest to determine if the URLRequest gets deleted.
class TestUserData : public base::SupportsUserData::Data {
 public:
  explicit TestUserData(bool* was_deleted)
      : was_deleted_(was_deleted) {
  }

  ~TestUserData() override { *was_deleted_ = true; }

 private:
  bool* was_deleted_;
};

enum GenericResourceThrottleFlags {
  NONE                       = 0,
  DEFER_STARTING_REQUEST     = 1 << 0,
  DEFER_PROCESSING_RESPONSE  = 1 << 1,
  CANCEL_BEFORE_START        = 1 << 2,
  CANCEL_PROCESSING_RESPONSE = 1 << 3,
  MUST_NOT_CACHE_BODY        = 1 << 4,
};

// Throttle that tracks the current throttle blocking a request.  Only one
// can throttle any request at a time.
class GenericResourceThrottle : public ResourceThrottle {
 public:
  // The value is used to indicate that the throttle should not provide
  // a error code when cancelling a request. net::OK is used, because this
  // is not an error code.
  static const int USE_DEFAULT_CANCEL_ERROR_CODE = net::OK;

  GenericResourceThrottle(int flags, int code)
      : flags_(flags),
        error_code_for_cancellation_(code) {
  }

  ~GenericResourceThrottle() override {
    if (active_throttle_ == this)
      active_throttle_ = nullptr;
  }

  // ResourceThrottle implementation:
  void WillStartRequest(bool* defer) override {
    ASSERT_EQ(nullptr, active_throttle_);
    if (flags_ & DEFER_STARTING_REQUEST) {
      active_throttle_ = this;
      *defer = true;
    }

    if (flags_ & CANCEL_BEFORE_START) {
      if (error_code_for_cancellation_ == USE_DEFAULT_CANCEL_ERROR_CODE) {
        Cancel();
      } else {
        CancelWithError(error_code_for_cancellation_);
      }
    }
  }

  void WillProcessResponse(bool* defer) override {
    ASSERT_EQ(nullptr, active_throttle_);
    if (flags_ & DEFER_PROCESSING_RESPONSE) {
      active_throttle_ = this;
      *defer = true;
    }

    if (flags_ & CANCEL_PROCESSING_RESPONSE) {
      if (error_code_for_cancellation_ == USE_DEFAULT_CANCEL_ERROR_CODE) {
        Cancel();
      } else {
        CancelWithError(error_code_for_cancellation_);
      }
    }
  }

  const char* GetNameForLogging() const override {
    return "GenericResourceThrottle";
  }

  void AssertAndResume() {
    ASSERT_TRUE(this == active_throttle_);
    active_throttle_ = nullptr;
    ResourceThrottle::Resume();
  }

  static GenericResourceThrottle* active_throttle() {
    return active_throttle_;
  }

  bool MustProcessResponseBeforeReadingBody() override {
    return flags_ & MUST_NOT_CACHE_BODY;
  }

 private:
  int flags_;  // bit-wise union of GenericResourceThrottleFlags.
  int error_code_for_cancellation_;

  // The currently active throttle, if any.
  static GenericResourceThrottle* active_throttle_;
};
// static
GenericResourceThrottle* GenericResourceThrottle::active_throttle_ = nullptr;

class TestResourceDispatcherHostDelegate
    : public ResourceDispatcherHostDelegate {
 public:
  TestResourceDispatcherHostDelegate()
      : create_two_throttles_(false),
        flags_(NONE),
        error_code_for_cancellation_(
            GenericResourceThrottle::USE_DEFAULT_CANCEL_ERROR_CODE) {
  }

  void set_url_request_user_data(base::SupportsUserData::Data* user_data) {
    user_data_.reset(user_data);
  }

  void set_flags(int value) {
    flags_ = value;
  }

  void set_error_code_for_cancellation(int code) {
    error_code_for_cancellation_ = code;
  }

  void set_create_two_throttles(bool create_two_throttles) {
    create_two_throttles_ = create_two_throttles;
  }

  // ResourceDispatcherHostDelegate implementation:

  void RequestBeginning(
      net::URLRequest* request,
      ResourceContext* resource_context,
      AppCacheService* appcache_service,
      ResourceType resource_type,
      std::vector<std::unique_ptr<ResourceThrottle>>* throttles) override {
    if (user_data_) {
      const void* key = user_data_.get();
      request->SetUserData(key, std::move(user_data_));
    }

    if (flags_ != NONE) {
      throttles->push_back(std::make_unique<GenericResourceThrottle>(
          flags_, error_code_for_cancellation_));
      if (create_two_throttles_)
        throttles->push_back(std::make_unique<GenericResourceThrottle>(
            flags_, error_code_for_cancellation_));
    }
  }

 private:
  bool create_two_throttles_;
  int flags_;
  int error_code_for_cancellation_;
  std::unique_ptr<base::SupportsUserData::Data> user_data_;
};

// Waits for a ShareableFileReference to be released.
class ShareableFileReleaseWaiter {
 public:
  explicit ShareableFileReleaseWaiter(const base::FilePath& path) {
    scoped_refptr<ShareableFileReference> file =
        ShareableFileReference::Get(path);
    file->AddFinalReleaseCallback(base::BindOnce(
        &ShareableFileReleaseWaiter::Released, base::Unretained(this)));
  }

  void Wait() {
    loop_.Run();
  }

 private:
  void Released(const base::FilePath& path) {
    loop_.Quit();
  }

  base::RunLoop loop_;

  DISALLOW_COPY_AND_ASSIGN(ShareableFileReleaseWaiter);
};

enum class TestMode {
  kWithoutOutOfBlinkCors,
  kWithOutOfBlinkCors,
};

class ResourceDispatcherHostTest : public testing::TestWithParam<TestMode> {
 public:
  typedef ResourceDispatcherHostImpl::LoadInfo LoadInfo;
  typedef ResourceDispatcherHostImpl::LoadInfoList LoadInfoList;
  typedef ResourceDispatcherHostImpl::LoadInfoMap LoadInfoMap;

  ResourceDispatcherHostTest()
      : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
        host_(base::Bind(&DownloadResourceHandler::Create),
              base::ThreadTaskRunnerHandle::Get(),
              /* enable_resource_scheduler */ true),
        use_test_ssl_certificate_(false),
        send_data_received_acks_(false),
        auto_advance_(false) {
    switch (GetParam()) {
      case TestMode::kWithoutOutOfBlinkCors:
        scoped_feature_list_.InitWithFeatures(
            // Enabled features
            {},
            // Disabled features
            {network::features::kOutOfBlinkCors});
        break;
      case TestMode::kWithOutOfBlinkCors:
        scoped_feature_list_.InitWithFeatures(
            // Enabled features
            {network::features::kOutOfBlinkCors,
             blink::features::kServiceWorkerServicification},
            // Disabled features
            {});
        break;
    }
    host_.SetLoaderDelegate(&loader_delegate_);
    browser_context_.reset(new TestBrowserContext());
    BrowserContext::EnsureResourceContextInitialized(browser_context_.get());
    content::RunAllTasksUntilIdle();

    filter_ = MakeTestFilter();
    net::URLRequestContext* request_context =
        browser_context_->GetRequestContext()->GetURLRequestContext();
    job_factory_.reset(new TestURLRequestJobFactory(this));
    request_context->set_job_factory(job_factory_.get());
    request_context->set_network_delegate(&network_delegate_);
  }

  ~ResourceDispatcherHostTest() override {
    filter_->OnChannelClosing();
    filter_ = nullptr;
    web_contents_filter_ = nullptr;
  }

 protected:
  friend class TestURLRequestJobFactory;

  // testing::Test
  void SetUp() override {
    ChildProcessSecurityPolicyImpl::GetInstance()->Add(0,
                                                       browser_context_.get());
    HandleScheme("test");
    scoped_refptr<SiteInstance> site_instance =
        SiteInstance::Create(browser_context_.get());
    web_contents_ =
        WebContents::Create(WebContents::CreateParams(browser_context_.get()));
    web_contents_filter_ = new TestFilterSpecifyingChild(
        browser_context_.get(),
        web_contents_->GetMainFrame()->GetProcess()->GetID());
    child_ids_.insert(web_contents_->GetMainFrame()->GetProcess()->GetID());
    request_context_getter_ = new net::TestURLRequestContextGetter(
        base::CreateSingleThreadTaskRunnerWithTraits(
            {content::BrowserThread::UI}));
  }

  void TearDown() override {
    web_contents_filter_->OnChannelClosing();
    web_contents_.reset();

    EXPECT_TRUE(URLRequestTestDelayedStartJob::DelayedStartQueueEmpty());
    URLRequestTestDelayedStartJob::ClearQueue();

    for (auto it = child_ids_.begin(); it != child_ids_.end(); ++it) {
      host_.CancelRequestsForProcess(*it);
    }

    host_.Shutdown();

    ChildProcessSecurityPolicyImpl::GetInstance()->Remove(0);

    // Flush the message loop to make application verifiers happy.
    if (ResourceDispatcherHostImpl::Get())
      ResourceDispatcherHostImpl::Get()->CancelRequestsForContext(
          browser_context_->GetResourceContext());

    browser_context_.reset();
    content::RunAllTasksUntilIdle();
  }

  // Creates a new TestFilter and registers it with |child_ids_| so as not
  // to leak per-child state on test shutdown.
  scoped_refptr<TestFilter> MakeTestFilter() {
    auto filter = base::MakeRefCounted<TestFilter>(browser_context_.get());
    child_ids_.insert(filter->child_id());
    return filter;
  }

  // Creates a request using the current test object as the filter and
  // SubResource as the resource type.
  void MakeTestRequest(int render_view_id,
                       int request_id,
                       const GURL& url,
                       network::mojom::URLLoaderRequest loader_request,
                       network::mojom::URLLoaderClientPtr client);
  void MakeTestRequestWithRenderFrame(
      int render_view_id,
      int render_frame_id,
      int request_id,
      const GURL& url,
      ResourceType type,
      network::mojom::URLLoaderRequest loader_request,
      network::mojom::URLLoaderClientPtr client);
  // Generates a request using the given filter and resource type.
  void MakeTestRequestWithResourceType(
      ResourceMessageFilter* filter,
      int render_view_id,
      int request_id,
      const GURL& url,
      ResourceType type,
      network::mojom::URLLoaderRequest loader_request,
      network::mojom::URLLoaderClientPtr client);

  void MakeWebContentsAssociatedTestRequestWithResourceType(
      int request_id,
      const GURL& url,
      ResourceType type,
      network::mojom::URLLoaderRequest loader_request,
      network::mojom::URLLoaderClientPtr client);

  // Generates a request with the given priority.
  void MakeTestRequestWithPriorityAndRenderFrame(
      int render_view_id,
      int render_frame_id,
      int request_id,
      net::RequestPriority priority,
      network::mojom::URLLoaderRequest loader_request,
      network::mojom::URLLoaderClientPtr client);

  void CancelRequest(int request_id);
  void CompleteStartRequest(int request_id);
  void CompleteStartRequest(ResourceMessageFilter* filter, int request_id);

  net::TestNetworkDelegate* network_delegate() { return &network_delegate_; }

  void EnsureSchemeIsAllowed(const std::string& scheme) {
    ChildProcessSecurityPolicyImpl* policy =
        ChildProcessSecurityPolicyImpl::GetInstance();
    if (!policy->IsWebSafeScheme(scheme))
      policy->RegisterWebSafeScheme(scheme);
  }

  // Sets a particular response for any request from now on. To switch back to
  // the default bahavior, pass an empty |headers|. |headers| should be CR[LF]
  // terminated.
  void SetResponse(const std::string& headers, const std::string& data) {
    response_headers_ = headers;
    response_data_ = data;
  }
  void SetResponse(const std::string& headers) {
    SetResponse(headers, std::string());
  }

  // If called, requests called from now on will be created as
  // TestHTTPSURLRequestJobs: that is, a test certificate will be set on
  // the |ssl_info| field of the response.
  void SetTestSSLCertificate() { use_test_ssl_certificate_ = true; }

  // Intercepts requests for the given protocol.
  void HandleScheme(const std::string& scheme) {
    job_factory_->HandleScheme(scheme);
    EnsureSchemeIsAllowed(scheme);
  }

  void DeleteRenderFrame(const GlobalFrameRoutingId& global_routing_id) {
    host_.OnRenderFrameDeleted(global_routing_id);
  }

  // Creates and drives a main resource request until completion. Then asserts
  // that the expected_error_code has been emitted for the request.
  void CompleteFailingMainResourceRequest(const GURL& url,
                                          int expected_error_code) {
    auto_advance_ = true;

    // Make a navigation request.
    TestNavigationURLLoaderDelegate delegate;
    mojom::BeginNavigationParamsPtr begin_params =
        mojom::BeginNavigationParams::New(
            std::string() /* headers */, net::LOAD_NORMAL,
            false /* skip_service_worker */,
            blink::mojom::RequestContextType::LOCATION,
            blink::WebMixedContentContextType::kBlockable,
            false /* is_form_submission */, GURL() /* searchable_form_url */,
            std::string() /* searchable_form_encoding */,
            GURL() /* client_side_redirect_url */,
            base::nullopt /* devtools_initiator_info */);
    CommonNavigationParams common_params;
    common_params.url = url;
    common_params.initiator_origin = url::Origin::Create(url);

    std::unique_ptr<NavigationRequestInfo> request_info(
        new NavigationRequestInfo(common_params, std::move(begin_params), url,
                                  url::Origin::Create(url), true, false, false,
                                  -1, false, false, false, false, nullptr,
                                  base::UnguessableToken::Create(),
                                  base::UnguessableToken::Create()));
    std::unique_ptr<NavigationURLLoader> test_loader =
        NavigationURLLoader::Create(
            browser_context_->GetResourceContext(),
            BrowserContext::GetDefaultStoragePartition(browser_context_.get()),
            std::move(request_info), nullptr, nullptr, nullptr, &delegate);

    // The navigation should fail with the expected error code.
    delegate.WaitForRequestFailed();
    ASSERT_EQ(expected_error_code, delegate.net_error());
  }

  bool IsDetached(net::URLRequest* request) {
    auto* request_info = ResourceRequestInfoImpl::ForRequest(request);
    if (!request_info)
      return false;
    return request_info->detachable_handler() &&
           request_info->detachable_handler()->is_detached();
  }

  bool IsAborted(const network::TestURLLoaderClient& client) {
    // TODO(toyoshim): Once NetworkService or OutOfBlinkCors is enabled, these
    // expectations below should be receiving a completion with ERR_ABORTED.
    if (!client.has_received_completion())
      return client.has_received_connection_error();

    return client.completion_status().error_code == net::ERR_ABORTED;
  }

  void SetMaxDelayableRequests(size_t max_delayable_requests) {
    network::ResourceSchedulerParamsManager::ParamsForNetworkQualityContainer c;
    for (int i = 0; i != net::EFFECTIVE_CONNECTION_TYPE_LAST; ++i) {
      auto type = static_cast<net::EffectiveConnectionType>(i);
      c[type] =
          network::ResourceSchedulerParamsManager::ParamsForNetworkQuality(
              max_delayable_requests, 0.0, false, base::nullopt);
    }
    host_.scheduler()->SetResourceSchedulerParamsManagerForTests(
        network::ResourceSchedulerParamsManager(c));
  }

  content::TestBrowserThreadBundle thread_bundle_;
  std::unique_ptr<TestBrowserContext> browser_context_;
  std::unique_ptr<TestURLRequestJobFactory> job_factory_;
  std::unique_ptr<WebContents> web_contents_;
  scoped_refptr<TestFilter> filter_;

  scoped_refptr<TestFilterSpecifyingChild> web_contents_filter_;
  net::TestNetworkDelegate network_delegate_;
  LoaderDelegateImpl loader_delegate_;
  ResourceDispatcherHostImpl host_;
  std::string response_headers_;
  std::string response_data_;
  bool use_test_ssl_certificate_;
  std::string scheme_;
  bool send_data_received_acks_;
  std::set<int> child_ids_;
  std::unique_ptr<base::RunLoop> wait_for_request_complete_loop_;
  RenderViewHostTestEnabler render_view_host_test_enabler_;
  bool auto_advance_;
  scoped_refptr<net::TestURLRequestContextGetter> request_context_getter_;
  base::test::ScopedFeatureList scoped_feature_list_;
};

void ResourceDispatcherHostTest::MakeTestRequest(
    int render_view_id,
    int request_id,
    const GURL& url,
    network::mojom::URLLoaderRequest loader_request,
    network::mojom::URLLoaderClientPtr client) {
  MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
                                  url, RESOURCE_TYPE_SUB_RESOURCE,
                                  std::move(loader_request), std::move(client));
}

void ResourceDispatcherHostTest::MakeTestRequestWithRenderFrame(
    int render_view_id,
    int render_frame_id,
    int request_id,
    const GURL& url,
    ResourceType type,
    network::mojom::URLLoaderRequest loader_request,
    network::mojom::URLLoaderClientPtr client) {
  network::ResourceRequest request = CreateResourceRequest("GET", type, url);
  request.render_frame_id = render_frame_id;
  filter_->CreateLoaderAndStart(
      std::move(loader_request), render_view_id, request_id,
      network::mojom::kURLLoadOptionSniffMimeType, request, std::move(client),
      net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
}

void ResourceDispatcherHostTest::MakeTestRequestWithResourceType(
    ResourceMessageFilter* filter,
    int render_view_id,
    int request_id,
    const GURL& url,
    ResourceType type,
    network::mojom::URLLoaderRequest loader_request,
    network::mojom::URLLoaderClientPtr client) {
  network::ResourceRequest request = CreateResourceRequest("GET", type, url);
  filter->CreateLoaderAndStart(
      std::move(loader_request), render_view_id, request_id,
      network::mojom::kURLLoadOptionSniffMimeType, request, std::move(client),
      net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
}

void ResourceDispatcherHostTest::
    MakeWebContentsAssociatedTestRequestWithResourceType(
        int request_id,
        const GURL& url,
        ResourceType type,
        network::mojom::URLLoaderRequest loader_request,
        network::mojom::URLLoaderClientPtr client) {
  network::ResourceRequest request = CreateResourceRequest("GET", type, url);
  DCHECK_EQ(web_contents_filter_->child_id(),
            web_contents_->GetMainFrame()->GetProcess()->GetID());
  request.render_frame_id = web_contents_->GetMainFrame()->GetRoutingID();
  web_contents_filter_->CreateLoaderAndStart(
      std::move(loader_request), 0, request_id,
      network::mojom::kURLLoadOptionNone, request, std::move(client),
      net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
}

void ResourceDispatcherHostTest::MakeTestRequestWithPriorityAndRenderFrame(
    int render_view_id,
    int render_frame_id,
    int request_id,
    net::RequestPriority priority,
    network::mojom::URLLoaderRequest loader_request,
    network::mojom::URLLoaderClientPtr client) {
  network::ResourceRequest request = CreateResourceRequest(
      "GET", RESOURCE_TYPE_SUB_RESOURCE, GURL("http://example.com/priority"));
  request.render_frame_id = render_frame_id;
  request.priority = priority;
  filter_->CreateLoaderAndStart(
      std::move(loader_request), render_view_id, request_id,
      network::mojom::kURLLoadOptionNone, request, std::move(client),
      net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
}

void ResourceDispatcherHostTest::CancelRequest(int request_id) {
  host_.CancelRequest(filter_->child_id(), request_id);
}

void ResourceDispatcherHostTest::CompleteStartRequest(int request_id) {
  CompleteStartRequest(filter_.get(), request_id);
}

void ResourceDispatcherHostTest::CompleteStartRequest(
    ResourceMessageFilter* filter,
    int request_id) {
  GlobalRequestID gid(filter->child_id(), request_id);
  net::URLRequest* req = host_.GetURLRequest(gid);
  EXPECT_TRUE(req);
  if (req)
    URLRequestTestDelayedStartJob::CompleteStart(req);
}

void CheckSuccessfulRequest(network::TestURLLoaderClient* client,
                            const std::string& reference_data) {
  if (!reference_data.empty()) {
    client->RunUntilResponseBodyArrived();
    mojo::ScopedDataPipeConsumerHandle body = client->response_body_release();
    ASSERT_TRUE(body.is_valid());

    std::string actual;
    EXPECT_TRUE(mojo::BlockingCopyToString(std::move(body), &actual));
    EXPECT_EQ(reference_data, actual);
  }
  client->RunUntilComplete();
  EXPECT_FALSE(client->response_body().is_valid());
  EXPECT_EQ(net::OK, client->completion_status().error_code);
}

// Tests whether messages get canceled properly. We issue four requests,
// cancel two of them, and make sure that each sent the proper notifications.
TEST_P(ResourceDispatcherHostTest, Cancel) {
  network::mojom::URLLoaderPtr loader1, loader2, loader3, loader4;
  network::TestURLLoaderClient client1, client2, client3, client4;
  MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1(),
                  mojo::MakeRequest(&loader1), client1.CreateInterfacePtr());
  MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2(),
                  mojo::MakeRequest(&loader2), client2.CreateInterfacePtr());
  MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3(),
                  mojo::MakeRequest(&loader3), client3.CreateInterfacePtr());

  MakeTestRequestWithResourceType(
      filter_.get(), 0, 4, net::URLRequestTestJob::test_url_4(),
      RESOURCE_TYPE_PREFETCH,  // detachable type
      mojo::MakeRequest(&loader4), client4.CreateInterfacePtr());

  CancelRequest(2);

  // Cancel request must come from the renderer for a detachable resource to
  // delay.
  loader4 = nullptr;
  content::RunAllTasksUntilIdle();

  // The handler should have been detached now.
  GlobalRequestID global_request_id(filter_->child_id(), 4);
  ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(
      host_.GetURLRequest(global_request_id));
  ASSERT_TRUE(info->detachable_handler()->is_detached());

  // flush all the pending requests
  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
  content::RunAllTasksUntilIdle();

  // Everything should be out now.
  EXPECT_EQ(0, host_.pending_requests());

  // Check that request 2 and 4 got canceled, as far as the renderer is
  // concerned.  Request 2 will have been deleted.
  client2.RunUntilConnectionError();
  client4.RunUntilComplete();
  EXPECT_EQ(net::ERR_ABORTED, client4.completion_status().error_code);

  // However, request 4 should have actually gone to completion. (Only request 2
  // was canceled.)
  EXPECT_EQ(4, network_delegate()->completed_requests());
  EXPECT_EQ(1, network_delegate()->canceled_requests());
  EXPECT_EQ(0, network_delegate()->error_count());
}

// Shows that detachable requests will timeout if the request takes too long to
// complete.
TEST_P(ResourceDispatcherHostTest, DetachedResourceTimesOut) {
  network::mojom::URLLoaderPtr loader;
  network::TestURLLoaderClient client;
  MakeTestRequestWithResourceType(
      filter_.get(), 0, 1, net::URLRequestTestJob::test_url_2(),
      RESOURCE_TYPE_PREFETCH,  // detachable type
      mojo::MakeRequest(&loader), client.CreateInterfacePtr());
  content::RunAllTasksUntilIdle();

  GlobalRequestID global_request_id(filter_->child_id(), 1);
  ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(
      host_.GetURLRequest(global_request_id));
  ASSERT_TRUE(info->detachable_handler());
  info->detachable_handler()->set_cancel_delay(
      base::TimeDelta::FromMilliseconds(200));

  // Cancel the request handled by |loader|.
  loader = nullptr;

  // From the renderer's perspective, the request was cancelled.
  content::RunAllTasksUntilIdle();
  client.RunUntilComplete();
  EXPECT_EQ(net::ERR_ABORTED, client.completion_status().error_code);

  // But it continues detached.
  EXPECT_EQ(1, host_.pending_requests());
  EXPECT_TRUE(info->detachable_handler()->is_detached());

  // Wait until after the delay timer times out before we start processing any
  // messages.
  base::OneShotTimer timer;
  base::RunLoop run_loop;
  timer.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(210),
              run_loop.QuitWhenIdleClosure());
  run_loop.Run();

  // The prefetch should be cancelled by now.
  EXPECT_EQ(0, host_.pending_requests());
  EXPECT_EQ(1, network_delegate()->completed_requests());
  EXPECT_EQ(1, network_delegate()->canceled_requests());
  EXPECT_EQ(0, network_delegate()->error_count());
}

// If the filter has disappeared then detachable resources should continue to
// load.
TEST_P(ResourceDispatcherHostTest, DeletedFilterDetached) {
  network::mojom::URLLoaderPtr loader1;
  network::TestURLLoaderClient client1;
  base::test::ScopedFeatureList feature_list;
  // test_url_1's data is available synchronously, so use 2 and 3.
  network::ResourceRequest request_prefetch = CreateResourceRequest(
      "GET", RESOURCE_TYPE_PREFETCH, net::URLRequestTestJob::test_url_2());

  filter_->CreateLoaderAndStart(
      mojo::MakeRequest(&loader1), 0, 1, network::mojom::kURLLoadOptionNone,
      request_prefetch, client1.CreateInterfacePtr(),
      net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));

  // Remove the filter before processing the requests by simulating channel
  // closure.
  ResourceRequestInfoImpl* info_prefetch = ResourceRequestInfoImpl::ForRequest(
      host_.GetURLRequest(GlobalRequestID(filter_->child_id(), 1)));
  DCHECK_EQ(filter_.get(), info_prefetch->requester_info()->filter());
  filter_->OnChannelClosing();

  content::RunAllTasksUntilIdle();
  DCHECK(IsAborted(client1));

  // But it continues detached.
  EXPECT_EQ(1, host_.pending_requests());
  EXPECT_TRUE(info_prefetch->detachable_handler()->is_detached());

  // Make sure the requests weren't canceled early.
  EXPECT_EQ(1, host_.pending_requests());

  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
  content::RunAllTasksUntilIdle();

  EXPECT_EQ(0, host_.pending_requests());
  EXPECT_EQ(1, network_delegate()->completed_requests());
  EXPECT_EQ(0, network_delegate()->canceled_requests());
  EXPECT_EQ(0, network_delegate()->error_count());
}

// If the filter has disappeared (original process dies) then detachable
// resources should continue to load, even when redirected.
TEST_P(ResourceDispatcherHostTest, DeletedFilterDetachedRedirect) {
  network::mojom::URLLoaderPtr loader;
  network::TestURLLoaderClient client;
  network::ResourceRequest request = CreateResourceRequest(
      "GET", RESOURCE_TYPE_PREFETCH,
      net::URLRequestTestJob::test_url_redirect_to_url_2());

  filter_->CreateLoaderAndStart(
      mojo::MakeRequest(&loader), 0, 1, network::mojom::kURLLoadOptionNone,
      request, client.CreateInterfacePtr(),
      net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));

  // Remove the filter before processing the request by simulating channel
  // closure.
  GlobalRequestID global_request_id(filter_->child_id(), 1);
  ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(
      host_.GetURLRequest(global_request_id));
  info->requester_info()->filter()->OnChannelClosing();

  // The request should be detached.
  EXPECT_EQ(1, host_.pending_requests());
  EXPECT_TRUE(info->detachable_handler()->is_detached());

  // Verify no redirects before resetting the filter.
  net::URLRequest* url_request = host_.GetURLRequest(global_request_id);
  EXPECT_EQ(1u, url_request->url_chain().size());

  // From the renderer's perspective, the request was cancelled.
  content::RunAllTasksUntilIdle();
  DCHECK(IsAborted(client));

  content::RunAllTasksUntilIdle();
  // Verify that a redirect was followed.
  EXPECT_EQ(2u, url_request->url_chain().size());

  // Make sure the request wasn't canceled early.
  EXPECT_EQ(1, host_.pending_requests());

  // Finish up the request.
  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
  content::RunAllTasksUntilIdle();

  EXPECT_EQ(0, host_.pending_requests());
  EXPECT_EQ(1, network_delegate()->completed_requests());
  EXPECT_EQ(0, network_delegate()->canceled_requests());
  EXPECT_EQ(0, network_delegate()->error_count());
}

TEST_P(ResourceDispatcherHostTest, CancelWhileStartIsDeferred) {
  network::mojom::URLLoaderPtr loader;
  network::TestURLLoaderClient client;
  bool was_deleted = false;

  // Arrange to have requests deferred before starting.
  TestResourceDispatcherHostDelegate delegate;
  delegate.set_flags(DEFER_STARTING_REQUEST);
  delegate.set_url_request_user_data(new TestUserData(&was_deleted));
  host_.SetDelegate(&delegate);

  MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1(),
                  mojo::MakeRequest(&loader), client.CreateInterfacePtr());
  content::RunAllTasksUntilIdle();
  // We cancel from the renderer because all non-renderer cancels delete
  // the request synchronously.
  host_.CancelRequestFromRenderer(GlobalRequestID(filter_->child_id(), 1));

  // Our TestResourceThrottle should not have been deleted yet.  This is to
  // ensure that destruction of the URLRequest happens asynchronously to
  // calling CancelRequest.
  EXPECT_FALSE(was_deleted);

  content::RunAllTasksUntilIdle();

  EXPECT_TRUE(was_deleted);
}

TEST_P(ResourceDispatcherHostTest, DetachWhileStartIsDeferred) {
  network::mojom::URLLoaderPtr loader;
  network::TestURLLoaderClient client;
  bool was_deleted = false;

  // Arrange to have requests deferred before starting.
  TestResourceDispatcherHostDelegate delegate;
  delegate.set_flags(DEFER_STARTING_REQUEST);
  delegate.set_url_request_user_data(new TestUserData(&was_deleted));
  host_.SetDelegate(&delegate);

  MakeTestRequestWithResourceType(
      filter_.get(), 0, 1, net::URLRequestTestJob::test_url_1(),
      RESOURCE_TYPE_PREFETCH,  // detachable type
      mojo::MakeRequest(&loader), client.CreateInterfacePtr());
  // Cancel request must come from the renderer for a detachable resource to
  // detach.
  loader = nullptr;

  // Even after driving the event loop, the request has not been deleted.
  EXPECT_FALSE(was_deleted);

  // However, it is still throttled because the defer happened above the
  // DetachableResourceHandler.
  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
  content::RunAllTasksUntilIdle();
  EXPECT_FALSE(was_deleted);

  // Resume the request.
  GenericResourceThrottle* throttle =
      GenericResourceThrottle::active_throttle();
  ASSERT_TRUE(throttle);
  throttle->AssertAndResume();

  // Now, the request completes.
  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
  content::RunAllTasksUntilIdle();
  EXPECT_TRUE(was_deleted);
  EXPECT_EQ(1, network_delegate()->completed_requests());
  EXPECT_EQ(0, network_delegate()->canceled_requests());
  EXPECT_EQ(0, network_delegate()->error_count());
}

// Tests if cancel is called in ResourceThrottle::WillStartRequest, then the
// URLRequest will not be started.
TEST_P(ResourceDispatcherHostTest, CancelInResourceThrottleWillStartRequest) {
  network::mojom::URLLoaderPtr loader;
  network::TestURLLoaderClient client;
  TestResourceDispatcherHostDelegate delegate;
  delegate.set_flags(CANCEL_BEFORE_START);
  host_.SetDelegate(&delegate);

  MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1(),
                  mojo::MakeRequest(&loader), client.CreateInterfacePtr());

  // flush all the pending requests
  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
  content::RunAllTasksUntilIdle();

  // Check that request got canceled.
  client.RunUntilComplete();
  EXPECT_EQ(net::ERR_ABORTED, client.completion_status().error_code);

  // Make sure URLRequest is never started.
  EXPECT_EQ(0, job_factory_->url_request_jobs_created_count());
}

TEST_P(ResourceDispatcherHostTest, PausedStartError) {
  network::mojom::URLLoaderPtr loader;
  network::TestURLLoaderClient client;
  // Arrange to have requests deferred before processing response headers.
  TestResourceDispatcherHostDelegate delegate;
  delegate.set_flags(DEFER_PROCESSING_RESPONSE);
  host_.SetDelegate(&delegate);

  job_factory_->SetDelayedStartJobGeneration(true);
  MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_error(),
                  mojo::MakeRequest(&loader), client.CreateInterfacePtr());
  CompleteStartRequest(1);

  // flush all the pending requests
  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
  content::RunAllTasksUntilIdle();

  EXPECT_EQ(0, host_.pending_requests());
}

TEST_P(ResourceDispatcherHostTest, ThrottleAndResumeTwice) {
  network::mojom::URLLoaderPtr loader;
  network::TestURLLoaderClient client;
  // Arrange to have requests deferred before starting.
  TestResourceDispatcherHostDelegate delegate;
  delegate.set_flags(DEFER_STARTING_REQUEST);
  delegate.set_create_two_throttles(true);
  host_.SetDelegate(&delegate);

  // Make sure the first throttle blocked the request, and then resume.
  MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1(),
                  mojo::MakeRequest(&loader), client.CreateInterfacePtr());
  GenericResourceThrottle* first_throttle =
      GenericResourceThrottle::active_throttle();
  ASSERT_TRUE(first_throttle);
  first_throttle->AssertAndResume();

  // Make sure the second throttle blocked the request, and then resume.
  ASSERT_TRUE(GenericResourceThrottle::active_throttle());
  ASSERT_NE(first_throttle, GenericResourceThrottle::active_throttle());
  GenericResourceThrottle::active_throttle()->AssertAndResume();

  ASSERT_FALSE(GenericResourceThrottle::active_throttle());

  // The request is started asynchronously.
  content::RunAllTasksUntilIdle();

  // Flush all the pending requests.
  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}

  EXPECT_EQ(0, host_.pending_requests());

  // Make sure the request completed successfully.
  CheckSuccessfulRequest(&client, net::URLRequestTestJob::test_data_1());
}

// Tests that the delegate can cancel a request and provide a error code.
TEST_P(ResourceDispatcherHostTest, CancelInDelegate) {
  network::mojom::URLLoaderPtr loader;
  network::TestURLLoaderClient client;
  TestResourceDispatcherHostDelegate delegate;
  delegate.set_flags(CANCEL_BEFORE_START);
  delegate.set_error_code_for_cancellation(net::ERR_ACCESS_DENIED);
  host_.SetDelegate(&delegate);

  MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1(),
                  mojo::MakeRequest(&loader), client.CreateInterfacePtr());
  // The request will get cancelled by the throttle.

  // flush all the pending requests
  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
  content::RunAllTasksUntilIdle();

  client.RunUntilComplete();
  EXPECT_EQ(net::ERR_ACCESS_DENIED, client.completion_status().error_code);
}

TEST_P(ResourceDispatcherHostTest, CancelRequestsForRoute) {
  network::mojom::URLLoaderPtr loader1, loader2, loader3, loader4;
  network::TestURLLoaderClient client1, client2, client3, client4;
  base::test::ScopedFeatureList feature_list;
  job_factory_->SetDelayedStartJobGeneration(true);
  MakeTestRequestWithRenderFrame(0, 11, 1, net::URLRequestTestJob::test_url_1(),
                                 RESOURCE_TYPE_XHR, mojo::MakeRequest(&loader1),
                                 client1.CreateInterfacePtr());
  EXPECT_EQ(1, host_.pending_requests());

  MakeTestRequestWithRenderFrame(0, 12, 2, net::URLRequestTestJob::test_url_2(),
                                 RESOURCE_TYPE_XHR, mojo::MakeRequest(&loader2),
                                 client2.CreateInterfacePtr());
  EXPECT_EQ(2, host_.pending_requests());

  MakeTestRequestWithRenderFrame(
      0, 11, 3, net::URLRequestTestJob::test_url_3(), RESOURCE_TYPE_PREFETCH,
      mojo::MakeRequest(&loader3), client3.CreateInterfacePtr());
  EXPECT_EQ(3, host_.pending_requests());

  MakeTestRequestWithRenderFrame(
      0, 12, 4, net::URLRequestTestJob::test_url_4(), RESOURCE_TYPE_PREFETCH,
      mojo::MakeRequest(&loader4), client4.CreateInterfacePtr());
  EXPECT_EQ(4, host_.pending_requests());

  EXPECT_TRUE(host_.GetURLRequest(GlobalRequestID(filter_->child_id(), 1)));
  EXPECT_TRUE(host_.GetURLRequest(GlobalRequestID(filter_->child_id(), 2)));
  EXPECT_TRUE(host_.GetURLRequest(GlobalRequestID(filter_->child_id(), 3)));
  EXPECT_TRUE(host_.GetURLRequest(GlobalRequestID(filter_->child_id(), 4)));

  host_.CancelRequestsForRoute(GlobalFrameRoutingId(filter_->child_id(), 11));

  EXPECT_FALSE(host_.GetURLRequest(GlobalRequestID(filter_->child_id(), 1)));
  EXPECT_TRUE(host_.GetURLRequest(GlobalRequestID(filter_->child_id(), 2)));
  ASSERT_TRUE(host_.GetURLRequest(GlobalRequestID(filter_->child_id(), 3)));
  ASSERT_TRUE(host_.GetURLRequest(GlobalRequestID(filter_->child_id(), 4)));

  EXPECT_TRUE(
      IsDetached(host_.GetURLRequest(GlobalRequestID(filter_->child_id(), 3))));
  EXPECT_FALSE(
      IsDetached(host_.GetURLRequest(GlobalRequestID(filter_->child_id(), 4))));

  CompleteStartRequest(2);
  CompleteStartRequest(3);
  CompleteStartRequest(4);

  while (host_.pending_requests() > 0) {
    while (net::URLRequestTestJob::ProcessOnePendingMessage()) {
    }
    content::RunAllTasksUntilIdle();
  }
}

// Tests CancelRequestsForProcess
TEST_P(ResourceDispatcherHostTest, TestProcessCancel) {
  network::mojom::URLLoaderPtr loader1, loader2, loader3, loader4;
  network::TestURLLoaderClient client1, client2, client3, client4;
  scoped_refptr<TestFilter> test_filter = MakeTestFilter();

  // request 1 goes to the test delegate
  MakeTestRequestWithResourceType(
      test_filter.get(), 0, 1, net::URLRequestTestJob::test_url_1(),
      RESOURCE_TYPE_SUB_RESOURCE, mojo::MakeRequest(&loader1),
      client1.CreateInterfacePtr());

  // request 2 goes to us
  MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2(),
                  mojo::MakeRequest(&loader2), client2.CreateInterfacePtr());

  // request 3 goes to the test delegate
  MakeTestRequestWithResourceType(
      test_filter.get(), 0, 3, net::URLRequestTestJob::test_url_3(),
      RESOURCE_TYPE_SUB_RESOURCE, mojo::MakeRequest(&loader3),
      client3.CreateInterfacePtr());

  // request 4 goes to us
  MakeTestRequestWithResourceType(
      filter_.get(), 0, 4, net::URLRequestTestJob::test_url_4(),
      RESOURCE_TYPE_PREFETCH,  // detachable type
      mojo::MakeRequest(&loader4), client4.CreateInterfacePtr());

  // Make sure all requests have finished stage one. test_url_1 will have
  // finished.
  content::RunAllTasksUntilIdle();

  // TODO(mbelshe):
  // Now that the async IO path is in place, the IO always completes on the
  // initial call; so the requests have already completed.  This basically
  // breaks the whole test.
  // EXPECT_EQ(3, host_.pending_requests());

  // Process test_url_2 and test_url_3 for one level so one callback is called.
  // We'll cancel test_url_4 (detachable) before processing it to verify that it
  // delays the cancel.
  for (int i = 0; i < 2; i++)
    EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());

  // Cancel the requests to the test process.
  host_.CancelRequestsForProcess(filter_->child_id());

  // The requests should all be cancelled, except request 4, which is detached.
  EXPECT_EQ(1, host_.pending_requests());
  GlobalRequestID global_request_id(filter_->child_id(), 4);
  ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(
      host_.GetURLRequest(global_request_id));
  ASSERT_TRUE(info->detachable_handler()->is_detached());

  // Flush all the pending requests.
  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}

  EXPECT_EQ(0, host_.pending_requests());

  client1.RunUntilConnectionError();
  CheckSuccessfulRequest(&client2, net::URLRequestTestJob::test_data_2());
  client3.RunUntilConnectionError();
  client4.RunUntilComplete();
  EXPECT_EQ(net::ERR_ABORTED, client4.completion_status().error_code);

  // For the network stack, no requests were canceled.
  EXPECT_EQ(4, network_delegate()->completed_requests());
  EXPECT_EQ(0, network_delegate()->canceled_requests());
  EXPECT_EQ(0, network_delegate()->error_count());

  test_filter->OnChannelClosing();
}

// Tests whether the correct requests get canceled when a RenderViewHost is
// deleted.
TEST_P(ResourceDispatcherHostTest, CancelRequestsOnRenderFrameDeleted) {
  network::mojom::URLLoaderPtr loader1, loader2, loader3, loader4, loader5;
  network::TestURLLoaderClient client1, client2, client3, client4, client5;
  // Requests all hang once started.  This prevents requests from being
  // destroyed due to completion.
  job_factory_->SetHangAfterStartJobGeneration(true);
  HandleScheme("http");

  TestResourceDispatcherHostDelegate delegate;
  host_.SetDelegate(&delegate);
  host_.OnRenderViewHostCreated(filter_->child_id(), 0,
                                request_context_getter_.get());
  SetMaxDelayableRequests(1);

  // One RenderView issues a high priority request and a low priority one. Both
  // should be started.
  MakeTestRequestWithPriorityAndRenderFrame(0, 10, 1, net::HIGHEST,
                                            mojo::MakeRequest(&loader1),
                                            client1.CreateInterfacePtr());
  MakeTestRequestWithPriorityAndRenderFrame(0, 11, 2, net::LOWEST,
                                            mojo::MakeRequest(&loader2),
                                            client2.CreateInterfacePtr());
  content::RunAllTasksUntilIdle();
  EXPECT_EQ(2, network_delegate_.created_requests());
  EXPECT_EQ(0, network_delegate_.canceled_requests());

  // The same RenderView issues two more low priority requests. The
  // ResourceScheduler shouldn't let them start immediately.
  MakeTestRequestWithPriorityAndRenderFrame(0, 10, 3, net::LOWEST,
                                            mojo::MakeRequest(&loader3),
                                            client3.CreateInterfacePtr());
  MakeTestRequestWithPriorityAndRenderFrame(0, 11, 4, net::LOWEST,
                                            mojo::MakeRequest(&loader4),
                                            client4.CreateInterfacePtr());
  content::RunAllTasksUntilIdle();
  EXPECT_EQ(2, network_delegate_.created_requests());
  EXPECT_EQ(0, network_delegate_.canceled_requests());

  // Another RenderView in the same process as the old one issues a request,
  // which is then started.
  MakeTestRequestWithPriorityAndRenderFrame(1, 12, 5, net::LOWEST,
                                            mojo::MakeRequest(&loader5),
                                            client5.CreateInterfacePtr());
  content::RunAllTasksUntilIdle();
  EXPECT_EQ(3, network_delegate_.created_requests());
  EXPECT_EQ(0, network_delegate_.canceled_requests());

  // The first two RenderFrameHosts are destroyed.  All 4 of their requests
  // should be cancelled, and none of the two deferred requests should be
  // started.
  DeleteRenderFrame(GlobalFrameRoutingId(filter_->child_id(), 10));
  DeleteRenderFrame(GlobalFrameRoutingId(filter_->child_id(), 11));
  host_.OnRenderViewHostDeleted(filter_->child_id(), 0);
  content::RunAllTasksUntilIdle();
  EXPECT_EQ(3, network_delegate_.created_requests());
  EXPECT_EQ(4, network_delegate_.canceled_requests());
}

TEST_P(ResourceDispatcherHostTest, TestProcessCancelDetachedTimesOut) {
  network::mojom::URLLoaderPtr loader;
  network::TestURLLoaderClient client;
  MakeTestRequestWithResourceType(
      filter_.get(), 0, 1, net::URLRequestTestJob::test_url_4(),
      RESOURCE_TYPE_PREFETCH,  // detachable type
      mojo::MakeRequest(&loader), client.CreateInterfacePtr());
  content::RunAllTasksUntilIdle();
  GlobalRequestID global_request_id(filter_->child_id(), 1);
  ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(
      host_.GetURLRequest(global_request_id));
  ASSERT_TRUE(info->detachable_handler());
  info->detachable_handler()->set_cancel_delay(
      base::TimeDelta::FromMilliseconds(200));
  content::RunAllTasksUntilIdle();

  // Cancel the requests to the test process.
  host_.CancelRequestsForProcess(filter_->child_id());
  EXPECT_EQ(1, host_.pending_requests());

  // Wait until after the delay timer times out before we start processing any
  // messages.
  base::RunLoop run_loop;
  base::OneShotTimer timer;
  timer.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(210),
              base::BindOnce(&base::RunLoop::QuitWhenIdle,
                             base::Unretained(&run_loop)));
  run_loop.Run();

  // The prefetch should be cancelled by now.
  EXPECT_EQ(0, host_.pending_requests());

  // In case any messages are still to be processed.
  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
  content::RunAllTasksUntilIdle();

  // The request should have cancelled.
  client.RunUntilComplete();
  EXPECT_EQ(net::ERR_ABORTED, client.completion_status().error_code);
  // And not run to completion.
  EXPECT_EQ(1, network_delegate()->completed_requests());
  EXPECT_EQ(1, network_delegate()->canceled_requests());
  EXPECT_EQ(0, network_delegate()->error_count());
}

// Tests blocking and resuming requests.
TEST_P(ResourceDispatcherHostTest, TestBlockingResumingRequests) {
  network::mojom::URLLoaderPtr loader1, loader2, loader3, loader4, loader5,
      loader6, loader7;
  network::TestURLLoaderClient client1, client2, client3, client4, client5,
      client6, client7;

  host_.BlockRequestsForRoute(GlobalFrameRoutingId(filter_->child_id(), 11));
  host_.BlockRequestsForRoute(GlobalFrameRoutingId(filter_->child_id(), 12));
  host_.BlockRequestsForRoute(GlobalFrameRoutingId(filter_->child_id(), 13));

  MakeTestRequestWithRenderFrame(0, 10, 1, net::URLRequestTestJob::test_url_1(),
                                 RESOURCE_TYPE_SUB_RESOURCE,
                                 mojo::MakeRequest(&loader1),
                                 client1.CreateInterfacePtr());
  MakeTestRequestWithRenderFrame(1, 11, 2, net::URLRequestTestJob::test_url_2(),
                                 RESOURCE_TYPE_SUB_RESOURCE,
                                 mojo::MakeRequest(&loader2),
                                 client2.CreateInterfacePtr());
  MakeTestRequestWithRenderFrame(0, 10, 3, net::URLRequestTestJob::test_url_3(),
                                 RESOURCE_TYPE_SUB_RESOURCE,
                                 mojo::MakeRequest(&loader3),
                                 client3.CreateInterfacePtr());
  MakeTestRequestWithRenderFrame(1, 11, 4, net::URLRequestTestJob::test_url_1(),
                                 RESOURCE_TYPE_SUB_RESOURCE,
                                 mojo::MakeRequest(&loader4),
                                 client4.CreateInterfacePtr());
  MakeTestRequestWithRenderFrame(2, 12, 5, net::URLRequestTestJob::test_url_2(),
                                 RESOURCE_TYPE_SUB_RESOURCE,
                                 mojo::MakeRequest(&loader5),
                                 client5.CreateInterfacePtr());
  MakeTestRequestWithRenderFrame(3, 13, 6, net::URLRequestTestJob::test_url_3(),
                                 RESOURCE_TYPE_SUB_RESOURCE,
                                 mojo::MakeRequest(&loader6),
                                 client6.CreateInterfacePtr());

  // Flush all the pending requests
  content::RunAllTasksUntilIdle();
  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}

  CheckSuccessfulRequest(&client1, net::URLRequestTestJob::test_data_1());
  CheckSuccessfulRequest(&client3, net::URLRequestTestJob::test_data_3());
  EXPECT_FALSE(client2.has_received_completion());
  EXPECT_FALSE(client4.has_received_completion());
  EXPECT_FALSE(client5.has_received_completion());
  EXPECT_FALSE(client6.has_received_completion());

  // Resume requests for RFH 11 and flush pending requests.
  host_.ResumeBlockedRequestsForRoute(
      GlobalFrameRoutingId(filter_->child_id(), 11));
  content::RunAllTasksUntilIdle();
  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}

  CheckSuccessfulRequest(&client2, net::URLRequestTestJob::test_data_2());
  CheckSuccessfulRequest(&client4, net::URLRequestTestJob::test_data_1());
  EXPECT_FALSE(client5.has_received_completion());
  EXPECT_FALSE(client6.has_received_completion());

  // Test that new requests are not blocked for RFH 11.
  MakeTestRequestWithRenderFrame(1, 11, 7, net::URLRequestTestJob::test_url_1(),
                                 RESOURCE_TYPE_SUB_RESOURCE,
                                 mojo::MakeRequest(&loader7),
                                 client7.CreateInterfacePtr());
  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
  CheckSuccessfulRequest(&client7, net::URLRequestTestJob::test_data_1());
  EXPECT_FALSE(client5.has_received_completion());
  EXPECT_FALSE(client6.has_received_completion());

  // Now resumes requests for all RFH (12 and 13).
  host_.ResumeBlockedRequestsForRoute(
      GlobalFrameRoutingId(filter_->child_id(), 12));
  host_.ResumeBlockedRequestsForRoute(
      GlobalFrameRoutingId(filter_->child_id(), 13));
  content::RunAllTasksUntilIdle();
  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}

  CheckSuccessfulRequest(&client5, net::URLRequestTestJob::test_data_2());
  CheckSuccessfulRequest(&client6, net::URLRequestTestJob::test_data_3());
}

// Tests blocking and canceling requests.
TEST_P(ResourceDispatcherHostTest, TestBlockingCancelingRequests) {
  network::mojom::URLLoaderPtr loader1, loader2, loader3, loader4, loader5;
  network::TestURLLoaderClient client1, client2, client3, client4, client5;

  host_.BlockRequestsForRoute(GlobalFrameRoutingId(filter_->child_id(), 11));

  MakeTestRequestWithRenderFrame(0, 10, 1, net::URLRequestTestJob::test_url_1(),
                                 RESOURCE_TYPE_SUB_RESOURCE,
                                 mojo::MakeRequest(&loader1),
                                 client1.CreateInterfacePtr());
  MakeTestRequestWithRenderFrame(1, 11, 2, net::URLRequestTestJob::test_url_2(),
                                 RESOURCE_TYPE_SUB_RESOURCE,
                                 mojo::MakeRequest(&loader2),
                                 client2.CreateInterfacePtr());
  MakeTestRequestWithRenderFrame(0, 10, 3, net::URLRequestTestJob::test_url_3(),
                                 RESOURCE_TYPE_SUB_RESOURCE,
                                 mojo::MakeRequest(&loader3),
                                 client3.CreateInterfacePtr());
  MakeTestRequestWithRenderFrame(1, 11, 4, net::URLRequestTestJob::test_url_1(),
                                 RESOURCE_TYPE_SUB_RESOURCE,
                                 mojo::MakeRequest(&loader4),
                                 client4.CreateInterfacePtr());
  // Blocked detachable resources should not delay cancellation.
  //
  MakeTestRequestWithRenderFrame(1, 11, 5, net::URLRequestTestJob::test_url_4(),
                                 RESOURCE_TYPE_PREFETCH,  // detachable type
                                 mojo::MakeRequest(&loader5),
                                 client5.CreateInterfacePtr());
  // Flush all the pending requests.
  content::RunAllTasksUntilIdle();
  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}

  CheckSuccessfulRequest(&client1, net::URLRequestTestJob::test_data_1());
  CheckSuccessfulRequest(&client3, net::URLRequestTestJob::test_data_3());
  EXPECT_FALSE(IsAborted(client2));
  EXPECT_FALSE(IsAborted(client4));
  EXPECT_FALSE(IsAborted(client5));

  // Cancel requests for RFH 11.
  host_.CancelBlockedRequestsForRoute(
      GlobalFrameRoutingId(filter_->child_id(), 11));
  content::RunAllTasksUntilIdle();
  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}

  EXPECT_TRUE(IsAborted(client2));
  EXPECT_TRUE(IsAborted(client4));
  EXPECT_TRUE(IsAborted(client5));
}

// Tests that blocked requests are canceled if their associated process dies.
TEST_P(ResourceDispatcherHostTest, TestBlockedRequestsProcessDies) {
  network::mojom::URLLoaderPtr loader1, loader2, loader3, loader4, loader5;
  network::TestURLLoaderClient client1, client2, client3, client4, client5;
  // This second filter is used to emulate a second process.
  scoped_refptr<TestFilter> second_filter = MakeTestFilter();

  host_.BlockRequestsForRoute(
      GlobalFrameRoutingId(second_filter->child_id(), 0));

  MakeTestRequestWithResourceType(
      filter_.get(), 0, 1, net::URLRequestTestJob::test_url_1(),
      RESOURCE_TYPE_SUB_RESOURCE, mojo::MakeRequest(&loader1),
      client1.CreateInterfacePtr());
  MakeTestRequestWithResourceType(
      second_filter.get(), 0, 2, net::URLRequestTestJob::test_url_2(),
      RESOURCE_TYPE_SUB_RESOURCE, mojo::MakeRequest(&loader2),
      client2.CreateInterfacePtr());
  MakeTestRequestWithResourceType(
      filter_.get(), 0, 3, net::URLRequestTestJob::test_url_3(),
      RESOURCE_TYPE_SUB_RESOURCE, mojo::MakeRequest(&loader3),
      client3.CreateInterfacePtr());
  MakeTestRequestWithResourceType(
      second_filter.get(), 0, 4, net::URLRequestTestJob::test_url_1(),
      RESOURCE_TYPE_SUB_RESOURCE, mojo::MakeRequest(&loader4),
      client4.CreateInterfacePtr());
  MakeTestRequestWithResourceType(
      second_filter.get(), 0, 5, net::URLRequestTestJob::test_url_4(),
      RESOURCE_TYPE_PREFETCH,  // detachable type
      mojo::MakeRequest(&loader5), client5.CreateInterfacePtr());

  // Simulate process death.
  host_.CancelRequestsForProcess(second_filter->child_id());

  // Flush all the pending requests.
  content::RunAllTasksUntilIdle();
  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}

  CheckSuccessfulRequest(&client1, net::URLRequestTestJob::test_data_1());
  CheckSuccessfulRequest(&client3, net::URLRequestTestJob::test_data_3());
  EXPECT_TRUE(IsAborted(client2));
  EXPECT_TRUE(IsAborted(client4));
  EXPECT_TRUE(IsAborted(client5));

  EXPECT_TRUE(host_.blocked_loaders_map_.empty());
  second_filter->OnChannelClosing();
}

// Tests that blocked requests don't leak when the ResourceDispatcherHost goes
// away.  Note that we rely on Purify for finding the leaks if any.
// If this test turns the Purify bot red, check the ResourceDispatcherHost
// destructor to make sure the blocked requests are deleted.
TEST_P(ResourceDispatcherHostTest, TestBlockedRequestsDontLeak) {
  network::mojom::URLLoaderPtr loader1, loader2, loader3, loader4, loader5,
      loader6, loader7, loader8;
  network::TestURLLoaderClient client1, client2, client3, client4, client5,
      client6, client7, client8;
  // This second filter is used to emulate a second process.
  scoped_refptr<TestFilter> second_filter = MakeTestFilter();

  host_.BlockRequestsForRoute(GlobalFrameRoutingId(filter_->child_id(), 1));
  host_.BlockRequestsForRoute(GlobalFrameRoutingId(filter_->child_id(), 2));
  host_.BlockRequestsForRoute(
      GlobalFrameRoutingId(second_filter->child_id(), 1));

  MakeTestRequestWithResourceType(
      filter_.get(), 0, 1, net::URLRequestTestJob::test_url_1(),
      RESOURCE_TYPE_SUB_RESOURCE, mojo::MakeRequest(&loader1),
      client1.CreateInterfacePtr());
  MakeTestRequestWithResourceType(
      filter_.get(), 1, 2, net::URLRequestTestJob::test_url_2(),
      RESOURCE_TYPE_SUB_RESOURCE, mojo::MakeRequest(&loader2),
      client2.CreateInterfacePtr());
  MakeTestRequestWithResourceType(
      filter_.get(), 0, 3, net::URLRequestTestJob::test_url_3(),
      RESOURCE_TYPE_SUB_RESOURCE, mojo::MakeRequest(&loader3),
      client3.CreateInterfacePtr());
  MakeTestRequestWithResourceType(
      second_filter.get(), 1, 4, net::URLRequestTestJob::test_url_1(),
      RESOURCE_TYPE_SUB_RESOURCE, mojo::MakeRequest(&loader4),
      client4.CreateInterfacePtr());
  MakeTestRequestWithResourceType(
      filter_.get(), 2, 5, net::URLRequestTestJob::test_url_2(),
      RESOURCE_TYPE_SUB_RESOURCE, mojo::MakeRequest(&loader5),
      client5.CreateInterfacePtr());
  MakeTestRequestWithResourceType(
      filter_.get(), 2, 6, net::URLRequestTestJob::test_url_3(),
      RESOURCE_TYPE_SUB_RESOURCE, mojo::MakeRequest(&loader6),
      client6.CreateInterfacePtr());
  MakeTestRequestWithResourceType(
      filter_.get(), 0, 7, net::URLRequestTestJob::test_url_4(),
      RESOURCE_TYPE_PREFETCH,  // detachable type
      mojo::MakeRequest(&loader7), client7.CreateInterfacePtr());
  MakeTestRequestWithResourceType(
      second_filter.get(), 1, 8, net::URLRequestTestJob::test_url_4(),
      RESOURCE_TYPE_PREFETCH,  // detachable type
      mojo::MakeRequest(&loader8), client8.CreateInterfacePtr());

  host_.CancelRequestsForProcess(filter_->child_id());
  host_.CancelRequestsForProcess(second_filter->child_id());

  // Flush all the pending requests.
  content::RunAllTasksUntilIdle();
  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}

  second_filter->OnChannelClosing();
}

// Test the private helper method "CalculateApproximateMemoryCost()".
TEST_P(ResourceDispatcherHostTest, CalculateApproximateMemoryCost) {
  net::URLRequestContext context;
  std::unique_ptr<net::URLRequest> req(context.CreateRequest(
      GURL("http://www.google.com"), net::DEFAULT_PRIORITY, nullptr,
      TRAFFIC_ANNOTATION_FOR_TESTS));
  EXPECT_EQ(4425, ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(
                      req.get()));

  // Add 9 bytes of referrer.
  req->SetReferrer("123456789");
  EXPECT_EQ(4434, ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(
                      req.get()));

  // Add 33 bytes of upload content.
  std::string upload_content;
  upload_content.resize(33);
  std::fill(upload_content.begin(), upload_content.end(), 'x');
  std::unique_ptr<net::UploadElementReader> reader(
      new net::UploadBytesElementReader(upload_content.data(),
                                        upload_content.size()));
  req->set_upload(
      net::ElementsUploadDataStream::CreateWithReader(std::move(reader), 0));

  // Since the upload throttling is disabled, this has no effect on the cost.
  EXPECT_EQ(4434, ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(
                      req.get()));
}

// Test that too much memory for outstanding requests for a particular
// render_process_host_id causes requests to fail.
TEST_P(ResourceDispatcherHostTest, TooMuchOutstandingRequestsMemory) {
  // Expected cost of each request as measured by
  // ResourceDispatcherHost::CalculateApproximateMemoryCost().
  const int kMemoryCostOfTest2Req =
      ResourceDispatcherHostImpl::kAvgBytesPerOutstandingRequest +
      net::URLRequestTestJob::test_url_2().spec().size() + sizeof("GET") - 1;

  // Tighten the bound on the ResourceDispatcherHost, to speed things up.
  constexpr int kMaxCostPerProcess = 440000;
  host_.set_max_outstanding_requests_cost_per_process(kMaxCostPerProcess);

  // Determine how many instance of test_url_2() we can request before
  // throttling kicks in.
  const size_t kMaxRequests = kMaxCostPerProcess / kMemoryCostOfTest2Req;

  auto loaders =
      std::make_unique<network::mojom::URLLoaderPtr[]>(kMaxRequests + 4);
  auto clients =
      std::make_unique<network::TestURLLoaderClient[]>(kMaxRequests + 4);
  network::mojom::URLLoaderPtr loader1, loader2, loader3, loader4;
  network::TestURLLoaderClient client1, client2, client3, client4;

  // This second filter is used to emulate a second process.
  scoped_refptr<TestFilter> second_filter = MakeTestFilter();

  // Saturate the number of outstanding requests for our process.
  for (size_t i = 0; i < kMaxRequests; ++i) {
    MakeTestRequestWithResourceType(
        filter_.get(), 0, i + 1, net::URLRequestTestJob::test_url_2(),
        RESOURCE_TYPE_SUB_RESOURCE, mojo::MakeRequest(&loaders[i]),
        clients[i].CreateInterfacePtr());
  }

  // Issue two more requests for our process -- these should fail immediately.
  MakeTestRequestWithResourceType(
      filter_.get(), 0, kMaxRequests + 1, net::URLRequestTestJob::test_url_2(),
      RESOURCE_TYPE_SUB_RESOURCE, mojo::MakeRequest(&loaders[kMaxRequests]),
      clients[kMaxRequests].CreateInterfacePtr());
  MakeTestRequestWithResourceType(
      filter_.get(), 0, kMaxRequests + 2, net::URLRequestTestJob::test_url_2(),
      RESOURCE_TYPE_SUB_RESOURCE, mojo::MakeRequest(&loaders[kMaxRequests + 1]),
      clients[kMaxRequests + 1].CreateInterfacePtr());
  // Issue two requests for the second process -- these should succeed since
  // it is just process 0 that is saturated.
  MakeTestRequestWithResourceType(
      second_filter.get(), 0, kMaxRequests + 3,
      net::URLRequestTestJob::test_url_2(), RESOURCE_TYPE_SUB_RESOURCE,
      mojo::MakeRequest(&loaders[kMaxRequests + 2]),
      clients[kMaxRequests + 2].CreateInterfacePtr());
  MakeTestRequestWithResourceType(
      second_filter.get(), 0, kMaxRequests + 4,
      net::URLRequestTestJob::test_url_2(), RESOURCE_TYPE_SUB_RESOURCE,
      mojo::MakeRequest(&loaders[kMaxRequests + 3]),
      clients[kMaxRequests + 3].CreateInterfacePtr());
  // Flush all the pending requests.
  content::RunAllTasksUntilIdle();
  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {
  }

  // Check that the first kMaxRequests succeeded.
  for (size_t i = 0; i < kMaxRequests; ++i)
    CheckSuccessfulRequest(&clients[i], net::URLRequestTestJob::test_data_2());

  // Check that the subsequent two requests (kMaxRequests + 1) and
  // (kMaxRequests + 2) were failed, since the per-process bound was reached.
  clients[kMaxRequests].RunUntilComplete();
  EXPECT_EQ(net::ERR_INSUFFICIENT_RESOURCES,
            clients[kMaxRequests].completion_status().error_code);
  clients[kMaxRequests + 1].RunUntilComplete();
  EXPECT_EQ(net::ERR_INSUFFICIENT_RESOURCES,
            clients[kMaxRequests + 1].completion_status().error_code);

  // The final 2 requests should have succeeded.
  CheckSuccessfulRequest(&clients[kMaxRequests + 2],
                         net::URLRequestTestJob::test_data_2());
  CheckSuccessfulRequest(&clients[kMaxRequests + 3],
                         net::URLRequestTestJob::test_data_2());

  second_filter->OnChannelClosing();
}

// Test that when too many requests are outstanding for a particular
// render_process_host_id, any subsequent request from it fails. Also verify
// that the global limit is honored.
TEST_P(ResourceDispatcherHostTest, TooManyOutstandingRequests) {
  // Tighten the bound on the ResourceDispatcherHost, to speed things up.
  constexpr size_t kMaxRequestsPerProcess = 2;
  host_.set_max_num_in_flight_requests_per_process(kMaxRequestsPerProcess);
  constexpr size_t kMaxRequests = 3;
  host_.set_max_num_in_flight_requests(kMaxRequests);

  // Needed to emulate additional processes.
  scoped_refptr<TestFilter> second_filter = MakeTestFilter();
  scoped_refptr<TestFilter> third_filter = MakeTestFilter();

  network::mojom::URLLoaderPtr loaders[kMaxRequests + 3];
  network::TestURLLoaderClient clients[kMaxRequests + 3];

  // Saturate the number of outstanding requests for our process.
  for (size_t i = 0; i < kMaxRequestsPerProcess; ++i) {
    MakeTestRequestWithResourceType(
        filter_.get(), 0, i + 1, net::URLRequestTestJob::test_url_2(),
        RESOURCE_TYPE_SUB_RESOURCE, mojo::MakeRequest(&loaders[i]),
        clients[i].CreateInterfacePtr());
  }

  // Issue another request for our process -- this should fail immediately.
  MakeTestRequestWithResourceType(
      filter_.get(), 0, kMaxRequestsPerProcess + 1,
      net::URLRequestTestJob::test_url_2(), RESOURCE_TYPE_SUB_RESOURCE,
      mojo::MakeRequest(&loaders[kMaxRequestsPerProcess]),
      clients[kMaxRequestsPerProcess].CreateInterfacePtr());

  // Issue a request for the second process -- this should succeed, because it
  // is just process 0 that is saturated.
  MakeTestRequestWithResourceType(
      second_filter.get(), 0, kMaxRequestsPerProcess + 2,
      net::URLRequestTestJob::test_url_2(), RESOURCE_TYPE_SUB_RESOURCE,
      mojo::MakeRequest(&loaders[kMaxRequestsPerProcess + 1]),
      clients[kMaxRequestsPerProcess + 1].CreateInterfacePtr());

  // Issue a request for the third process -- this should fail, because the
  // global limit has been reached.
  MakeTestRequestWithResourceType(
      third_filter.get(), 0, kMaxRequestsPerProcess + 3,
      net::URLRequestTestJob::test_url_2(), RESOURCE_TYPE_SUB_RESOURCE,
      mojo::MakeRequest(&loaders[kMaxRequestsPerProcess + 2]),
      clients[kMaxRequestsPerProcess + 2].CreateInterfacePtr());

  // Flush all the pending requests.
  content::RunAllTasksUntilIdle();
  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {
  }

  for (size_t i = 0; i < kMaxRequestsPerProcess; ++i)
    CheckSuccessfulRequest(&clients[i], net::URLRequestTestJob::test_data_2());

  clients[kMaxRequestsPerProcess].RunUntilComplete();
  EXPECT_EQ(net::ERR_INSUFFICIENT_RESOURCES,
            clients[kMaxRequestsPerProcess].completion_status().error_code);
  clients[kMaxRequestsPerProcess + 1].RunUntilComplete();
  EXPECT_EQ(net::ERR_INSUFFICIENT_RESOURCES,
            clients[kMaxRequestsPerProcess + 1].completion_status().error_code);
  clients[kMaxRequestsPerProcess + 2].RunUntilComplete();
  EXPECT_EQ(net::ERR_INSUFFICIENT_RESOURCES,
            clients[kMaxRequestsPerProcess + 2].completion_status().error_code);

  second_filter->OnChannelClosing();
  third_filter->OnChannelClosing();
}

// Tests that we sniff the mime type for a simple request.
TEST_P(ResourceDispatcherHostTest, MimeSniffed) {
  network::mojom::URLLoaderPtr loader;
  network::TestURLLoaderClient client;
  std::string raw_headers("HTTP/1.1 200 OK\n\n");
  std::string response_data("<html><title>Test One</title></html>");
  SetResponse(raw_headers, response_data);

  HandleScheme("http");
  MakeTestRequest(0, 1, GURL("http:bla"), mojo::MakeRequest(&loader),
                  client.CreateInterfacePtr());

  // Flush all pending requests.
  content::RunAllTasksUntilIdle();
  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}

  client.RunUntilResponseReceived();
  EXPECT_EQ("text/html", client.response_head().mime_type);
  EXPECT_TRUE(client.response_head().did_mime_sniff);
}

// Tests that we don't sniff the mime type when the server provides one.
TEST_P(ResourceDispatcherHostTest, MimeNotSniffed) {
  network::mojom::URLLoaderPtr loader;
  network::TestURLLoaderClient client;
  std::string raw_headers("HTTP/1.1 200 OK\n"
                          "Content-type: image/jpeg\n\n");
  std::string response_data("<html><title>Test One</title></html>");
  SetResponse(raw_headers, response_data);

  HandleScheme("http");
  MakeTestRequest(0, 1, GURL("http:bla"), mojo::MakeRequest(&loader),
                  client.CreateInterfacePtr());

  // Flush all pending requests.
  content::RunAllTasksUntilIdle();
  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}

  client.RunUntilResponseReceived();
  EXPECT_EQ("image/jpeg", client.response_head().mime_type);
  EXPECT_FALSE(client.response_head().did_mime_sniff);
}

// Tests that we don't sniff the mime type when there is no message body.
TEST_P(ResourceDispatcherHostTest, MimeNotSniffed2) {
  network::mojom::URLLoaderPtr loader;
  network::TestURLLoaderClient client;
  SetResponse("HTTP/1.1 304 Not Modified\n\n");

  HandleScheme("http");
  MakeTestRequest(0, 1, GURL("http:bla"), mojo::MakeRequest(&loader),
                  client.CreateInterfacePtr());

  // Flush all pending requests.
  content::RunAllTasksUntilIdle();
  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}

  client.RunUntilResponseReceived();
  EXPECT_EQ("", client.response_head().mime_type);
}

TEST_P(ResourceDispatcherHostTest, MimeSniff204) {
  network::mojom::URLLoaderPtr loader;
  network::TestURLLoaderClient client;
  SetResponse("HTTP/1.1 204 No Content\n\n");

  HandleScheme("http");
  MakeTestRequest(0, 1, GURL("http:bla"), mojo::MakeRequest(&loader),
                  client.CreateInterfacePtr());

  // Flush all pending requests.
  content::RunAllTasksUntilIdle();
  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}

  client.RunUntilResponseReceived();
  EXPECT_EQ("text/plain", client.response_head().mime_type);
}

TEST_P(ResourceDispatcherHostTest, MimeSniffEmpty) {
  network::mojom::URLLoaderPtr loader;
  network::TestURLLoaderClient client;
  SetResponse("HTTP/1.1 200 OK\n\n");

  HandleScheme("http");
  MakeTestRequest(0, 1, GURL("http:bla"), mojo::MakeRequest(&loader),
                  client.CreateInterfacePtr());

  // Flush all pending requests.
  content::RunAllTasksUntilIdle();
  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}

  client.RunUntilResponseReceived();
  EXPECT_EQ("text/plain", client.response_head().mime_type);
}

// Tests for crbug.com/31266 (Non-2xx + application/octet-stream).
TEST_P(ResourceDispatcherHostTest, ForbiddenDownload) {
  std::string raw_headers("HTTP/1.1 403 Forbidden\n"
                          "Content-disposition: attachment; filename=blah\n"
                          "Content-type: application/octet-stream\n\n");
  std::string response_data("<html><title>Test One</title></html>");
  SetResponse(raw_headers, response_data);

  HandleScheme("http");

  int expected_error_code = net::ERR_INVALID_RESPONSE;
  GURL forbidden_download_url = GURL("http:bla");

  CompleteFailingMainResourceRequest(forbidden_download_url,
                                     expected_error_code);
}

TEST_P(ResourceDispatcherHostTest, CancelRequestsForContextDetached) {
  EXPECT_EQ(0, host_.pending_requests());
  network::mojom::URLLoaderPtr loader;
  network::TestURLLoaderClient client;
  constexpr int render_view_id = 0;
  constexpr int request_id = 1;

  MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id,
                                  net::URLRequestTestJob::test_url_4(),
                                  RESOURCE_TYPE_PREFETCH,  // detachable type
                                  mojo::MakeRequest(&loader),
                                  client.CreateInterfacePtr());

  // Simulate a cancel coming from the renderer.
  loader = nullptr;
  content::RunAllTasksUntilIdle();

  // Since the request had already started processing as detachable,
  // the cancellation above should have been ignored and the request
  // should have been detached.
  EXPECT_EQ(1, host_.pending_requests());

  // Cancelling by other methods should also leave it detached.
  host_.CancelRequestsForProcess(render_view_id);
  EXPECT_EQ(1, host_.pending_requests());

  // Cancelling by context should work.
  host_.CancelRequestsForContext(filter_->resource_context());
  EXPECT_EQ(0, host_.pending_requests());
}

namespace {

class ExternalProtocolBrowserClient : public TestContentBrowserClient {
 public:
  ExternalProtocolBrowserClient() {}

  bool HandleExternalProtocol(
      const GURL& url,
      ResourceRequestInfo::WebContentsGetter web_contents_getter,
      int child_id,
      NavigationUIData* navigation_data,
      bool is_main_frame,
      ui::PageTransition page_transition,
      bool has_user_gesture,
      const std::string& method,
      const net::HttpRequestHeaders& headers) override {
    return false;
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(ExternalProtocolBrowserClient);
};

}  // namespace

// Verifies that if the embedder says that it didn't handle an unkonown protocol
// the request is cancelled and net::ERR_ABORTED is returned. Otherwise it is
// not aborted and net/ layer cancels it with net::ERR_UNKNOWN_URL_SCHEME.
TEST_P(ResourceDispatcherHostTest, UnknownURLScheme) {
  EXPECT_EQ(0, host_.pending_requests());

  HandleScheme("http");

  ExternalProtocolBrowserClient test_client;
  ContentBrowserClient* old_client = SetBrowserClientForTesting(&test_client);

  const GURL invalid_scheme_url = GURL("foo://bar");
  int expected_error_code = net::ERR_UNKNOWN_URL_SCHEME;
  CompleteFailingMainResourceRequest(invalid_scheme_url, expected_error_code);
  SetBrowserClientForTesting(old_client);

  expected_error_code = net::ERR_ABORTED;
  CompleteFailingMainResourceRequest(invalid_scheme_url, expected_error_code);
}

// Request a very large detachable resource and cancel part way. Some of the
// data should have been sent to the renderer, but not all.
TEST_P(ResourceDispatcherHostTest, DataSentBeforeDetach) {
  EXPECT_EQ(0, host_.pending_requests());

  constexpr int render_view_id = 0;
  constexpr int request_id = 1;
  network::mojom::URLLoaderPtr loader;
  network::TestURLLoaderClient client;

  std::string raw_headers("HTTP\n"
                          "Content-type: image/jpeg\n\n");
  std::string response_data("01234567890123456789\x01foobar");

  // Create a response larger than kMaxAllocationSize (currently 32K). Note
  // that if this increase beyond 512K we'll need to make the response longer.
  const int kAllocSize = 1024*512;
  response_data.resize(kAllocSize, ' ');

  SetResponse(raw_headers, response_data);
  job_factory_->SetDelayedCompleteJobGeneration(true);
  HandleScheme("http");

  MakeTestRequestWithResourceType(
      filter_.get(), render_view_id, request_id,
      GURL("http://example.com/blah"), RESOURCE_TYPE_PREFETCH,
      mojo::MakeRequest(&loader), client.CreateInterfacePtr());
  content::RunAllTasksUntilIdle();

  // Get a bit of data before cancelling.
  EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
  client.RunUntilResponseBodyArrived();

  // Simulate a cancellation coming from the renderer.
  loader = nullptr;
  content::RunAllTasksUntilIdle();

  EXPECT_EQ(1, host_.pending_requests());

  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}

  // Verify the data that was received before cancellation. The request should
  // have appeared to cancel, however.
  client.RunUntilComplete();
  EXPECT_TRUE(client.response_body().is_valid());
  EXPECT_EQ(net::ERR_ABORTED, client.completion_status().error_code);
}

WebContents* WebContentsBinder(WebContents* rv) { return rv; }

// Tests GetLoadInfoForAllRoutes when there are 3 requests from the same
// RenderView.  The second one is farthest along.
TEST_P(ResourceDispatcherHostTest, LoadInfo) {
  std::unique_ptr<LoadInfoList> infos(new LoadInfoList);
  LoadInfo info;
  WebContents* wc1 = reinterpret_cast<WebContents*>(0x1);
  info.web_contents_getter = base::Bind(WebContentsBinder, wc1);
  info.load_state = net::LoadStateWithParam(net::LOAD_STATE_SENDING_REQUEST,
                                            base::string16());
  info.host = "a.com";
  info.upload_position = 0;
  info.upload_size = 0;
  infos->push_back(info);

  info.host = "b.com";
  info.load_state = net::LoadStateWithParam(net::LOAD_STATE_READING_RESPONSE,
                                            base::string16());
  infos->push_back(info);

  info.host = "c.com";

  std::unique_ptr<LoadInfoMap> load_info_map =
      ResourceDispatcherHostImpl::PickMoreInterestingLoadInfos(
          std::move(infos));
  ASSERT_EQ(1u, load_info_map->size());
  ASSERT_TRUE(load_info_map->find(wc1) != load_info_map->end());
  EXPECT_EQ("b.com", (*load_info_map)[wc1].host);
  EXPECT_EQ(net::LOAD_STATE_READING_RESPONSE,
            (*load_info_map)[wc1].load_state.state);
  EXPECT_EQ(0u, (*load_info_map)[wc1].upload_position);
  EXPECT_EQ(0u, (*load_info_map)[wc1].upload_size);
}

// Tests GetLoadInfoForAllRoutes when there are 2 requests with the same
// priority.  The first one (Which will have the lowest ID) should be returned.
TEST_P(ResourceDispatcherHostTest, LoadInfoSamePriority) {
  std::unique_ptr<LoadInfoList> infos(new LoadInfoList);
  LoadInfo info;
  WebContents* wc1 = reinterpret_cast<WebContents*>(0x1);
  info.web_contents_getter = base::Bind(WebContentsBinder, wc1);
  info.load_state = net::LoadStateWithParam(net::LOAD_STATE_IDLE,
                                            base::string16());
  info.host = "a.com";
  info.upload_position = 0;
  info.upload_size = 0;
  infos->push_back(info);

  info.host = "b.com";
  infos->push_back(info);

  std::unique_ptr<LoadInfoMap> load_info_map =
      ResourceDispatcherHostImpl::PickMoreInterestingLoadInfos(
          std::move(infos));
  ASSERT_EQ(1u, load_info_map->size());
  ASSERT_TRUE(load_info_map->find(wc1) != load_info_map->end());
  EXPECT_EQ("a.com", (*load_info_map)[wc1].host);
  EXPECT_EQ(net::LOAD_STATE_IDLE, (*load_info_map)[wc1].load_state.state);
  EXPECT_EQ(0u, (*load_info_map)[wc1].upload_position);
  EXPECT_EQ(0u, (*load_info_map)[wc1].upload_size);
}

// Tests GetLoadInfoForAllRoutes when a request is uploading a body.
TEST_P(ResourceDispatcherHostTest, LoadInfoUploadProgress) {
  std::unique_ptr<LoadInfoList> infos(new LoadInfoList);
  LoadInfo info;
  WebContents* wc1 = reinterpret_cast<WebContents*>(0x1);
  info.web_contents_getter = base::Bind(WebContentsBinder, wc1);
  info.load_state = net::LoadStateWithParam(net::LOAD_STATE_READING_RESPONSE,
                                            base::string16());
  info.host = "a.com";
  info.upload_position = 0;
  info.upload_size = 0;
  infos->push_back(info);

  info.upload_position = 1000;
  info.upload_size = 1000;
  infos->push_back(info);

  info.host = "b.com";
  info.load_state = net::LoadStateWithParam(net::LOAD_STATE_SENDING_REQUEST,
                                            base::string16());
  info.upload_position = 50;
  info.upload_size = 100;
  infos->push_back(info);

  info.host = "a.com";
  info.load_state = net::LoadStateWithParam(net::LOAD_STATE_READING_RESPONSE,
                                            base::string16());
  info.upload_position = 1000;
  info.upload_size = 1000;
  infos->push_back(info);

  info.host = "c.com";
  info.upload_position = 0;
  info.upload_size = 0;
  infos->push_back(info);

  std::unique_ptr<LoadInfoMap> load_info_map =
      ResourceDispatcherHostImpl::PickMoreInterestingLoadInfos(
          std::move(infos));
  ASSERT_EQ(1u, load_info_map->size());
  ASSERT_TRUE(load_info_map->find(wc1) != load_info_map->end());
  EXPECT_EQ("b.com", (*load_info_map)[wc1].host);
  EXPECT_EQ(net::LOAD_STATE_SENDING_REQUEST,
            (*load_info_map)[wc1].load_state.state);
  EXPECT_EQ(50u, (*load_info_map)[wc1].upload_position);
  EXPECT_EQ(100u, (*load_info_map)[wc1].upload_size);
}

// Tests GetLoadInfoForAllRoutes when there are 4 requests from 2 different
// RenderViews.  Also tests the case where the first / last requests are the
// most interesting ones.
TEST_P(ResourceDispatcherHostTest, LoadInfoTwoRenderViews) {
  std::unique_ptr<LoadInfoList> infos(new LoadInfoList);
  LoadInfo info;
  WebContents* wc1 = reinterpret_cast<WebContents*>(0x1);
  info.web_contents_getter = base::Bind(WebContentsBinder, wc1);
  info.load_state = net::LoadStateWithParam(net::LOAD_STATE_CONNECTING,
                                            base::string16());
  info.host = "a.com";
  info.upload_position = 0;
  info.upload_size = 0;
  infos->push_back(info);

  WebContents* wc2 = reinterpret_cast<WebContents*>(0x2);
  info.web_contents_getter = base::Bind(WebContentsBinder, wc2);
  info.load_state = net::LoadStateWithParam(net::LOAD_STATE_IDLE,
                                            base::string16());
  info.host = "b.com";
  infos->push_back(info);

  info.web_contents_getter = base::Bind(WebContentsBinder, wc1);
  info.host = "c.com";
  infos->push_back(info);

  info.web_contents_getter = base::Bind(WebContentsBinder, wc2);
  info.load_state = net::LoadStateWithParam(net::LOAD_STATE_CONNECTING,
                                            base::string16());
  info.host = "d.com";
  infos->push_back(info);

  std::unique_ptr<LoadInfoMap> load_info_map =
      ResourceDispatcherHostImpl::PickMoreInterestingLoadInfos(
          std::move(infos));
  ASSERT_EQ(2u, load_info_map->size());

  ASSERT_TRUE(load_info_map->find(wc1) != load_info_map->end());
  EXPECT_EQ("a.com", (*load_info_map)[wc1].host);
  EXPECT_EQ(net::LOAD_STATE_CONNECTING,
            (*load_info_map)[wc1].load_state.state);
  EXPECT_EQ(0u, (*load_info_map)[wc1].upload_position);
  EXPECT_EQ(0u, (*load_info_map)[wc1].upload_size);

  ASSERT_TRUE(load_info_map->find(wc2) != load_info_map->end());
  EXPECT_EQ("d.com", (*load_info_map)[wc2].host);
  EXPECT_EQ(net::LOAD_STATE_CONNECTING,
            (*load_info_map)[wc2].load_state.state);
  EXPECT_EQ(0u, (*load_info_map)[wc2].upload_position);
  EXPECT_EQ(0u, (*load_info_map)[wc2].upload_size);
}

// Tests that a ResourceThrottle that needs to process the response before any
// part of the body is read can do so.
TEST_P(ResourceDispatcherHostTest, ThrottleMustProcessResponseBeforeRead) {
  // Ensure all jobs will check that no read operation is called.
  job_factory_->SetMustNotReadJobGeneration(true);
  HandleScheme("http");

  // Create a ResourceThrottle that must process the response before any part of
  // the body is read. This throttle will also cancel the request in
  // WillProcessResponse.
  TestResourceDispatcherHostDelegate delegate;
  int throttle_flags = CANCEL_PROCESSING_RESPONSE | MUST_NOT_CACHE_BODY;
  delegate.set_flags(throttle_flags);
  host_.SetDelegate(&delegate);

  // This response should normally result in the MIME type being sniffed, which
  // requires reading the body.
  std::string raw_headers(
      "HTTP/1.1 200 OK\n"
      "Content-Type: text/plain; charset=utf-8\n\n");
  std::string response_data("p { text-align: center; }");
  SetResponse(raw_headers, response_data);
  network::mojom::URLLoaderPtr loader;
  network::TestURLLoaderClient client;

  MakeTestRequestWithResourceType(
      filter_.get(), filter_->child_id(), 1, GURL("http://example.com/blah"),
      RESOURCE_TYPE_STYLESHEET, mojo::MakeRequest(&loader),
      client.CreateInterfacePtr());

  while (net::URLRequestTestJob::ProcessOnePendingMessage()) {
  }
  content::RunAllTasksUntilIdle();
}

// A URLRequestTestJob that sets a test certificate on the |ssl_info|
// field of the response.
class TestHTTPSURLRequestJob : public net::URLRequestTestJob {
 public:
  TestHTTPSURLRequestJob(net::URLRequest* request,
                         net::NetworkDelegate* network_delegate,
                         const std::string& response_headers,
                         const std::string& response_data,
                         bool auto_advance)
      : net::URLRequestTestJob(request,
                               network_delegate,
                               response_headers,
                               response_data,
                               auto_advance) {}

  void GetResponseInfo(net::HttpResponseInfo* info) override {
    net::URLRequestTestJob::GetResponseInfo(info);
    info->ssl_info.cert =
        net::ImportCertFromFile(net::GetTestCertsDirectory(), "ok_cert.pem");
  }
};

net::URLRequestJob* TestURLRequestJobFactory::MaybeCreateJobWithProtocolHandler(
      const std::string& scheme,
      net::URLRequest* request,
      net::NetworkDelegate* network_delegate) const {
  url_request_jobs_created_count_++;
  if (hang_after_start_) {
    return new net::URLRequestFailedJob(request, network_delegate,
                                        net::ERR_IO_PENDING);
  }
  if (test_fixture_->response_headers_.empty()) {
    if (delay_start_) {
      return new URLRequestTestDelayedStartJob(request, network_delegate);
    } else if (delay_complete_) {
      return new URLRequestTestDelayedCompletionJob(request,
                                                    network_delegate);
    } else if (scheme == "big-job") {
      return new URLRequestBigJob(request, network_delegate);
    } else {
      return new net::URLRequestTestJob(request, network_delegate,
                                        test_fixture_->auto_advance_);
    }
  } else {
    if (delay_start_) {
      return new URLRequestTestDelayedStartJob(
          request, network_delegate,
          test_fixture_->response_headers_, test_fixture_->response_data_,
          false);
    } else if (delay_complete_) {
      return new URLRequestTestDelayedCompletionJob(
          request, network_delegate,
          test_fixture_->response_headers_, test_fixture_->response_data_,
          false);
    } else if (must_not_read_) {
      return new URLRequestMustNotReadTestJob(request, network_delegate,
                                              test_fixture_->response_headers_,
                                              test_fixture_->response_data_);
    } else if (test_fixture_->use_test_ssl_certificate_) {
      return new TestHTTPSURLRequestJob(request, network_delegate,
                                        test_fixture_->response_headers_,
                                        test_fixture_->response_data_, false);
    } else {
      return new net::URLRequestTestJob(
          request, network_delegate, test_fixture_->response_headers_,
          test_fixture_->response_data_, test_fixture_->auto_advance_);
    }
  }
}

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

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

INSTANTIATE_TEST_CASE_P(WithoutOutOfBlinkCors,
                        ResourceDispatcherHostTest,
                        ::testing::Values(TestMode::kWithoutOutOfBlinkCors));

INSTANTIATE_TEST_CASE_P(WithOutOfBlinkCors,
                        ResourceDispatcherHostTest,
                        ::testing::Values(TestMode::kWithOutOfBlinkCors));

}  // namespace content
