Fenced frames: Cancel in-progress requests upon network revocation [4/N]

For fenced frames network revocation, previously we only cancelled in-
progress requests with URLLoader. Now we also cancel for CorsURLLoader.

Bug: 1515599
Change-Id: Idc8e7554d919c9544e6837d2ae1c0e6fcd7ae73f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5448555
Reviewed-by: Tsuyoshi Horo <horo@chromium.org>
Commit-Queue: Garrett Tanzer <gtanzer@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1291889}
diff --git a/services/network/cors/cors_url_loader.cc b/services/network/cors/cors_url_loader.cc
index 3c33ac15..b56aa89 100644
--- a/services/network/cors/cors_url_loader.cc
+++ b/services/network/cors/cors_url_loader.cc
@@ -830,6 +830,17 @@
   }
 }
 
+void CorsURLLoader::CancelRequestIfNonceMatchesAndUrlNotExempted(
+    const base::UnguessableToken& nonce,
+    const std::set<GURL>& exemptions) {
+  if (isolation_info_.nonce() == nonce) {
+    if (!exemptions.contains(request_.url.GetWithoutFilename())) {
+      HandleComplete(
+          URLLoaderCompletionStatus(net::ERR_NETWORK_ACCESS_REVOKED));
+    }
+  }
+}
+
 void CorsURLLoader::StartRequest() {
   TRACE_EVENT("loading", "CorsURLLoader::StartRequest",
               perfetto::Flow::ProcessScoped(net_log_.source().id));
diff --git a/services/network/cors/cors_url_loader.h b/services/network/cors/cors_url_loader.h
index e57505da..3bdb85eb 100644
--- a/services/network/cors/cors_url_loader.h
+++ b/services/network/cors/cors_url_loader.h
@@ -120,6 +120,11 @@
   void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
   void OnComplete(const URLLoaderCompletionStatus& status) override;
 
+  // Cancel the request because network revocation was triggered.
+  void CancelRequestIfNonceMatchesAndUrlNotExempted(
+      const base::UnguessableToken& nonce,
+      const std::set<GURL>& exemptions);
+
   static network::mojom::FetchResponseType CalculateResponseTaintingForTesting(
       const GURL& url,
       mojom::RequestMode request_mode,
diff --git a/services/network/cors/cors_url_loader_factory.cc b/services/network/cors/cors_url_loader_factory.cc
index a29453f..861aefe 100644
--- a/services/network/cors/cors_url_loader_factory.cc
+++ b/services/network/cors/cors_url_loader_factory.cc
@@ -839,4 +839,25 @@
   return network_loader_factory_->GetBoundNetworkForTesting();  // IN-TEST
 }
 
+void CorsURLLoaderFactory::CancelRequestsIfNonceMatchesAndUrlNotExempted(
+    const base::UnguessableToken& nonce,
+    const std::set<GURL>& exemptions) {
+  // Cancelling the request may cause the URL loader to be deleted from the data
+  // structure, invalidating the iterator if it is currently pointing to that
+  // element. So advance to the next element first and delete the previous one.
+  for (auto loader_it = url_loaders_.begin(); loader_it != url_loaders_.end();
+       /* iteration performed inside the loop */) {
+    ++loader_it;
+    (*std::prev(loader_it))
+        ->CancelRequestIfNonceMatchesAndUrlNotExempted(nonce, exemptions);
+  }
+  for (auto loader_it = cors_url_loaders_.begin();
+       loader_it != cors_url_loaders_.end();
+       /* iteration performed inside the loop */) {
+    ++loader_it;
+    (*std::prev(loader_it))
+        ->CancelRequestIfNonceMatchesAndUrlNotExempted(nonce, exemptions);
+  }
+}
+
 }  // namespace network::cors
diff --git a/services/network/cors/cors_url_loader_factory.h b/services/network/cors/cors_url_loader_factory.h
index 6635f21..09807d8b 100644
--- a/services/network/cors/cors_url_loader_factory.h
+++ b/services/network/cors/cors_url_loader_factory.h
@@ -107,6 +107,13 @@
   // guarantee that the overriding factory behaves correctly).
   net::handles::NetworkHandle GetBoundNetworkForTesting() const;
 
+  // Cancels all requests matching `nonce` associated with this factory, unless
+  // exempted by a url in `exemptions`. Used to cancel in-progress requests
+  // when network revocation is triggered.
+  void CancelRequestsIfNonceMatchesAndUrlNotExempted(
+      const base::UnguessableToken& nonce,
+      const std::set<GURL>& exemptions);
+
  private:
   class FactoryOverride;
 
diff --git a/services/network/network_context.cc b/services/network/network_context.cc
index 431f8c5..aa94a653 100644
--- a/services/network/network_context.cc
+++ b/services/network/network_context.cc
@@ -3087,9 +3087,7 @@
     network_revocation_nonces_.insert(nonce);
     const std::set<GURL>& exemptions = network_revocation_exemptions_[nonce];
     for (const auto& factory : url_loader_factories_) {
-      for (const auto& loader : factory->url_loaders()) {
-        loader->CancelRequestIfNonceMatchesAndUrlNotExempted(nonce, exemptions);
-      }
+      factory->CancelRequestsIfNonceMatchesAndUrlNotExempted(nonce, exemptions);
     }
 #if BUILDFLAG(ENABLE_WEBSOCKETS)
     if (websocket_factory_) {