Convert IsSafeRedirectTarget and a couple throttles to work on UI thread

This converts a couple of the easy throttles that just needed to get
data from Profile instead of ProfileIOData, as well as converting
IsSafeRedirectTarget which now uses ExtensionRegistry instead of
extensions::InfoMap from ProfileIOData.

TBR=bsazonov@chromium.org

Bug: 824844, 976990
Change-Id: Iffb2ba970beeb4aacc0057b2f8ea6c6e0dd4b810
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1671588
Commit-Queue: Clark DuVall <cduvall@chromium.org>
Reviewed-by: Bo <boliu@chromium.org>
Reviewed-by: Kinuko Yasuda <kinuko@chromium.org>
Cr-Commit-Position: refs/heads/master@{#672239}
diff --git a/android_webview/browser/aw_content_browser_client.cc b/android_webview/browser/aw_content_browser_client.cc
index 5869691..0b4382c1 100644
--- a/android_webview/browser/aw_content_browser_client.cc
+++ b/android_webview/browser/aw_content_browser_client.cc
@@ -859,7 +859,7 @@
 }
 
 std::vector<std::unique_ptr<content::URLLoaderThrottle>>
-AwContentBrowserClient::CreateURLLoaderThrottles(
+AwContentBrowserClient::CreateURLLoaderThrottlesOnIO(
     const network::ResourceRequest& request,
     content::ResourceContext* resource_context,
     const base::RepeatingCallback<content::WebContents*()>& wc_getter,
diff --git a/android_webview/browser/aw_content_browser_client.h b/android_webview/browser/aw_content_browser_client.h
index 600cb9d5..f7cd6a6 100644
--- a/android_webview/browser/aw_content_browser_client.h
+++ b/android_webview/browser/aw_content_browser_client.h
@@ -183,7 +183,7 @@
       service_manager::BinderRegistry* registry,
       content::RenderFrameHost* render_frame_host) override;
   std::vector<std::unique_ptr<content::URLLoaderThrottle>>
-  CreateURLLoaderThrottles(
+  CreateURLLoaderThrottlesOnIO(
       const network::ResourceRequest& request,
       content::ResourceContext* resource_context,
       const base::RepeatingCallback<content::WebContents*()>& wc_getter,
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 0149bfa..fe25e96 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -258,6 +258,7 @@
 #include "components/services/quarantine/quarantine_service.h"
 #include "components/services/unzip/public/interfaces/constants.mojom.h"
 #include "components/signin/core/browser/account_consistency_method.h"
+#include "components/signin/core/browser/signin_pref_names.h"
 #include "components/spellcheck/spellcheck_buildflags.h"
 #include "components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.h"
 #include "components/translate/core/common/translate_switches.h"
@@ -4662,13 +4663,14 @@
 }  // namespace
 
 std::vector<std::unique_ptr<content::URLLoaderThrottle>>
-ChromeContentBrowserClient::CreateURLLoaderThrottles(
+ChromeContentBrowserClient::CreateURLLoaderThrottlesOnIO(
     const network::ResourceRequest& request,
     content::ResourceContext* resource_context,
     const base::RepeatingCallback<content::WebContents*()>& wc_getter,
     content::NavigationUIData* navigation_ui_data,
     int frame_tree_node_id) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  DCHECK(!base::FeatureList::IsEnabled(features::kNavigationLoaderOnUI));
 
   std::vector<std::unique_ptr<content::URLLoaderThrottle>> result;
 
@@ -4772,6 +4774,49 @@
   return result;
 }
 
+std::vector<std::unique_ptr<content::URLLoaderThrottle>>
+ChromeContentBrowserClient::CreateURLLoaderThrottles(
+    const network::ResourceRequest& request,
+    content::BrowserContext* browser_context,
+    const base::RepeatingCallback<content::WebContents*()>& wc_getter,
+    content::NavigationUIData* navigation_ui_data,
+    int frame_tree_node_id) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+  std::vector<std::unique_ptr<content::URLLoaderThrottle>> result;
+
+  Profile* profile = Profile::FromBrowserContext(browser_context);
+
+  ChromeNavigationUIData* chrome_navigation_ui_data =
+      static_cast<ChromeNavigationUIData*>(navigation_ui_data);
+
+  if (chrome_navigation_ui_data &&
+      chrome_navigation_ui_data->prerender_mode() != prerender::NO_PRERENDER) {
+    result.push_back(std::make_unique<prerender::PrerenderURLLoaderThrottle>(
+        chrome_navigation_ui_data->prerender_mode(),
+        chrome_navigation_ui_data->prerender_histogram_prefix(),
+        base::BindOnce(GetPrerenderCanceller, wc_getter),
+        base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI})));
+  }
+
+  bool is_off_the_record = profile->IsOffTheRecord();
+  bool is_signed_in = !is_off_the_record &&
+                      !profile->GetPrefs()
+                           ->GetString(prefs::kGoogleServicesUserAccountId)
+                           .empty();
+
+  chrome::mojom::DynamicParams dynamic_params = {
+      profile->GetPrefs()->GetBoolean(prefs::kForceGoogleSafeSearch),
+      profile->GetPrefs()->GetInteger(prefs::kForceYouTubeRestrict),
+      profile->GetPrefs()->GetString(prefs::kAllowedDomainsForApps),
+      variations::VariationsHttpHeaderProvider::GetInstance()
+          ->GetClientDataHeader(is_signed_in)};
+  result.push_back(std::make_unique<GoogleURLLoaderThrottle>(
+      is_off_the_record, std::move(dynamic_params)));
+
+  return result;
+}
+
 void ChromeContentBrowserClient::RegisterNonNetworkNavigationURLLoaderFactories(
     int frame_tree_node_id,
     NonNetworkURLLoaderFactoryMap* factories) {
@@ -5225,9 +5270,10 @@
 #endif
 }
 
