Allow extensions to modify CORS preflight with Web Request API (1/2)

Supporting preflight is tricky because preflight requests are made in
the network service, and they don't have request IDs. We are adding
a new message, OnLoaderForCorsPreflightCreated, to
TrustedURLLoaderHeaderClient to address that.

We are using TrustedURLLoaderHeaderClient, which means this mechanism
works only when "extraHeaders" is specified. Unlike for usual requests,
WebRequestProxyingUrlLoaderFactory::InProgressRequest dispatches
 - onBeforeRequest when OnLoaderForCorsPreflightCreated is called,
 - onBeforeSendHeaders and onSendHeaders when OnBeforeSendHeaders
   is called, and
 - onHeadersReceived, onResponseStarted, and onCompleted when
   OnHeadersReceived is called.

This CL is a preliminary change. It adds
 - TrustedURLLoaderHeaderClient.OnLoaderForCorsPreflightCreated
   as described above,
 - "remote_endpoint" param to TrustedHeaderClient.OnHeadersReceived
   to get endpoint information in OnHeadersReceived, and
 - kURLLoaderOptionAsCorsPreflight to mark a request as a CORS
   preflight.

This CL doesn't change any behavior because we have not set
kURLLoadOptionAsCorsPreflight and kURLLoadOptionUseHeaderClient in
network::cors::PreflightController yet.

The subsequent change is: https://crrev.com/c/1837561

Bug: 1002884
Change-Id: Ib396e35ce636f6ed016df089d393dedec94db430
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1833395
Commit-Queue: Yutaka Hirano <[email protected]>
Reviewed-by: David Benjamin <[email protected]>
Reviewed-by: Karan Bhatia <[email protected]>
Reviewed-by: Kinuko Yasuda <[email protected]>
Reviewed-by: Takashi Toyoshima <[email protected]>
Cr-Commit-Position: refs/heads/master@{#706372}
diff --git a/net/base/network_delegate.cc b/net/base/network_delegate.cc
index 6dc817f..cecc0fb 100644
--- a/net/base/network_delegate.cc
+++ b/net/base/network_delegate.cc
@@ -60,6 +60,7 @@
     CompletionOnceCallback callback,
     const HttpResponseHeaders* original_response_headers,
     scoped_refptr<HttpResponseHeaders>* override_response_headers,
+    const IPEndPoint& endpoint,
     GURL* allowed_unsafe_redirect_url) {
   TRACE_EVENT0(NetTracingCategory(), "NetworkDelegate::NotifyHeadersReceived");
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
@@ -67,7 +68,7 @@
   DCHECK(!callback.is_null());
   return OnHeadersReceived(request, std::move(callback),
                            original_response_headers, override_response_headers,
-                           allowed_unsafe_redirect_url);
+                           endpoint, allowed_unsafe_redirect_url);
 }
 
 void NetworkDelegate::NotifyResponseStarted(URLRequest* request,
diff --git a/net/base/network_delegate.h b/net/base/network_delegate.h
index 301c56f..fc35ecc 100644
--- a/net/base/network_delegate.h
+++ b/net/base/network_delegate.h
@@ -40,6 +40,7 @@
 class CookieOptions;
 class HttpRequestHeaders;
 class HttpResponseHeaders;
+class IPEndPoint;
 class ProxyInfo;
 class URLRequest;
 
@@ -66,6 +67,7 @@
       CompletionOnceCallback callback,
       const HttpResponseHeaders* original_response_headers,
       scoped_refptr<HttpResponseHeaders>* override_response_headers,
+      const IPEndPoint& remote_endpoint,
       GURL* allowed_unsafe_redirect_url);
   void NotifyBeforeRedirect(URLRequest* request,
                             const GURL& new_location);
@@ -184,6 +186,7 @@
       CompletionOnceCallback callback,
       const HttpResponseHeaders* original_response_headers,
       scoped_refptr<HttpResponseHeaders>* override_response_headers,
+      const IPEndPoint& remote_endpoint,
       GURL* allowed_unsafe_redirect_url) = 0;
 
   // Called right after a redirect response code was received. |new_location| is
diff --git a/net/base/network_delegate_impl.cc b/net/base/network_delegate_impl.cc
index 1a65fad..398fb5f 100644
--- a/net/base/network_delegate_impl.cc
+++ b/net/base/network_delegate_impl.cc
@@ -32,6 +32,7 @@
     CompletionOnceCallback callback,
     const HttpResponseHeaders* original_response_headers,
     scoped_refptr<HttpResponseHeaders>* override_response_headers,
