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

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

#include "base/command_line.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/ref_counted.h"
#include "base/run_loop.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/bind.h"
#include "build/build_config.h"
#include "content/browser/download/download_manager_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/site_isolation_policy.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_client.h"
#include "content/public/common/network_service_util.h"
#include "content/public/common/url_constants.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_content_browser_client.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/test_utils.h"
#include "content/public/test/url_loader_interceptor.h"
#include "content/shell/browser/shell.h"
#include "net/base/filename_util.h"
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/http_request.h"
#include "net/test/embedded_test_server/http_response.h"
#include "net/test/url_request/url_request_failed_job.h"
#include "net/test/url_request/url_request_mock_http_job.h"
#include "services/network/public/cpp/features.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "third_party/blink/public/common/chrome_debug_urls.h"
#include "third_party/blink/public/common/loader/url_loader_throttle.h"
#include "url/gurl.h"

using base::ASCIIToUTF16;
using testing::HasSubstr;
using testing::Not;

namespace content {

class LoaderBrowserTest : public ContentBrowserTest,
                          public DownloadManager::Observer {
 public:
  LoaderBrowserTest() : got_downloads_(false) {}

 protected:
  void SetUpOnMainThread() override {
    base::FilePath path = GetTestFilePath("", "");
    GetIOThreadTaskRunner({})->PostTask(
        FROM_HERE,
        base::BindOnce(&net::URLRequestMockHTTPJob::AddUrlHandlers, path));
    GetIOThreadTaskRunner({})->PostTask(
        FROM_HERE, base::BindOnce(&net::URLRequestFailedJob::AddUrlHandler));
    host_resolver()->AddRule("*", "127.0.0.1");
  }

  void CheckTitleTest(const GURL& url, const std::string& expected_title) {
    std::u16string expected_title16(ASCIIToUTF16(expected_title));
    TitleWatcher title_watcher(shell()->web_contents(), expected_title16);
    EXPECT_TRUE(NavigateToURL(shell(), url));
    EXPECT_EQ(expected_title16, title_watcher.WaitAndGetTitle());
  }

  bool GetPopupTitle(const GURL& url, std::u16string* title) {
    EXPECT_TRUE(NavigateToURL(shell(), url));

    ShellAddedObserver new_shell_observer;

    // Create dynamic popup.
    if (!ExecJs(shell(), "OpenPopup();"))
      return false;

    Shell* new_shell = new_shell_observer.GetShell();
    *title = new_shell->web_contents()->GetTitle();
    return true;
  }

  std::string GetCookies(const GURL& url) {
    return content::GetCookies(shell()->web_contents()->GetBrowserContext(),
                               url);
  }

  bool got_downloads() const { return got_downloads_; }

 private:
  void SetUp() override {
    base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
        "cors_exempt_header_list", "ExemptFoo");
    ContentBrowserTest::SetUp();
  }

  bool got_downloads_;
};

// Test title for content created by javascript window.open().
// See http://crbug.com/5988
IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, DynamicTitle1) {
  ASSERT_TRUE(embedded_test_server()->Start());

  GURL url(embedded_test_server()->GetURL("/dynamic1.html"));
  std::u16string title;
  ASSERT_TRUE(GetPopupTitle(url, &title));
  EXPECT_TRUE(
      base::StartsWith(title, u"My Popup Title", base::CompareCase::SENSITIVE))
      << "Actual title: " << title;
}

// Test title for content created by javascript window.open().
// See http://crbug.com/5988
IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, DynamicTitle2) {
  ASSERT_TRUE(embedded_test_server()->Start());

  GURL url(embedded_test_server()->GetURL("/dynamic2.html"));
  std::u16string title;
  ASSERT_TRUE(GetPopupTitle(url, &title));
  EXPECT_TRUE(base::StartsWith(title, u"My Dynamic Title",
                               base::CompareCase::SENSITIVE))
      << "Actual title: " << title;
}

// Tests that the renderer does not crash when issuing a stale-revalidation
// request when the enable_referrers renderer preference is `false`. See
// https://crbug.com/966140.
IN_PROC_BROWSER_TEST_F(LoaderBrowserTest,
                       DisableReferrersStaleWhileRevalidate) {
  ASSERT_TRUE(embedded_test_server()->Start());
  WebContentsImpl* web_contents =
      static_cast<WebContentsImpl*>(shell()->web_contents());

  // Navigate to the page that will eventually fetch a stale-revalidation
  // request. Ensure that the renderer has not crashed.
  ASSERT_TRUE(NavigateToURL(
      shell(), embedded_test_server()->GetURL("/stale-while-revalidate.html")));

  // Force-disable the |enable_referrers| preference.
  web_contents->GetMutableRendererPrefs()->enable_referrers = false;
  web_contents->SyncRendererPrefs();

  // Wait for the stale-while-revalidate tests to pass by observing the page's
  // title. If the renderer crashes, the test immediately fails.
  std::u16string expected_title = u"Pass";
  TitleWatcher title_watcher(web_contents, expected_title);

  // The invocation of runTest() below starts a test written in JavaScript, that
  // after some time, creates a stale-revalidation request. The above IPC
  // message should be handled by the renderer (thus updating its preferences),
  // before this stale-revalidation request is sent. Technically nothing
  // guarantees this will happen, so it is theoretically possible the test is
  // racy, however in practice the renderer will always handle the IPC message
  // before the stale-revalidation request. This is because the renderer is
  // never completely blocked from the time the test starts.
  EXPECT_TRUE(ExecJs(shell(), "runTest()"));
  ASSERT_EQ(expected_title, title_watcher.WaitAndGetTitle());
}

IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, SniffNoContentTypeNoData) {
  // Make sure no downloads start.
  shell()
      ->web_contents()
      ->GetBrowserContext()
      ->GetDownloadManager()
      ->AddObserver(this);
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url(embedded_test_server()->GetURL("/content-sniffer-test3.html"));
  CheckTitleTest(url, "Content Sniffer Test 3");
  EXPECT_EQ(1u, Shell::windows().size());
  ASSERT_FALSE(got_downloads());
}

// Make sure file URLs are not sniffed as HTML when they don't end in HTML.
IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, DoNotSniffHTMLFromFileUrl) {
  base::FilePath path =
      GetTestFilePath(nullptr, "content-sniffer-test5.not-html");
  GURL file_url = net::FilePathToFileURL(path);
  // If the file isn't rendered as HTML, the title will match the name of the
  // file, rather than the contents of the file's title tag.
  CheckTitleTest(file_url, path.BaseName().MaybeAsASCII());
}

IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, ContentDispositionEmpty) {
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url(embedded_test_server()->GetURL("/content-disposition-empty.html"));
  CheckTitleTest(url, "success");
}

IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, ContentDispositionInline) {
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url(embedded_test_server()->GetURL("/content-disposition-inline.html"));
  CheckTitleTest(url, "success");
}

// Test for bug #1091358.
IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, SyncXMLHttpRequest) {
  ASSERT_TRUE(embedded_test_server()->Start());
  EXPECT_TRUE(NavigateToURL(
      shell(), embedded_test_server()->GetURL("/sync_xmlhttprequest.html")));

  // Let's check the XMLHttpRequest ran successfully.
  EXPECT_EQ(true, EvalJs(shell(), "DidSyncRequestSucceed();"));
}

// If this flakes, use http://crbug.com/62776.
IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, SyncXMLHttpRequest_Disallowed) {
  ASSERT_TRUE(embedded_test_server()->Start());
  EXPECT_TRUE(NavigateToURL(
      shell(),
      embedded_test_server()->GetURL("/sync_xmlhttprequest_disallowed.html")));

  // Let's check the XMLHttpRequest ran successfully.
  EXPECT_EQ(true, EvalJs(shell(), "DidSucceed();"));
}

// Test for bug #1159553 -- A synchronous xhr (whose content-type is
// downloadable) would trigger download and hang the renderer process,
// if executed while navigating to a new page.
// Disabled on Mac: see http://crbug.com/56264
#if BUILDFLAG(IS_MAC)
#define MAYBE_SyncXMLHttpRequest_DuringUnload \
  DISABLED_SyncXMLHttpRequest_DuringUnload
#else
#define MAYBE_SyncXMLHttpRequest_DuringUnload SyncXMLHttpRequest_DuringUnload
#endif
IN_PROC_BROWSER_TEST_F(LoaderBrowserTest,
                       MAYBE_SyncXMLHttpRequest_DuringUnload) {
  ASSERT_TRUE(embedded_test_server()->Start());
  shell()
      ->web_contents()
      ->GetBrowserContext()
      ->GetDownloadManager()
      ->AddObserver(this);

  CheckTitleTest(
      embedded_test_server()->GetURL("/sync_xmlhttprequest_during_unload.html"),
      "sync xhr on unload");

  // Navigate to a new page, to dispatch unload event and trigger xhr.
  // (the bug would make this step hang the renderer).
  CheckTitleTest(embedded_test_server()->GetURL("/title2.html"),
                 "Title Of Awesomeness");

  ASSERT_FALSE(got_downloads());
}

namespace {

// Responds with a HungResponse for the specified URL to hang on the request.
// It crashes the process.
//
// |crash_network_service_callback| crashes the network service when invoked,
// and must be called on the UI thread.
std::unique_ptr<net::test_server::HttpResponse> CancelOnRequest(
    const std::string& relative_url,
    int child_id,
    base::RepeatingClosure crash_network_service_callback,
    const net::test_server::HttpRequest& request) {
  if (request.relative_url != relative_url)
    return nullptr;

  content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
                                               crash_network_service_callback);

  return std::make_unique<net::test_server::HungResponse>();
}

}  // namespace

// Tests the case where the request is cancelled by a layer above the
// URLRequest, which passes the error on ResourceLoader teardown, rather than in
// response to call to AsyncResourceHandler::OnResponseComplete.
// Failed on Android M builder. See crbug/1111427.
#if BUILDFLAG(IS_ANDROID)
#define MAYBE_SyncXMLHttpRequest_Cancelled DISABLED_SyncXMLHttpRequest_Cancelled
#else
#define MAYBE_SyncXMLHttpRequest_Cancelled SyncXMLHttpRequest_Cancelled
#endif
IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, MAYBE_SyncXMLHttpRequest_Cancelled) {
  // If network service is running in-process, we can't simulate a crash.
  if (IsInProcessNetworkService())
    return;

  embedded_test_server()->RegisterRequestHandler(base::BindRepeating(
      &CancelOnRequest, "/hung",
      shell()->web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID(),
      base::BindRepeating(&BrowserTestBase::SimulateNetworkServiceCrash,
                          base::Unretained(this))));

  ASSERT_TRUE(embedded_test_server()->Start());
  WaitForLoadStop(shell()->web_contents());

  EXPECT_TRUE(NavigateToURL(
      shell(),
      embedded_test_server()->GetURL("/sync_xmlhttprequest_cancelled.html")));

  // 19 is the value of NETWORK_ERROR on DOMException.
  EXPECT_EQ(19, EvalJs(shell(), "getErrorCode();"));
}

// Flaky everywhere. http://crbug.com/130404
// Tests that onunload is run for cross-site requests.  (Bug 1114994)
IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, DISABLED_CrossSiteOnunloadCookie) {
  ASSERT_TRUE(embedded_test_server()->Start());

  GURL url = embedded_test_server()->GetURL("/onunload_cookie.html");
  CheckTitleTest(url, "set cookie on unload");

  // Navigate to a new cross-site page, to dispatch unload event and set the
  // cookie.
  CheckTitleTest(
      net::URLRequestMockHTTPJob::GetMockUrl("content-sniffer-test0.html"),
      "Content Sniffer Test 0");

  // Check that the cookie was set.
  EXPECT_EQ("onunloadCookie=foo", GetCookies(url));
}

// If this flakes, use http://crbug.com/130404
// Tests that onunload is run for cross-site requests to URLs that complete
// without network loads (e.g., about:blank, data URLs).
IN_PROC_BROWSER_TEST_F(LoaderBrowserTest,
                       DISABLED_CrossSiteImmediateLoadOnunloadCookie) {
  ASSERT_TRUE(embedded_test_server()->Start());

  GURL url = embedded_test_server()->GetURL("/onunload_cookie.html");
  CheckTitleTest(url, "set cookie on unload");

  // Navigate to a cross-site page that loads immediately without making a
  // network request.  The unload event should still be run.
  EXPECT_TRUE(NavigateToURL(shell(), GURL(url::kAboutBlankURL)));

  // Check that the cookie was set.
  EXPECT_EQ("onunloadCookie=foo", GetCookies(url));
}