-bool ChromeContentBrowserClient::IsSafeRedirectTarget(
+bool ChromeContentBrowserClient::IsSafeRedirectTargetOnIO(
     const GURL& url,
     content::ResourceContext* context) {
+  DCHECK(!base::FeatureList::IsEnabled(features::kNavigationLoaderOnUI));
 #if BUILDFLAG(ENABLE_EXTENSIONS)
   if (url.SchemeIs(extensions::kExtensionScheme)) {
     ProfileIOData* io_data = ProfileIOData::FromResourceContext(context);
@@ -5242,6 +5288,23 @@
   return true;
 }
 
+bool ChromeContentBrowserClient::IsSafeRedirectTarget(
+    const GURL& url,
+    content::BrowserContext* context) {
+#if BUILDFLAG(ENABLE_EXTENSIONS)
+  if (url.SchemeIs(extensions::kExtensionScheme)) {
+    const Extension* extension = extensions::ExtensionRegistry::Get(context)
+                                     ->enabled_extensions()
+                                     .GetByID(url.host());
+    if (!extension)
+      return false;
+    return extensions::WebAccessibleResourcesInfo::IsResourceWebAccessible(
+        extension, url.path());
+  }
+#endif  // BUILDFLAG(ENABLE_EXTENSIONS)
+  return true;
+}
+
 void ChromeContentBrowserClient::RegisterRendererPreferenceWatcher(
     content::BrowserContext* browser_context,
     blink::mojom::RendererPreferenceWatcherPtr watcher) {
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h
index 02795a8e..52f60d5 100644
--- a/chrome/browser/chrome_content_browser_client.h
+++ b/chrome/browser/chrome_content_browser_client.h
@@ -464,12 +464,19 @@
   base::FilePath GetLoggingFileName(
       const base::CommandLine& command_line) override;
   std::vector<std::unique_ptr<content::URLLoaderThrottle>>
-  CreateURLLoaderThrottles(
+  CreateURLLoaderThrottlesOnIO(
       const network::ResourceRequest& request,
       content::ResourceContext* resource_context,
       const base::RepeatingCallback<content::WebContents*()>& wc_getter,
       content::NavigationUIData* navigation_ui_data,
       int frame_tree_node_id) override;
+  std::vector<std::unique_ptr<content::URLLoaderThrottle>>
+  CreateURLLoaderThrottles(
+      const network::ResourceRequest& request,
+      content::BrowserContext* browser_context,
+      const base::RepeatingCallback<content::WebContents*()>& wc_getter,
+      content::NavigationUIData* navigation_ui_data,
+      int frame_tree_node_id) override;
   void RegisterNonNetworkNavigationURLLoaderFactories(
       int frame_tree_node_id,
       NonNetworkURLLoaderFactoryMap* factories) override;
@@ -551,8 +558,10 @@
       network::mojom::URLLoaderFactory*& out_factory) override;
   std::unique_ptr<content::OverlayWindow> CreateWindowForPictureInPicture(
       content::PictureInPictureWindowController* controller) override;
+  bool IsSafeRedirectTargetOnIO(const GURL& url,
+                                content::ResourceContext* context) override;
   bool IsSafeRedirectTarget(const GURL& url,
-                            content::ResourceContext* context) override;
+                            content::BrowserContext* context) override;
   void RegisterRendererPreferenceWatcher(
       content::BrowserContext* browser_context,
       blink::mojom::RendererPreferenceWatcherPtr watcher) override;
diff --git a/chrome/browser/signin/mirror_browsertest.cc b/chrome/browser/signin/mirror_browsertest.cc
index 50d8f0c..1ca7b7b 100644
--- a/chrome/browser/signin/mirror_browsertest.cc
+++ b/chrome/browser/signin/mirror_browsertest.cc
@@ -66,7 +66,7 @@
 
   // ContentBrowserClient overrides:
   std::vector<std::unique_ptr<content::URLLoaderThrottle>>
-  CreateURLLoaderThrottles(
+  CreateURLLoaderThrottlesOnIO(
       const network::ResourceRequest& request,
       content::ResourceContext* resource_context,
       const base::RepeatingCallback<content::WebContents*()>& wc_getter,
@@ -77,6 +77,16 @@
       throttles.push_back(std::make_unique<HeaderModifyingThrottle>());
     return throttles;
   }
+  std::vector<std::unique_ptr<content::URLLoaderThrottle>>
+  CreateURLLoaderThrottles(
+      const network::ResourceRequest& request,
+      content::BrowserContext* browser_context,
+      const base::RepeatingCallback<content::WebContents*()>& wc_getter,
+      content::NavigationUIData* navigation_ui_data,
+      int frame_tree_node_id) override {
+    return CreateURLLoaderThrottlesOnIO(request, nullptr, wc_getter,
+                                        navigation_ui_data, frame_tree_node_id);
+  }
 
  private:
   const GURL watch_url_;
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc
index 45398a1..bcc66e4 100644
--- a/content/browser/frame_host/navigation_request.cc
+++ b/content/browser/frame_host/navigation_request.cc
@@ -1757,7 +1757,7 @@
   begin_params_->headers = headers.ToString();
 
   loader_ = NavigationURLLoader::Create(
-      browser_context->GetResourceContext(), partition,
+      browser_context, browser_context->GetResourceContext(), partition,
       std::make_unique<NavigationRequestInfo>(
           common_params_, begin_params_.Clone(), site_for_cookies,
           top_frame_origin, frame_tree_node_->IsMainFrame(),
diff --git a/content/browser/loader/loader_browsertest.cc b/content/browser/loader/loader_browsertest.cc
index f40618fe..13819a5 100644
--- a/content/browser/loader/loader_browsertest.cc
+++ b/content/browser/loader/loader_browsertest.cc
@@ -1200,7 +1200,7 @@
   ~ThrottleContentBrowserClient() override {}
 
   // ContentBrowserClient overrides:
-  std::vector<std::unique_ptr<URLLoaderThrottle>> CreateURLLoaderThrottles(
+  std::vector<std::unique_ptr<URLLoaderThrottle>> CreateURLLoaderThrottlesOnIO(
       const network::ResourceRequest& request,
       ResourceContext* resource_context,
       const base::RepeatingCallback<WebContents*()>& wc_getter,
@@ -1212,6 +1212,15 @@
     throttles.push_back(std::move(throttle));
     return throttles;
   }
+  std::vector<std::unique_ptr<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 {
+    return CreateURLLoaderThrottlesOnIO(request, nullptr, wc_getter,
+                                        navigation_ui_data, frame_tree_node_id);
+  }
 
  private:
   bool modify_start_;
diff --git a/content/browser/loader/navigation_url_loader.cc b/content/browser/loader/navigation_url_loader.cc
index 921a101..3f3714f4b 100644
--- a/content/browser/loader/navigation_url_loader.cc
+++ b/content/browser/loader/navigation_url_loader.cc
@@ -20,6 +20,7 @@
 static NavigationURLLoaderFactory* g_loader_factory = nullptr;
 
 std::unique_ptr<NavigationURLLoader> NavigationURLLoader::Create(
+    BrowserContext* browser_context,
     ResourceContext* resource_context,
     StoragePartition* storage_partition,
     std::unique_ptr<NavigationRequestInfo> request_info,
@@ -35,8 +36,9 @@
         std::move(navigation_ui_data), service_worker_handle, delegate);
   }
   return std::make_unique<NavigationURLLoaderImpl>(
-      resource_context, storage_partition, std::move(request_info),
-      std::move(navigation_ui_data), service_worker_handle, appcache_handle,
+      browser_context, resource_context, storage_partition,
+      std::move(request_info), std::move(navigation_ui_data),
+      service_worker_handle, appcache_handle,
       std::move(prefetched_signed_exchange_cache), delegate,
       std::vector<std::unique_ptr<NavigationLoaderInterceptor>>());
 }
diff --git a/content/browser/loader/navigation_url_loader.h b/content/browser/loader/navigation_url_loader.h
index 2cc2e00d..160f5de 100644
--- a/content/browser/loader/navigation_url_loader.h
+++ b/content/browser/loader/navigation_url_loader.h
@@ -21,6 +21,7 @@
 namespace content {
 
 class AppCacheNavigationHandle;
+class BrowserContext;
 class NavigationUIData;
 class NavigationURLLoaderDelegate;
 class NavigationURLLoaderFactory;
@@ -45,6 +46,7 @@
   // structure. Information like has_user_gesture and
   // should_replace_current_entry shouldn't be needed at this layer.
   static std::unique_ptr<NavigationURLLoader> Create(
+      BrowserContext* browser_context,
       ResourceContext* resource_context,
       StoragePartition* storage_partition,
       std::unique_ptr<NavigationRequestInfo> request_info,
diff --git a/content/browser/loader/navigation_url_loader_impl.cc b/content/browser/loader/navigation_url_loader_impl.cc
index ca4b3db..d4b734f 100644
--- a/content/browser/loader/navigation_url_loader_impl.cc
+++ b/content/browser/loader/navigation_url_loader_impl.cc
@@ -300,15 +300,16 @@
 // Determines whether it is safe to redirect from |from_url| to |to_url|.
 bool IsRedirectSafe(const GURL& from_url,
                     const GURL& to_url,
+                    BrowserContext* browser_context,
                     ResourceContext* resource_context) {
-  // TODO(http://crbug.com/824840): Make
-  // ContentBrowserClient::IsSafeRedirectTarget work on UI thread.
   if (NavigationURLLoaderImpl::IsNavigationLoaderOnUIEnabled()) {
-    return IsSafeRedirectTarget(from_url, to_url);
+    return IsSafeRedirectTarget(from_url, to_url) &&
+           GetContentClient()->browser()->IsSafeRedirectTarget(to_url,
+                                                               browser_context);
   }
   return IsSafeRedirectTarget(from_url, to_url) &&
-         GetContentClient()->browser()->IsSafeRedirectTarget(to_url,
-                                                             resource_context);
+         GetContentClient()->browser()->IsSafeRedirectTargetOnIO(
+             to_url, resource_context);
 }
 
 // Runs |task| on the thread specified by |thread_id| if already on that thread,
@@ -340,6 +341,7 @@
       std::vector<std::unique_ptr<NavigationLoaderInterceptor>>
           initial_interceptors,
       std::unique_ptr<network::ResourceRequest> resource_request,
+      BrowserContext* browser_context,
       ResourceContext* resource_context,
       const GURL& url,
       bool is_main_frame,
@@ -358,6 +360,7 @@
         proxied_factory_info_(std::move(proxied_factory_info)),
         known_schemes_(std::move(known_schemes)),
         bypass_redirect_checks_(bypass_redirect_checks),
+        browser_context_(browser_context),
         weak_factory_(this) {}
 
   ~URLLoaderRequestController() override {
@@ -1234,7 +1237,8 @@
                          const network::ResourceResponseHead& head) override {
     if (base::FeatureList::IsEnabled(network::features::kNetworkService) &&
         !bypass_redirect_checks_ &&
-        !IsRedirectSafe(url_, redirect_info.new_url, resource_context_)) {
+        !IsRedirectSafe(url_, redirect_info.new_url, browser_context_,
+                        resource_context_)) {
       // Call CancelWithError instead of OnComplete so that if there is an
       // intercepting URLLoaderFactory (created through the embedder's
       // ContentBrowserClient::WillCreateURLLoaderFactory) it gets notified.
@@ -1367,10 +1371,12 @@
   }
 
   std::vector<std::unique_ptr<URLLoaderThrottle>> CreateURLLoaderThrottles() {
-    // TODO(http://crbug.com/824840): Create throttles on UI thread.
-    if (IsNavigationLoaderOnUIEnabled())
-      return {};
-    return GetContentClient()->browser()->CreateURLLoaderThrottles(
+    if (IsNavigationLoaderOnUIEnabled()) {
+      return GetContentClient()->browser()->CreateURLLoaderThrottles(
+          *resource_request_, browser_context_, web_contents_getter_,
+          navigation_ui_data_.get(), frame_tree_node_id_);
+    }
+    return GetContentClient()->browser()->CreateURLLoaderThrottlesOnIO(
         *resource_request_, resource_context_, web_contents_getter_,
         navigation_ui_data_.get(), frame_tree_node_id_);
   }
@@ -1498,6 +1504,9 @@
   // Counts the time overhead of all the hops from the UI to the IO threads.
   base::TimeDelta ui_to_io_time_;
 
+  // Only used when NavigationLoaderOnUI is enabled:
+  BrowserContext* browser_context_;
+
   mutable base::WeakPtrFactory<URLLoaderRequestController> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(URLLoaderRequestController);
@@ -1506,6 +1515,7 @@
 // TODO(https://crbug.com/790734): pass |navigation_ui_data| along with the
 // request so that it could be modified.
 NavigationURLLoaderImpl::NavigationURLLoaderImpl(
+    BrowserContext* browser_context,
     ResourceContext* resource_context,
     StoragePartition* storage_partition,
     std::unique_ptr<NavigationRequestInfo> request_info,
@@ -1555,7 +1565,7 @@
     request_controller_ = std::make_unique<URLLoaderRequestController>(
         /* initial_interceptors = */
         std::vector<std::unique_ptr<NavigationLoaderInterceptor>>(),
-        std::move(new_request), resource_context,
+        std::move(new_request), browser_context, resource_context,
         request_info->common_params.url, request_info->is_main_frame,
         /* proxied_url_loader_factory_request */ nullptr,
         /* proxied_url_loader_factory_info */ nullptr, std::set<std::string>(),
@@ -1685,11 +1695,11 @@
 
   DCHECK(!request_controller_);
   request_controller_ = std::make_unique<URLLoaderRequestController>(
-      std::move(initial_interceptors), std::move(new_request), resource_context,
-      request_info->common_params.url, request_info->is_main_frame,
-      std::move(proxied_factory_request), std::move(proxied_factory_info),
-      std::move(known_schemes), bypass_redirect_checks,
-      weak_factory_.GetWeakPtr());
+      std::move(initial_interceptors), std::move(new_request), browser_context,
+      resource_context, request_info->common_params.url,
+      request_info->is_main_frame, std::move(proxied_factory_request),
+      std::move(proxied_factory_info), std::move(known_schemes),
+      bypass_redirect_checks, weak_factory_.GetWeakPtr());
   RunOrPostTaskIfNecessary(
       FROM_HERE, GetLoaderRequestControllerThreadID(),
       base::BindOnce(&URLLoaderRequestController::Start,
diff --git a/content/browser/loader/navigation_url_loader_impl.h b/content/browser/loader/navigation_url_loader_impl.h
index a6091e44..d434b1f 100644
--- a/content/browser/loader/navigation_url_loader_impl.h
+++ b/content/browser/loader/navigation_url_loader_impl.h
@@ -23,6 +23,7 @@
 
 namespace content {
 
+class BrowserContext;
 class NavigationLoaderInterceptor;
 class PrefetchedSignedExchangeCache;
 class ResourceContext;
@@ -35,6 +36,7 @@
   // The caller is responsible for ensuring that |delegate| outlives the loader.
   // Note |initial_interceptors| is there for test purposes only.
   NavigationURLLoaderImpl(
+      BrowserContext* browser_context,
       ResourceContext* resource_context,
       StoragePartition* storage_partition,
       std::unique_ptr<NavigationRequestInfo> request_info,
diff --git a/content/browser/loader/navigation_url_loader_impl_unittest.cc b/content/browser/loader/navigation_url_loader_impl_unittest.cc
index 67e23f2..aa31b443 100644
--- a/content/browser/loader/navigation_url_loader_impl_unittest.cc
+++ b/content/browser/loader/navigation_url_loader_impl_unittest.cc
@@ -196,7 +196,7 @@
         &most_recent_resource_request_));
 
     return std::make_unique<NavigationURLLoaderImpl>(
-        browser_context_->GetResourceContext(),
+        browser_context_.get(), browser_context_->GetResourceContext(),
         BrowserContext::GetDefaultStoragePartition(browser_context_.get()),
         std::move(request_info), nullptr /* navigation_ui_data */,
         nullptr /* service_worker_handle */, nullptr /* appcache_handle */,
diff --git a/content/browser/loader/navigation_url_loader_unittest.cc b/content/browser/loader/navigation_url_loader_unittest.cc
index 567eab4..2464072 100644
--- a/content/browser/loader/navigation_url_loader_unittest.cc
+++ b/content/browser/loader/navigation_url_loader_unittest.cc
@@ -106,7 +106,7 @@
                                   base::UnguessableToken::Create(),
                                   base::UnguessableToken::Create()));
     return NavigationURLLoader::Create(
-        browser_context_->GetResourceContext(),
+        browser_context_.get(), browser_context_->GetResourceContext(),
         BrowserContext::GetDefaultStoragePartition(browser_context_.get()),
         std::move(request_info), nullptr, nullptr, nullptr, nullptr, delegate);
   }
diff --git a/content/browser/loader/prefetch_url_loader_service.cc b/content/browser/loader/prefetch_url_loader_service.cc
index 6167581..6c41f5b 100644
--- a/content/browser/loader/prefetch_url_loader_service.cc
+++ b/content/browser/loader/prefetch_url_loader_service.cc
@@ -181,7 +181,7 @@
       !request_context_getter_->GetURLRequestContext())
     return std::vector<std::unique_ptr<content::URLLoaderThrottle>>();
   int frame_tree_node_id = frame_tree_node_id_getter.Run();
-  return GetContentClient()->browser()->CreateURLLoaderThrottles(
+  return GetContentClient()->browser()->CreateURLLoaderThrottlesOnIO(
       request, resource_context_,
       base::BindRepeating(&WebContents::FromFrameTreeNodeId,
                           frame_tree_node_id),
diff --git a/content/browser/loader/resource_dispatcher_host_unittest.cc b/content/browser/loader/resource_dispatcher_host_unittest.cc
index ad80ccc8..2f0ccb59 100644
--- a/content/browser/loader/resource_dispatcher_host_unittest.cc
+++ b/content/browser/loader/resource_dispatcher_host_unittest.cc
@@ -846,7 +846,7 @@
                                   base::UnguessableToken::Create()));
     std::unique_ptr<NavigationURLLoader> test_loader =
         NavigationURLLoader::Create(
-            browser_context_->GetResourceContext(),
+            browser_context_.get(), browser_context_->GetResourceContext(),
             BrowserContext::GetDefaultStoragePartition(browser_context_.get()),
             std::move(request_info), nullptr, nullptr, nullptr, nullptr,
             &delegate);
diff --git a/content/browser/service_worker/service_worker_browsertest.cc b/content/browser/service_worker/service_worker_browsertest.cc
index adad382..02cd39d9 100644
--- a/content/browser/service_worker/service_worker_browsertest.cc
+++ b/content/browser/service_worker/service_worker_browsertest.cc
@@ -3702,7 +3702,7 @@
   ~ThrottlingContentBrowserClient() override {}
 
   // ContentBrowserClient overrides:
-  std::vector<std::unique_ptr<URLLoaderThrottle>> CreateURLLoaderThrottles(
+  std::vector<std::unique_ptr<URLLoaderThrottle>> CreateURLLoaderThrottlesOnIO(
       const network::ResourceRequest& request,
       ResourceContext* resource_context,
       const base::RepeatingCallback<WebContents*()>& wc_getter,
diff --git a/content/browser/worker_host/worker_script_fetch_initiator.cc b/content/browser/worker_host/worker_script_fetch_initiator.cc
index b834b67..01dadb8 100644
--- a/content/browser/worker_host/worker_script_fetch_initiator.cc
+++ b/content/browser/worker_host/worker_script_fetch_initiator.cc
@@ -367,7 +367,7 @@
     base::RepeatingCallback<WebContents*()> wc_getter =
         base::BindRepeating([]() -> WebContents* { return nullptr; });
     std::vector<std::unique_ptr<URLLoaderThrottle>> throttles =
-        GetContentClient()->browser()->CreateURLLoaderThrottles(
+        GetContentClient()->browser()->CreateURLLoaderThrottlesOnIO(
             *resource_request, resource_context, wc_getter,
             nullptr /* navigation_ui_data */, -1 /* frame_tree_node_id */);
 
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc
index 440244e..2ff5541 100644
--- a/content/public/browser/content_browser_client.cc
+++ b/content/public/browser/content_browser_client.cc
@@ -719,7 +719,7 @@
 }
 
 std::vector<std::unique_ptr<URLLoaderThrottle>>
-ContentBrowserClient::CreateURLLoaderThrottles(
+ContentBrowserClient::CreateURLLoaderThrottlesOnIO(
     const network::ResourceRequest& request,
     ResourceContext* resource_context,
     const base::RepeatingCallback<WebContents*()>& wc_getter,
@@ -728,6 +728,16 @@
   return std::vector<std::unique_ptr<URLLoaderThrottle>>();
 }
 
+std::vector<std::unique_ptr<URLLoaderThrottle>>
+ContentBrowserClient::CreateURLLoaderThrottles(
+    const network::ResourceRequest& request,
+    BrowserContext* browser_context,
+    const base::RepeatingCallback<WebContents*()>& wc_getter,
+    NavigationUIData* navigation_ui_data,
+    int frame_tree_node_id) {
+  return std::vector<std::unique_ptr<URLLoaderThrottle>>();
+}
+
 void ContentBrowserClient::RegisterNonNetworkNavigationURLLoaderFactories(
     int frame_tree_node_id,
     NonNetworkURLLoaderFactoryMap* factories) {}
@@ -901,8 +911,13 @@
   return nullptr;
 }
 
+bool ContentBrowserClient::IsSafeRedirectTargetOnIO(const GURL& url,
+                                                    ResourceContext* context) {
+  return true;
+}
+
 bool ContentBrowserClient::IsSafeRedirectTarget(const GURL& url,
-                                                ResourceContext* context) {
+                                                BrowserContext* context) {
   return true;
 }
 
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
index 46eed09..56f0da1 100644
--- a/content/public/browser/content_browser_client.h
+++ b/content/public/browser/content_browser_client.h
@@ -1174,12 +1174,20 @@
   // This is called both when the network service is enabled and disabled.
   // This is called on the IO thread.
   virtual std::vector<std::unique_ptr<URLLoaderThrottle>>
-  CreateURLLoaderThrottles(
+  CreateURLLoaderThrottlesOnIO(
       const network::ResourceRequest& request,
       ResourceContext* resource_context,
       const base::RepeatingCallback<WebContents*()>& wc_getter,
       NavigationUIData* navigation_ui_data,
       int frame_tree_node_id);
+  // Same as above but called on UI thread.
+  virtual std::vector<std::unique_ptr<URLLoaderThrottle>>
+  CreateURLLoaderThrottles(
+      const network::ResourceRequest& request,
+      BrowserContext* browser_context,
+      const base::RepeatingCallback<WebContents*()>& wc_getter,
+      NavigationUIData* navigation_ui_data,
+      int frame_tree_node_id);
 
   // Allows the embedder to register per-scheme URLLoaderFactory implementations
   // to handle navigation URL requests for schemes not handled by the Network
@@ -1483,7 +1491,10 @@
 
   // Returns true if it is safe to redirect to |url|, otherwise returns false.
   // This is called on the IO thread.
-  virtual bool IsSafeRedirectTarget(const GURL& url, ResourceContext* context);
+  virtual bool IsSafeRedirectTargetOnIO(const GURL& url,
+                                        ResourceContext* context);
+  // Same as above but called on UI thread.
+  virtual bool IsSafeRedirectTarget(const GURL& url, BrowserContext* context);
 
   // Registers the watcher to observe updates in RendererPreferences.
   virtual void RegisterRendererPreferenceWatcher(