+    const IPEndPoint& endpoint,
     GURL* allowed_unsafe_redirect_url) {
   return OK;
 }
diff --git a/net/base/network_delegate_impl.h b/net/base/network_delegate_impl.h
index ed5192ab..857fb29e 100644
--- a/net/base/network_delegate_impl.h
+++ b/net/base/network_delegate_impl.h
@@ -53,6 +53,7 @@
       CompletionOnceCallback callback,
       const HttpResponseHeaders* original_response_headers,
       scoped_refptr<HttpResponseHeaders>* override_response_headers,
+      const IPEndPoint& endpoint,
       GURL* allowed_unsafe_redirect_url) override;
 
   void OnBeforeRedirect(URLRequest* request, const GURL& new_location) override;
diff --git a/net/proxy_resolution/network_delegate_error_observer_unittest.cc b/net/proxy_resolution/network_delegate_error_observer_unittest.cc
index 86c3720..50fb964 100644
--- a/net/proxy_resolution/network_delegate_error_observer_unittest.cc
+++ b/net/proxy_resolution/network_delegate_error_observer_unittest.cc
@@ -44,6 +44,7 @@
       CompletionOnceCallback callback,
       const HttpResponseHeaders* original_response_headers,
       scoped_refptr<HttpResponseHeaders>* override_response_headers,
+      const net::IPEndPoint& endpoint,
       GURL* allowed_unsafe_redirect_url) override {
     return OK;
   }
diff --git a/net/proxy_resolution/pac_file_fetcher_impl_unittest.cc b/net/proxy_resolution/pac_file_fetcher_impl_unittest.cc
index e3a074b..6882f78 100644
--- a/net/proxy_resolution/pac_file_fetcher_impl_unittest.cc
+++ b/net/proxy_resolution/pac_file_fetcher_impl_unittest.cc
@@ -155,6 +155,7 @@
       CompletionOnceCallback callback,
       const HttpResponseHeaders* original_response_headers,
       scoped_refptr<HttpResponseHeaders>* override_response_headers,
+      const net::IPEndPoint& endpoint,
       GURL* allowed_unsafe_redirect_url) override {
     return OK;
   }
diff --git a/net/url_request/url_request_context_builder.cc b/net/url_request/url_request_context_builder.cc
index 640a708..7825bf23 100644
--- a/net/url_request/url_request_context_builder.cc
+++ b/net/url_request/url_request_context_builder.cc
@@ -88,6 +88,7 @@
       CompletionOnceCallback callback,
       const HttpResponseHeaders* original_response_headers,
       scoped_refptr<HttpResponseHeaders>* override_response_headers,
+      const IPEndPoint& endpoint,
       GURL* allowed_unsafe_redirect_url) override {
     return OK;
   }
diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc
index eccaeff..1f133bb 100644
--- a/net/url_request/url_request_http_job.cc
+++ b/net/url_request/url_request_http_job.cc
@@ -910,6 +910,9 @@
       // |NetworkDelegate::URLRequestDestroyed()| has been called.
       OnCallToDelegate(NetLogEventType::NETWORK_DELEGATE_HEADERS_RECEIVED);
       allowed_unsafe_redirect_url_ = GURL();
+      IPEndPoint endpoint;
+      if (transaction_)
+        transaction_->GetRemoteEndpoint(&endpoint);
       // The NetworkDelegate must watch for OnRequestDestroyed and not modify
       // any of the arguments after it's called.
       // TODO(mattm): change the API to remove the out-params and take the
@@ -918,7 +921,7 @@
           request_,
           base::BindOnce(&URLRequestHttpJob::OnHeadersReceivedCallback,
                          weak_factory_.GetWeakPtr()),