namespace {

// Handles |request| by serving a redirect response.
std::unique_ptr<net::test_server::HttpResponse> NoContentResponseHandler(
    const std::string& path,
    const net::test_server::HttpRequest& request) {
  if (!base::StartsWith(path, request.relative_url,
                        base::CompareCase::SENSITIVE)) {
    return nullptr;
  }

  std::unique_ptr<net::test_server::BasicHttpResponse> http_response(
      new net::test_server::BasicHttpResponse);
  http_response->set_code(net::HTTP_NO_CONTENT);
  return std::move(http_response);
}

}  // namespace

// Tests that the unload handler is not run for 204 responses.
// If this flakes use http://crbug.com/80596.
IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, CrossSiteNoUnloadOn204) {
  const char kNoContentPath[] = "/nocontent";
  embedded_test_server()->RegisterRequestHandler(
      base::BindRepeating(&NoContentResponseHandler, kNoContentPath));

  ASSERT_TRUE(embedded_test_server()->Start());

  // Start with a URL that sets a cookie in its unload handler.
  GURL url = embedded_test_server()->GetURL("/onunload_cookie.html");
  CheckTitleTest(url, "set cookie on unload");

  // Navigate to a cross-site URL that returns a 204 No Content response.
  EXPECT_TRUE(NavigateToURLAndExpectNoCommit(
      shell(), embedded_test_server()->GetURL(kNoContentPath)));

  // Check that the unload cookie was not set.
  EXPECT_EQ("", GetCookies(url));
}

// Tests that the onbeforeunload and onunload logic is short-circuited if the
// old renderer is gone.  In that case, we don't want to wait for the old
// renderer to run the handlers.
// We need to disable this on Mac because the crash causes the OS CrashReporter
// process to kick in to analyze the poor dead renderer.  Unfortunately, if the
// app isn't stripped of debug symbols, this takes about five minutes to
// complete and isn't conducive to quick turnarounds. As we don't currently
// strip the app on the build bots, this is bad times.
#if BUILDFLAG(IS_MAC)
#define MAYBE_CrossSiteAfterCrash DISABLED_CrossSiteAfterCrash
#else
#define MAYBE_CrossSiteAfterCrash CrossSiteAfterCrash
#endif
IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, MAYBE_CrossSiteAfterCrash) {
  // Make sure we have a live process before trying to kill it.
  EXPECT_TRUE(NavigateToURL(shell(), GURL("about:blank")));

  // Cause the renderer to crash.
  RenderProcessHostWatcher crash_observer(
      shell()->web_contents(),
      RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
  EXPECT_FALSE(NavigateToURL(shell(), GURL(blink::kChromeUICrashURL)));
  // Wait for browser to notice the renderer crash.
  crash_observer.Wait();

  // Navigate to a new cross-site page.  The browser should not wait around for
  // the old renderer's on{before}unload handlers to run.
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url(embedded_test_server()->GetURL("/content-sniffer-test0.html"));
  CheckTitleTest(url, "Content Sniffer Test 0");
}

// Tests that cross-site navigations work when the new page does not go through
// the BufferedEventHandler (e.g., non-http{s} URLs).  (Bug 1225872)
IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, CrossSiteNavigationNonBuffered) {
  // Start with an HTTP page.
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url1(embedded_test_server()->GetURL("/content-sniffer-test0.html"));
  CheckTitleTest(url1, "Content Sniffer Test 0");

  // Now load a file:// page, which does not use the BufferedEventHandler.
  // Make sure that the page loads and displays a title, and doesn't get stuck.
  GURL url2 = GetTestUrl("", "title2.html");
  CheckTitleTest(url2, "Title Of Awesomeness");
}

// Flaky everywhere. http://crbug.com/130404
// Tests that a cross-site navigation to an error page (resulting in the link
// doctor page) still runs the onunload handler and can support navigations
// away from the link doctor page.  (Bug 1235537)
IN_PROC_BROWSER_TEST_F(LoaderBrowserTest,
                       DISABLED_CrossSiteNavigationErrorPage) {
  ASSERT_TRUE(embedded_test_server()->Start());

  GURL url(embedded_test_server()->GetURL("/onunload_cookie.html"));
  CheckTitleTest(url, "set cookie on unload");

  // Navigate to a new cross-site URL that results in an error.
  // TODO(creis): If this causes crashes or hangs, it might be for the same
  // reason as ErrorPageTest::DNSError.  See bug 1199491 and
  // http://crbug.com/22877.
  GURL failed_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  std::unique_ptr<URLLoaderInterceptor> url_interceptor =
      URLLoaderInterceptor::SetupRequestFailForURL(failed_url,
                                                   net::ERR_NAME_NOT_RESOLVED);
  EXPECT_FALSE(NavigateToURL(shell(), failed_url));

  EXPECT_NE(u"set cookie on unload", shell()->web_contents()->GetTitle());

  // Check that the cookie was set, meaning that the onunload handler ran.
  EXPECT_EQ("onunloadCookie=foo", GetCookies(url));

  // Check that renderer-initiated navigations still work.  In a previous bug,
  // the ResourceDispatcherHost would think that such navigations were
  // cross-site, because we didn't clean up from the previous request.  Since
  // WebContentsImpl was in the NORMAL state, it would ignore the attempt to run
  // the onunload handler, and the navigation would fail. We can't test by
  // redirecting to javascript:window.location='someURL', since javascript:
  // URLs are prohibited by policy from interacting with sensitive chrome
  // pages of which the error page is one.  Instead, use automation to kick
  // off the navigation, and wait to see that the tab loads.
  std::u16string expected_title16(u"Title Of Awesomeness");
  TitleWatcher title_watcher(shell()->web_contents(), expected_title16);

  GURL test_url(embedded_test_server()->GetURL("/title2.html"));
  std::string redirect_script =
      "window.location='" + test_url.possibly_invalid_spec() + "';" + "true;";
  EXPECT_EQ(true, EvalJs(shell(), redirect_script));
  EXPECT_EQ(expected_title16, title_watcher.WaitAndGetTitle());
}

IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, CrossSiteNavigationErrorPage2) {
  ASSERT_TRUE(embedded_test_server()->Start());

  GURL url(embedded_test_server()->GetURL("/title2.html"));
  CheckTitleTest(url, "Title Of Awesomeness");

  // Navigate to a new cross-site URL that results in an error.
  // TODO(creis): If this causes crashes or hangs, it might be for the same
  // reason as ErrorPageTest::DNSError.  See bug 1199491 and
  // http://crbug.com/22877.
  GURL failed_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  std::unique_ptr<URLLoaderInterceptor> url_interceptor =
      URLLoaderInterceptor::SetupRequestFailForURL(failed_url,
                                                   net::ERR_NAME_NOT_RESOLVED);

  EXPECT_FALSE(NavigateToURL(shell(), failed_url));
  EXPECT_NE(u"Title Of Awesomeness", shell()->web_contents()->GetTitle());

  // Repeat navigation.  We are testing that this completes.
  EXPECT_FALSE(NavigateToURL(shell(), failed_url));
  EXPECT_NE(u"Title Of Awesomeness", shell()->web_contents()->GetTitle());
}

IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, CrossOriginRedirectBlocked) {
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url(
      embedded_test_server()->GetURL("/cross-origin-redirect-blocked.html"));
  // We expect the following URL requests from this test:
  // 1- navigation to http://127.0.0.1:[port]/cross-origin-redirect-blocked.html
  // 2- XHR to
  // http://127.0.0.1:[port]/server-redirect-302?http://a.com:[port]/title2.html
  // 3- above XHR is redirected to http://a.com:[port]/title2.html which should
  // be blocked
  // 4- When the page notices the above request is blocked, it issues an XHR to
  // http://127.0.0.1:[port]/title2.html
  // 5- When the above XHR succeed, the page navigates to
  // http://127.0.0.1:[port]/title3.html
  //
  // If the redirect in #3 were not blocked, we'd instead see a navigation
  // to http://a.com[port]/title2.html, and the title would be different.
  CheckTitleTest(url, "Title Of More Awesomeness");
}

// Tests that ResourceRequestInfoImpl is updated correctly on failed
// requests, to prevent calling Read on a request that has already failed.
// See bug 40250.
IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, CrossSiteFailedRequest) {
  // Visit another URL first to trigger a cross-site navigation.
  EXPECT_TRUE(NavigateToURL(shell(), GetTestUrl("", "simple_page.html")));

  // Visit a URL that fails without calling ResourceDispatcherHost::Read.
  GURL broken_url("chrome://theme");
  EXPECT_FALSE(NavigateToURL(shell(), broken_url));
}

namespace {

std::unique_ptr<net::test_server::HttpResponse> HandleRedirectRequest(
    const std::string& request_path,
    const net::test_server::HttpRequest& request) {
  if (!base::StartsWith(request.relative_url, request_path,
                        base::CompareCase::SENSITIVE)) {
    return nullptr;
  }

  std::unique_ptr<net::test_server::BasicHttpResponse> http_response(
      new net::test_server::BasicHttpResponse);
  http_response->set_code(net::HTTP_FOUND);
  http_response->AddCustomHeader(
      "Location", request.relative_url.substr(request_path.length()));
  return std::move(http_response);
}

}  // namespace

// Test that we update the cookie policy URLs correctly when transferring
// navigations.
IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, CookiePolicy) {
  embedded_test_server()->RegisterRequestHandler(
      base::BindRepeating(&HandleRedirectRequest, "/redirect?"));
  ASSERT_TRUE(embedded_test_server()->Start());

  std::string set_cookie_url(base::StringPrintf(
      "http://localhost:%u/set_cookie.html", embedded_test_server()->port()));
  GURL url(embedded_test_server()->GetURL("/redirect?" + set_cookie_url));

  std::u16string expected_title16(u"cookie set");
  TitleWatcher title_watcher(shell()->web_contents(), expected_title16);
  EXPECT_TRUE(NavigateToURL(shell(), url,
                            GURL(set_cookie_url) /* expected_commit_url */));
  EXPECT_EQ(expected_title16, title_watcher.WaitAndGetTitle());
}

// Test that ui::PAGE_TRANSITION_CLIENT_REDIRECT is correctly set
// when encountering a meta refresh tag.
IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, PageTransitionClientRedirect) {
  ASSERT_TRUE(embedded_test_server()->Start());

  NavigateToURLBlockUntilNavigationsComplete(
      shell(), embedded_test_server()->GetURL("/client_redirect.html"), 2);

  NavigationEntry* entry =
      shell()->web_contents()->GetController().GetLastCommittedEntry();

  EXPECT_TRUE(entry->GetTransitionType() & ui::PAGE_TRANSITION_CLIENT_REDIRECT);
}

IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, SubresourceRedirectToDataURLBlocked) {
  ASSERT_TRUE(embedded_test_server()->Start());

  EXPECT_TRUE(NavigateToURL(shell(), embedded_test_server()->GetURL("/echo")));

  GURL subresource_url = embedded_test_server()->GetURL(
      "/server-redirect?data:text/plain,redirected1");
  std::string script = R"((url => {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', url, true);
    return new Promise(resolve => {
      xhr.onload = () => resolve("ALLOWED");
      xhr.onerror = () => resolve("BLOCKED");
      xhr.send();
    });
  }))";

  EXPECT_EQ("BLOCKED",
            EvalJs(shell(), script + "('" + subresource_url.spec() + "')"));
}

IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, RedirectToDataURLBlocked) {
  ASSERT_TRUE(embedded_test_server()->Start());
  EXPECT_FALSE(NavigateToURL(
      shell(), embedded_test_server()->GetURL(
                   "/server-redirect?data:text/plain,redirected1")));
}

IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, RedirectToAboutURLBlocked) {
  ASSERT_TRUE(embedded_test_server()->Start());
  EXPECT_FALSE(NavigateToURL(
      shell(), embedded_test_server()->GetURL(
                   "/server-redirect?" + std::string(url::kAboutBlankURL))));
}

namespace {

// Creates a valid filesystem URL.
GURL CreateFileSystemURL(Shell* window) {
  std::string filesystem_url_string = EvalJs(window, R"(
      var blob = new Blob(['<html><body>hello</body></html>'],
                          {type: 'text/html'});
      new Promise(resolve => {
        window.webkitRequestFileSystem(TEMPORARY, blob.size, fs => {
          fs.root.getFile('foo.html', {create: true}, file => {
            file.createWriter(writer => {
              writer.write(blob);
              writer.onwriteend = () => {
                resolve(file.toURL());
              }
            });
          });
        });
      });)")
                                          .ExtractString();
  GURL filesystem_url(filesystem_url_string);
  EXPECT_TRUE(filesystem_url.is_valid());
  EXPECT_TRUE(filesystem_url.SchemeIsFileSystem());
  return filesystem_url;
}

}  // namespace

IN_PROC_BROWSER_TEST_F(LoaderBrowserTest,
                       SubresourceRedirectToFileSystemURLBlocked) {
  ASSERT_TRUE(embedded_test_server()->Start());

  EXPECT_TRUE(NavigateToURL(shell(), embedded_test_server()->GetURL("/echo")));

  GURL subresource_url = embedded_test_server()->GetURL(
      "/server-redirect?" + CreateFileSystemURL(shell()).spec());
  std::string script = R"((url => {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', url, true);
    return new Promise(resolve => {
      xhr.onload = () => resolve("ALLOWED");
      xhr.onerror = () => resolve("BLOCKED");
      xhr.send();
    });
  }))";

  EXPECT_EQ("BLOCKED",
            EvalJs(shell(), script + "('" + subresource_url.spec() + "')"));
}

IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, RedirectToFileSystemURLBlocked) {
  ASSERT_TRUE(embedded_test_server()->Start());
  // Need to navigate to a URL first so the filesystem can be created.
  EXPECT_TRUE(NavigateToURL(shell(), embedded_test_server()->GetURL("/echo")));

  EXPECT_FALSE(NavigateToURL(
      shell(), embedded_test_server()->GetURL(
                   "/server-redirect?" + CreateFileSystemURL(shell()).spec())));
}

namespace {

struct RequestData {
  const GURL url;
  const net::SiteForCookies site_for_cookies;
  const absl::optional<url::Origin> initiator;
  const int load_flags;
  const std::string referrer;

  RequestData(const GURL& url,
              const net::SiteForCookies& site_for_cookies,
              const absl::optional<url::Origin>& initiator,
              int load_flags,
              const std::string& referrer)
      : url(url),
        site_for_cookies(site_for_cookies),
        initiator(initiator),
        load_flags(load_flags),
        referrer(referrer) {}
};

}  // namespace

class RequestDataBrowserTest : public ContentBrowserTest {
 public:
  RequestDataBrowserTest()
      : interceptor_(std::make_unique<content::URLLoaderInterceptor>(
            base::BindRepeating(&RequestDataBrowserTest::OnRequest,
                                base::Unretained(this)))) {}
  ~RequestDataBrowserTest() override {}

  std::vector<RequestData> data() {
    base::AutoLock auto_lock(requests_lock_);
    auto copy = requests_;
    return copy;
  }

  void WaitForRequests(size_t count) {
    while (true) {
      base::RunLoop run_loop;
      {
        base::AutoLock auto_lock(requests_lock_);
        if (requests_.size() == count)
          return;
        requests_closure_ = run_loop.QuitClosure();
      }
      run_loop.Run();
    }
  }

 private:
  void SetUpOnMainThread() override {
    ContentBrowserTest::SetUpOnMainThread();

    ASSERT_TRUE(embedded_test_server()->Start());

    host_resolver()->AddRule("*", "127.0.0.1");
  }

  void TearDownOnMainThread() override { interceptor_.reset(); }

  bool OnRequest(URLLoaderInterceptor::RequestParams* params) {
    RequestCreated(RequestData(
        params->url_request.url, params->url_request.site_for_cookies,
        params->url_request.request_initiator, params->url_request.load_flags,
        params->url_request.referrer.spec()));
    return false;
  }

  void RequestCreated(RequestData data) {
    base::AutoLock auto_lock(requests_lock_);
    requests_.push_back(data);
    if (requests_closure_)
      std::move(requests_closure_).Run();
  }

  base::Lock requests_lock_;
  std::vector<RequestData> requests_;
  base::OnceClosure requests_closure_;
  std::unique_ptr<URLLoaderInterceptor> interceptor_;
};

IN_PROC_BROWSER_TEST_F(RequestDataBrowserTest, Basic) {
  GURL top_url(embedded_test_server()->GetURL("/page_with_subresources.html"));
  url::Origin top_origin = url::Origin::Create(top_url);

  NavigateToURLBlockUntilNavigationsComplete(shell(), top_url, 1);

  auto requests = data();
  EXPECT_EQ(8u, requests.size());

  // All resources loaded directly by the top-level document should have a
  // |first_party| and |initiator| that match the URL of the top-level document.
  // The top-level document itself doesn't have an |initiator|.
  const RequestData* first_request = &requests[0];
  EXPECT_TRUE(first_request->site_for_cookies.IsEquivalent(
      net::SiteForCookies::FromUrl(top_url)));
  EXPECT_FALSE(first_request->initiator.has_value());
  for (size_t i = 1; i < requests.size(); i++) {
    const RequestData* request = &requests[i];
    EXPECT_TRUE(request->site_for_cookies.IsEquivalent(
        net::SiteForCookies::FromOrigin(top_origin)));
    ASSERT_TRUE(request->initiator.has_value());
    EXPECT_EQ(top_origin, request->initiator);
  }
}

IN_PROC_BROWSER_TEST_F(RequestDataBrowserTest, LinkRelPrefetch) {
  GURL top_url(embedded_test_server()->GetURL("/link_rel_prefetch.html"));
  url::Origin top_origin = url::Origin::Create(top_url);

  NavigateToURLBlockUntilNavigationsComplete(shell(), top_url, 1);
  WaitForRequests(2u);

  auto requests = data();
  EXPECT_EQ(2u, requests.size());
  auto* request = &requests[1];
  EXPECT_EQ(top_origin, request->initiator);
  EXPECT_EQ(top_url, request->referrer);
  EXPECT_TRUE(request->load_flags & net::LOAD_PREFETCH);
}

IN_PROC_BROWSER_TEST_F(RequestDataBrowserTest, LinkRelPrefetchReferrerPolicy) {
  GURL top_url(embedded_test_server()->GetURL(
      "/link_rel_prefetch_referrer_policy.html"));
  GURL img_url(embedded_test_server()->GetURL("/image.jpg"));
  url::Origin top_origin = url::Origin::Create(top_url);

  NavigateToURLBlockUntilNavigationsComplete(shell(), top_url, 1);
  WaitForRequests(2u);

  auto requests = data();
  EXPECT_EQ(2u, requests.size());
  auto* main_frame_request = &requests[0];
  auto* image_request = &requests[1];

  // Check the main frame request.
  EXPECT_EQ(top_url, main_frame_request->url);
  EXPECT_FALSE(main_frame_request->initiator.has_value());

  // Check the image request.
  EXPECT_EQ(img_url, image_request->url);
  EXPECT_TRUE(image_request->initiator.has_value());
  EXPECT_EQ(top_origin, image_request->initiator);
  // Respect the "origin" policy set by the <meta> tag.
  EXPECT_EQ(top_url.DeprecatedGetOriginAsURL().spec(), image_request->referrer);
  EXPECT_TRUE(image_request->load_flags & net::LOAD_PREFETCH);
}