-          headers.get(), &override_response_headers_,
+          headers.get(), &override_response_headers_, endpoint,
           &allowed_unsafe_redirect_url_);
       if (error != OK) {
         if (error == ERR_IO_PENDING) {
diff --git a/net/url_request/url_request_test_util.cc b/net/url_request/url_request_test_util.cc
index 09cda16c..5170349 100644
--- a/net/url_request/url_request_test_util.cc
+++ b/net/url_request/url_request_test_util.cc
@@ -459,6 +459,7 @@
     CompletionOnceCallback callback,
     const HttpResponseHeaders* original_response_headers,
     scoped_refptr<HttpResponseHeaders>* override_response_headers,
+    const IPEndPoint& endpoint,
     GURL* allowed_unsafe_redirect_url) {
   int req_id = GetRequestId(request);
   bool is_first_response =
diff --git a/net/url_request/url_request_test_util.h b/net/url_request/url_request_test_util.h
index 6dedc56..aaaf60bd 100644
--- a/net/url_request/url_request_test_util.h
+++ b/net/url_request/url_request_test_util.h
@@ -339,6 +339,7 @@
       CompletionOnceCallback callback,
       const HttpResponseHeaders* original_response_headers,
       scoped_refptr<HttpResponseHeaders>* override_response_headers,
+      const IPEndPoint& endpoint,
       GURL* allowed_unsafe_redirect_url) override;
   void OnBeforeRedirect(URLRequest* request, const GURL& new_location) override;
   void OnResponseStarted(URLRequest* request, int net_error) override;
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc
index 29e365d..20add8e 100644
--- a/net/url_request/url_request_unittest.cc
+++ b/net/url_request/url_request_unittest.cc
@@ -439,6 +439,7 @@
       CompletionOnceCallback callback,
       const HttpResponseHeaders* original_response_headers,
       scoped_refptr<HttpResponseHeaders>* override_response_headers,
+      const IPEndPoint& endpoint,
       GURL* allowed_unsafe_redirect_url) override;
 
   // Resets the callbacks and |stage_blocked_for_callback_|.
@@ -544,12 +545,14 @@
     CompletionOnceCallback callback,
     const HttpResponseHeaders* original_response_headers,
     scoped_refptr<HttpResponseHeaders>* override_response_headers,
+    const IPEndPoint& endpoint,
     GURL* allowed_unsafe_redirect_url) {
   // TestNetworkDelegate always completes synchronously.
-  CHECK_NE(ERR_IO_PENDING,
-           TestNetworkDelegate::OnHeadersReceived(
-               request, base::NullCallback(), original_response_headers,
-               override_response_headers, allowed_unsafe_redirect_url));
+  CHECK_NE(
+      ERR_IO_PENDING,
+      TestNetworkDelegate::OnHeadersReceived(
+          request, base::NullCallback(), original_response_headers,
+          override_response_headers, endpoint, allowed_unsafe_redirect_url));
 
   return MaybeBlockStage(ON_HEADERS_RECEIVED, std::move(callback));
 }
@@ -2917,6 +2920,7 @@
       CompletionOnceCallback callback,
       const HttpResponseHeaders* original_response_headers,
       scoped_refptr<HttpResponseHeaders>* override_response_headers,
+      const IPEndPoint& endpoint,
       GURL* allowed_unsafe_redirect_url) override;
 
  private:
@@ -2930,6 +2934,7 @@
     CompletionOnceCallback callback,
     const HttpResponseHeaders* original_response_headers,
     scoped_refptr<HttpResponseHeaders>* override_response_headers,
+    const IPEndPoint& endpoint,
     GURL* allowed_unsafe_redirect_url) {
   HttpResponseHeaders* new_response_headers =
       new HttpResponseHeaders(original_response_headers->raw_headers());
@@ -2940,7 +2945,7 @@
   *override_response_headers = new_response_headers;
   return TestNetworkDelegate::OnHeadersReceived(
       request, std::move(callback), original_response_headers,
-      override_response_headers, allowed_unsafe_redirect_url);
+      override_response_headers, endpoint, allowed_unsafe_redirect_url);
 }
 
 // Test that cookie expiration times are adjusted for server/client clock
@@ -4337,12 +4342,14 @@
       CompletionOnceCallback callback,
       const HttpResponseHeaders* original_response_headers,
       scoped_refptr<HttpResponseHeaders>* override_response_headers,
+      const IPEndPoint& endpoint,
       GURL* allowed_unsafe_redirect_url) override {
     // TestNetworkDelegate always completes synchronously.
-    CHECK_NE(ERR_IO_PENDING,
-             TestNetworkDelegate::OnHeadersReceived(
-                 request, base::NullCallback(), original_response_headers,
-                 override_response_headers, allowed_unsafe_redirect_url));
+    CHECK_NE(
+        ERR_IO_PENDING,
+        TestNetworkDelegate::OnHeadersReceived(
+            request, base::NullCallback(), original_response_headers,
+            override_response_headers, endpoint, allowed_unsafe_redirect_url));
     return RunCallbackAsynchronously(request, std::move(callback));
   }