// TODO(crbug.com/1271868): Flaky on all platforms.
IN_PROC_BROWSER_TEST_F(RequestDataBrowserTest, DISABLED_BasicCrossSite) {
  GURL top_url(embedded_test_server()->GetURL(
      "a.com", "/nested_page_with_subresources.html"));
  GURL nested_url(embedded_test_server()->GetURL(
      "not-a.com", "/page_with_subresources.html"));
  url::Origin top_origin = url::Origin::Create(top_url);
  url::Origin nested_origin = url::Origin::Create(nested_url);

  NavigateToURLBlockUntilNavigationsComplete(shell(), top_url, 1);

  auto requests = data();
  EXPECT_EQ(9u, requests.size());

  // The first items loaded are the top-level and nested documents. These should
  // both have a |site_for_cookies| that matches the origin of the top-level
  // document. The top-level document has no initiator and the nested frame is
  // initiated by the top-level document.
  EXPECT_EQ(top_url, requests[0].url);
  EXPECT_TRUE(requests[0].site_for_cookies.IsEquivalent(
      net::SiteForCookies::FromOrigin(top_origin)));
  EXPECT_FALSE(requests[0].initiator.has_value());

  EXPECT_EQ(nested_url, requests[1].url);
  EXPECT_TRUE(requests[1].site_for_cookies.IsEquivalent(
      net::SiteForCookies::FromOrigin(top_origin)));
  EXPECT_EQ(top_origin, requests[1].initiator);

  // The remaining items are loaded as subresources in the nested document, and
  // should have a unique first-party, and an initiator that matches the
  // document in which they're embedded.
  for (size_t i = 2; i < requests.size(); i++) {
    SCOPED_TRACE(requests[i].url);
    EXPECT_TRUE(requests[i].site_for_cookies.IsNull());
    EXPECT_EQ(nested_origin, requests[i].initiator);
  }
}

IN_PROC_BROWSER_TEST_F(RequestDataBrowserTest, SameOriginNested) {
  GURL top_url(embedded_test_server()->GetURL("/page_with_iframe.html"));
  GURL image_url(embedded_test_server()->GetURL("/image.jpg"));
  GURL nested_url(embedded_test_server()->GetURL("/title1.html"));
  url::Origin top_origin = url::Origin::Create(top_url);

  NavigateToURLBlockUntilNavigationsComplete(shell(), top_url, 1);

  auto requests = data();
  EXPECT_EQ(3u, requests.size());

  // User-initiated top-level navigations have a first-party that matches the
  // URL to which they navigate. The navigation was initiated outside of a
  // document, so there is no |initiator|.
  EXPECT_EQ(top_url, requests[0].url);
  EXPECT_TRUE(requests[0].site_for_cookies.IsEquivalent(
      net::SiteForCookies::FromOrigin(top_origin)));
  EXPECT_FALSE(requests[0].initiator.has_value());

  // Subresource requests have a first-party and initiator that matches the
  // document in which they're embedded.
  EXPECT_EQ(image_url, requests[1].url);
  EXPECT_TRUE(requests[1].site_for_cookies.IsEquivalent(
      net::SiteForCookies::FromOrigin(top_origin)));
  EXPECT_EQ(top_origin, requests[1].initiator);

  // Same-origin nested frames have a first-party and initiator that matches
  // the document in which they're embedded (since the frame is same site with
  // toplevel).
  EXPECT_EQ(nested_url, requests[2].url);
  EXPECT_TRUE(requests[2].site_for_cookies.IsEquivalent(
      net::SiteForCookies::FromOrigin(top_origin)));
  EXPECT_EQ(top_origin, requests[2].initiator);
}

IN_PROC_BROWSER_TEST_F(RequestDataBrowserTest, SameOriginAuxiliary) {
  GURL top_url(embedded_test_server()->GetURL("/simple_links.html"));
  GURL auxiliary_url(embedded_test_server()->GetURL("/title2.html"));
  url::Origin top_origin = url::Origin::Create(top_url);

  NavigateToURLBlockUntilNavigationsComplete(shell(), top_url, 1);

  ShellAddedObserver new_shell_observer;
  EXPECT_EQ(true, EvalJs(shell(), "clickSameSiteNewWindowLink();"));
  Shell* new_shell = new_shell_observer.GetShell();
  EXPECT_TRUE(WaitForLoadStop(new_shell->web_contents()));

  auto requests = data();
  EXPECT_EQ(2u, requests.size());

  // User-initiated top-level navigations have a first-party that matches the
  // URL to which they navigate, even if they fail to load. The navigation was
  // initiated outside of a document, so there is no |initiator|.
  EXPECT_EQ(top_url, requests[0].url);
  EXPECT_TRUE(requests[0].site_for_cookies.IsEquivalent(
      net::SiteForCookies::FromOrigin(top_origin)));
  EXPECT_FALSE(requests[0].initiator.has_value());

  // Auxiliary navigations have a first-party that matches the URL to which they
  // navigate, and an initiator that matches the document that triggered them.
  EXPECT_EQ(auxiliary_url, requests[1].url);
  EXPECT_TRUE(requests[1].site_for_cookies.IsEquivalent(
      net::SiteForCookies::FromUrl(auxiliary_url)));
  EXPECT_EQ(top_origin, requests[1].initiator);
}

IN_PROC_BROWSER_TEST_F(RequestDataBrowserTest, CrossOriginAuxiliary) {
  GURL top_url(embedded_test_server()->GetURL("/simple_links.html"));
  GURL auxiliary_url(embedded_test_server()->GetURL("foo.com", "/title2.html"));
  url::Origin top_origin = url::Origin::Create(top_url);

  NavigateToURLBlockUntilNavigationsComplete(shell(), top_url, 1);

  const char kReplacePortNumber[] = "setPortNumber(%d);";
  uint16_t port_number = embedded_test_server()->port();
  EXPECT_TRUE(
      ExecJs(shell(), base::StringPrintf(kReplacePortNumber, port_number)));

  ShellAddedObserver new_shell_observer;
  EXPECT_EQ(true, EvalJs(shell(), "clickCrossSiteNewWindowLink();"));
  Shell* new_shell = new_shell_observer.GetShell();
  EXPECT_TRUE(WaitForLoadStop(new_shell->web_contents()));

  auto requests = data();
  EXPECT_EQ(2u, requests.size());

  // User-initiated top-level navigations have a first-party that matches the
  // URL to which they navigate, even if they fail to load. The navigation was
  // initiated outside of a document, so there is no initiator.
  EXPECT_EQ(top_url, requests[0].url);
  EXPECT_TRUE(requests[0].site_for_cookies.IsEquivalent(
      net::SiteForCookies::FromOrigin(top_origin)));
  EXPECT_FALSE(requests[0].initiator.has_value());

  // Auxiliary navigations have a first-party that matches the URL to which they
  // navigate, and an initiator that matches the document that triggered them.
  EXPECT_EQ(auxiliary_url, requests[1].url);
  EXPECT_TRUE(requests[1].site_for_cookies.IsEquivalent(
      net::SiteForCookies::FromUrl(auxiliary_url)));
  EXPECT_EQ(top_origin, requests[1].initiator);
}

IN_PROC_BROWSER_TEST_F(RequestDataBrowserTest, FailedNavigation) {
  // Navigating to this URL will fail, as we haven't taught the host resolver
  // about 'a.com'.
  GURL top_url(embedded_test_server()->GetURL("a.com", "/simple_page.html"));
  url::Origin top_origin = url::Origin::Create(top_url);

  NavigateToURLBlockUntilNavigationsComplete(shell(), top_url, 1);

  auto requests = data();
  EXPECT_EQ(1u, requests.size());

  // User-initiated top-level navigations have a first-party that matches the
  // URL to which they navigate, even if they fail to load. The navigation was
  // initiated outside of a document, so there is no initiator.
  EXPECT_EQ(top_url, requests[0].url);
  EXPECT_TRUE(requests[0].site_for_cookies.IsEquivalent(
      net::SiteForCookies::FromOrigin(top_origin)));
  EXPECT_FALSE(requests[0].initiator.has_value());
}

IN_PROC_BROWSER_TEST_F(RequestDataBrowserTest, CrossOriginNested) {
  GURL top_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  GURL top_js_url(
      embedded_test_server()->GetURL("a.com", "/tree_parser_util.js"));
  GURL nested_url(embedded_test_server()->GetURL(
      "b.com", "/cross_site_iframe_factory.html?b()"));
  GURL nested_js_url(
      embedded_test_server()->GetURL("b.com", "/tree_parser_util.js"));
  url::Origin top_origin = url::Origin::Create(top_url);
  url::Origin nested_origin = url::Origin::Create(nested_url);

  NavigateToURLBlockUntilNavigationsComplete(shell(), top_url, 1);

  auto requests = data();
  EXPECT_EQ(4u, requests.size());

  // User-initiated top-level navigations have a |first-party|. The navigation
  // was initiated outside of a document, so there are no initiator.
  EXPECT_EQ(top_url, requests[0].url);
  EXPECT_TRUE(requests[0].site_for_cookies.IsEquivalent(
      net::SiteForCookies::FromOrigin(top_origin)));
  EXPECT_FALSE(requests[0].initiator.has_value());

  EXPECT_EQ(top_js_url, requests[1].url);
  EXPECT_TRUE(requests[1].site_for_cookies.IsEquivalent(
      net::SiteForCookies::FromOrigin(top_origin)));
  EXPECT_EQ(top_origin, requests[1].initiator);

  // Cross-origin frames have a first-party and initiator that matches the URL
  // in which they're embedded (if they are the first cross-origin thing)
  EXPECT_EQ(nested_url, requests[2].url);
  EXPECT_TRUE(requests[2].site_for_cookies.IsEquivalent(
      net::SiteForCookies::FromOrigin(top_origin)));
  EXPECT_EQ(top_origin, requests[2].initiator);

  // Cross-origin subresource requests have a unique first-party, and an
  // initiator that matches the document in which they're embedded.
  EXPECT_EQ(nested_js_url, requests[3].url);
  EXPECT_TRUE(requests[3].site_for_cookies.IsNull());
  EXPECT_EQ(nested_origin, requests[3].initiator);
}

// Regression test for https://crbug.com/648608. An attacker could trivially
// bypass cookies SameSite=Strict protections by navigating a new window twice.
IN_PROC_BROWSER_TEST_F(LoaderBrowserTest,
                       CookieSameSiteStrictOpenNewNamedWindowTwice) {
  ASSERT_TRUE(embedded_test_server()->Start());

  // 1) Add cookies for 'a.com', one of them with the "SameSite=Strict" option.
  BrowserContext* context = shell()->web_contents()->GetBrowserContext();
  GURL a_url("http://a.com");
  EXPECT_TRUE(SetCookie(context, a_url, "cookie_A=A; SameSite=Strict;"));
  EXPECT_TRUE(SetCookie(context, a_url, "cookie_B=B"));

  // 2) Navigate to malicious.com.
  EXPECT_TRUE(NavigateToURL(shell(), embedded_test_server()->GetURL(
                                         "malicious.com", "/title1.html")));

  // 2.1) malicious.com opens a new window to 'http://a.com/echoall'.
  GURL echoall_url = embedded_test_server()->GetURL("a.com", "/echoall");
  std::string script = base::StringPrintf("window.open('%s', 'named_frame');",
                                          echoall_url.spec().c_str());
  {
    TestNavigationObserver new_tab_observer(shell()->web_contents(), 1);
    new_tab_observer.StartWatchingNewWebContents();
    EXPECT_TRUE(ExecJs(shell(), script));
    new_tab_observer.Wait();
    ASSERT_EQ(2u, Shell::windows().size());
    Shell* new_shell = Shell::windows()[1];
    EXPECT_TRUE(WaitForLoadStop(new_shell->web_contents()));

    // Only the cookie without "SameSite=Strict" should be sent.
    std::string html_content =
        EvalJs(new_shell, "document.body.textContent").ExtractString();
    EXPECT_THAT(html_content.c_str(), Not(HasSubstr("cookie_A=A")));
    EXPECT_THAT(html_content.c_str(), HasSubstr("cookie_B=B"));
  }

  // 2.2) Same as in 2.1). The difference is that the new tab will be reused.
  {
    Shell* new_shell = Shell::windows()[1];
    TestNavigationObserver new_tab_observer(new_shell->web_contents(), 1);
    EXPECT_TRUE(ExecJs(shell(), script));
    new_tab_observer.Wait();
    ASSERT_EQ(2u, Shell::windows().size());
    EXPECT_TRUE(WaitForLoadStop(new_shell->web_contents()));

    // Only the cookie without "SameSite=Strict" should be sent.
    std::string html_content =
        EvalJs(new_shell, "document.body.textContent").ExtractString();
    EXPECT_THAT(html_content.c_str(), Not(HasSubstr("cookie_A=A")));
    EXPECT_THAT(html_content.c_str(), HasSubstr("cookie_B=B"));
  }
}

class URLModifyingThrottle : public blink::URLLoaderThrottle {
 public:
  URLModifyingThrottle(bool modify_start, bool modify_redirect)
      : modify_start_(modify_start), modify_redirect_(modify_redirect) {}

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

  ~URLModifyingThrottle() override = default;

  void WillStartRequest(network::ResourceRequest* request,
                        bool* defer) override {
    if (!modify_start_)
      return;

    GURL::Replacements replacements;
    replacements.SetQueryStr("foo=bar");
    request->url = request->url.ReplaceComponents(replacements);
    request->headers.SetHeader("Foo", "BarRequest");
    request->cors_exempt_headers.SetHeader("ExemptFoo", "ExemptBarRequest");
  }

  void WillRedirectRequest(
      net::RedirectInfo* redirect_info,
      const network::mojom::URLResponseHead& response_head,
      bool* defer,
      std::vector<std::string>* to_be_removed_request_headers,
      net::HttpRequestHeaders* modified_request_headers,
      net::HttpRequestHeaders* modified_cors_exempt_request_headers) override {
    if (!modify_redirect_)
      return;

    modified_request_headers->SetHeader("Foo", "BarRedirect");
    modified_cors_exempt_request_headers->SetHeader("ExemptFoo",
                                                    "ExemptBarRedirect");

    if (modified_redirect_url_)
      return;  // Only need to do this once.

    modified_redirect_url_ = true;
    GURL::Replacements replacements;
    replacements.SetQueryStr("foo=bar");
    redirect_info->new_url =
        redirect_info->new_url.ReplaceComponents(replacements);
  }

 private:
  bool modify_start_;
  bool modify_redirect_;
  bool modified_redirect_url_ = false;
};

class ThrottleContentBrowserClient
    : public ContentBrowserTestContentBrowserClient {
 public:
  ThrottleContentBrowserClient(bool modify_start, bool modify_redirect)
      : modify_start_(modify_start), modify_redirect_(modify_redirect) {}

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

  ~ThrottleContentBrowserClient() override {}

  // ContentBrowserClient overrides:
  std::vector<std::unique_ptr<blink::URLLoaderThrottle>>
  CreateURLLoaderThrottles(
      const network::ResourceRequest& request,
      BrowserContext* browser_context,
      const base::RepeatingCallback<WebContents*()>& wc_getter,
      NavigationUIData* navigation_ui_data,
      int frame_tree_node_id) override {
    std::vector<std::unique_ptr<blink::URLLoaderThrottle>> throttles;
    auto throttle =
        std::make_unique<URLModifyingThrottle>(modify_start_, modify_redirect_);
    throttles.push_back(std::move(throttle));
    return throttles;
  }

 private:
  bool modify_start_;
  bool modify_redirect_;
};

// Ensures if a URLLoaderThrottle modifies a URL in WillStartRequest the
// new request matches
IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, URLLoaderThrottleStartModify) {
  base::Lock lock;
  ThrottleContentBrowserClient content_browser_client(true, false);

  std::set<GURL> urls_requested;
  std::map<GURL, net::test_server::HttpRequest::HeaderMap> header_map;
  embedded_test_server()->RegisterRequestMonitor(base::BindLambdaForTesting(
      [&](const net::test_server::HttpRequest& request) {
        base::AutoLock auto_lock(lock);
        urls_requested.insert(request.GetURL());
        header_map[request.GetURL()] = request.headers;
      }));

  ASSERT_TRUE(embedded_test_server()->Start());

  GURL url = embedded_test_server()->GetURL("/simple_page.html");
  GURL expected_url(url.spec() + "?foo=bar");
  EXPECT_TRUE(
      NavigateToURL(shell(), url, expected_url /* expected_commit_url */));

  {
    base::AutoLock auto_lock(lock);
    ASSERT_TRUE(urls_requested.find(expected_url) != urls_requested.end());
    ASSERT_TRUE(header_map[expected_url]["Foo"] == "BarRequest");
    ASSERT_TRUE(header_map[expected_url]["ExemptFoo"] == "ExemptBarRequest");
  }
}

// Ensures if a URLLoaderThrottle modifies a URL and headers in
// WillRedirectRequest the new request matches.
IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, URLLoaderThrottleRedirectModify) {
  base::Lock lock;
  ThrottleContentBrowserClient content_browser_client(false, true);

  std::set<GURL> urls_requested;
  std::map<GURL, net::test_server::HttpRequest::HeaderMap> header_map;
  embedded_test_server()->RegisterRequestMonitor(base::BindLambdaForTesting(
      [&](const net::test_server::HttpRequest& request) {
        base::AutoLock auto_lock(lock);
        urls_requested.insert(request.GetURL());
        header_map[request.GetURL()] = request.headers;
      }));

  ASSERT_TRUE(embedded_test_server()->Start());

  GURL url =
      embedded_test_server()->GetURL("/server-redirect?simple_page.html");
  GURL expected_url =
      embedded_test_server()->GetURL("/simple_page.html?foo=bar");
  EXPECT_TRUE(
      NavigateToURL(shell(), url, expected_url /* expected_commit_url */));

  {
    base::AutoLock auto_lock(lock);
    ASSERT_EQ(header_map[expected_url]["Foo"], "BarRedirect");
    ASSERT_EQ(header_map[expected_url]["ExemptFoo"], "ExemptBarRedirect");
    ASSERT_NE(urls_requested.find(expected_url), urls_requested.end());
  }
}

}  // namespace content
