Bug 1496577 - have OPTIONS preflights inherit the original request's referrer and referrer policy; r?ckerschb draft
authorThomas Wisniewski <twisniewski@mozilla.com>
Sun, 07 Oct 2018 13:38:20 -0400
changeset 1718502 4e77783600214d0df0025d69e3ffa9b3054b4c0e
parent 1718439 90853a59691e0c77014c38049bfb38b2b6ca1e16
child 1718503 cea6b4c7fd4321583a2f269e2c962329365eaaf0
push id304834
push userwisniewskit@gmail.com
push dateSun, 07 Oct 2018 17:39:38 +0000
treeherdertry@cea6b4c7fd43 [default view] [failures only]
reviewersckerschb
bugs1496577
milestone64.0a1
Bug 1496577 - have OPTIONS preflights inherit the original request's referrer and referrer policy; r?ckerschb
netwerk/protocol/http/nsCORSListenerProxy.cpp
testing/web-platform/meta/fetch/api/cors/cors-preflight-referrer.any.js.ini
testing/web-platform/tests/common/get-host-info.sub.js
--- a/netwerk/protocol/http/nsCORSListenerProxy.cpp
+++ b/netwerk/protocol/http/nsCORSListenerProxy.cpp
@@ -1564,16 +1564,27 @@ nsCORSListenerProxy::StartCORSPreflight(
   // Set up listener which will start the original channel
   RefPtr<nsCORSPreflightListener> preflightListener =
     new nsCORSPreflightListener(principal, aCallback, loadContext,
                                 withCredentials, method, preflightHeaders);
 
   rv = preflightChannel->SetNotificationCallbacks(preflightListener);
   NS_ENSURE_SUCCESS(rv, rv);
 
+  // Per https://fetch.spec.whatwg.org/#cors-preflight-fetch step 1, the
+  // request's referrer and referrer policy should match the original request.
+  uint32_t referrerPolicy = nsIHttpChannel::REFERRER_POLICY_UNSET;
+  rv = reqCh->GetReferrerPolicy(&referrerPolicy);
+  NS_ENSURE_SUCCESS(rv, rv);
+  nsCOMPtr<nsIURI> requestReferrerURI;
+  rv = reqCh->GetReferrer(getter_AddRefs(requestReferrerURI));
+  NS_ENSURE_SUCCESS(rv, rv);
+  rv = preCh->SetReferrerWithPolicy(requestReferrerURI, referrerPolicy);
+  NS_ENSURE_SUCCESS(rv, rv);
+
   // Start preflight
   rv = preflightChannel->AsyncOpen2(preflightListener);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Return newly created preflight channel
   preflightChannel.forget(aPreflightChannel);
 
   return NS_OK;
deleted file mode 100644
--- a/testing/web-platform/meta/fetch/api/cors/cors-preflight-referrer.any.js.ini
+++ /dev/null
@@ -1,51 +0,0 @@
-[cors-preflight-referrer.any.worker.html]
-  [Referrer policy: "" and referrer: default]
-    expected: FAIL
-
-  [Referrer policy: "" and referrer: 'myreferrer']
-    expected: FAIL
-
-  [Referrer policy: origin and referrer: default]
-    expected: FAIL
-
-  [Referrer policy: origin and referrer: 'myreferrer']
-    expected: FAIL
-
-  [Referrer policy: origin-when-cross-origin and referrer: default]
-    expected: FAIL
-
-  [Referrer policy: origin-when-cross-origin and referrer: 'myreferrer']
-    expected: FAIL
-
-  [Referrer policy: unsafe-url and referrer: default]
-    expected: FAIL
-
-  [Referrer policy: unsafe-url and referrer: 'myreferrer']
-    expected: FAIL
-
-
-[cors-preflight-referrer.any.html]
-  [Referrer policy: "" and referrer: default]
-    expected: FAIL
-
-  [Referrer policy: "" and referrer: 'myreferrer']
-    expected: FAIL
-
-  [Referrer policy: origin and referrer: default]
-    expected: FAIL
-
-  [Referrer policy: origin and referrer: 'myreferrer']
-    expected: FAIL
-
-  [Referrer policy: origin-when-cross-origin and referrer: default]
-    expected: FAIL
-
-  [Referrer policy: origin-when-cross-origin and referrer: 'myreferrer']
-    expected: FAIL
-
-  [Referrer policy: unsafe-url and referrer: default]
-    expected: FAIL
-
-  [Referrer policy: unsafe-url and referrer: 'myreferrer']
-    expected: FAIL
-
--- a/testing/web-platform/tests/common/get-host-info.sub.js
+++ b/testing/web-platform/tests/common/get-host-info.sub.js
@@ -1,36 +1,39 @@
 function get_host_info() {
 
   var HTTP_PORT = '{{ports[http][0]}}';
   var HTTP_PORT2 = '{{ports[http][1]}}';
   var HTTPS_PORT = '{{ports[https][0]}}';
+  var HTTP_PORT_ELIDED = HTTP_PORT == "80" ? "" : (":" + HTTP_PORT);
+  var HTTP_PORT2_ELIDED = HTTP_PORT2 == "80" ? "" : (":" + HTTP_PORT2);
+  var HTTPS_PORT_ELIDED = HTTPS_PORT == "80" ? "" : (":" + HTTPS_PORT);
   var ORIGINAL_HOST = '{{host}}';
   var REMOTE_HOST = (ORIGINAL_HOST === 'localhost') ? '127.0.0.1' : ('www1.' + ORIGINAL_HOST);
   var OTHER_HOST = '{{domains[www2]}}';
   var NOTSAMESITE_HOST = (ORIGINAL_HOST === 'localhost') ? '127.0.0.1' : ('not-' + ORIGINAL_HOST);
 
   return {
     HTTP_PORT: HTTP_PORT,
     HTTP_PORT2: HTTP_PORT2,
     HTTPS_PORT: HTTPS_PORT,
     ORIGINAL_HOST: ORIGINAL_HOST,
     REMOTE_HOST: REMOTE_HOST,
 
-    HTTP_ORIGIN: 'http://' + ORIGINAL_HOST + ':' + HTTP_PORT,
-    HTTPS_ORIGIN: 'https://' + ORIGINAL_HOST + ':' + HTTPS_PORT,
-    HTTPS_ORIGIN_WITH_CREDS: 'https://foo:bar@' + ORIGINAL_HOST + ':' + HTTPS_PORT,
-    HTTP_ORIGIN_WITH_DIFFERENT_PORT: 'http://' + ORIGINAL_HOST + ':' + HTTP_PORT2,
-    HTTP_REMOTE_ORIGIN: 'http://' + REMOTE_HOST + ':' + HTTP_PORT,
-    HTTP_NOTSAMESITE_ORIGIN: 'http://' + NOTSAMESITE_HOST + ':' + HTTP_PORT,
-    HTTP_REMOTE_ORIGIN_WITH_DIFFERENT_PORT: 'http://' + REMOTE_HOST + ':' + HTTP_PORT2,
-    HTTPS_REMOTE_ORIGIN: 'https://' + REMOTE_HOST + ':' + HTTPS_PORT,
-    HTTPS_REMOTE_ORIGIN_WITH_CREDS: 'https://foo:bar@' + REMOTE_HOST + ':' + HTTPS_PORT,
-    UNAUTHENTICATED_ORIGIN: 'http://' + OTHER_HOST + ':' + HTTP_PORT,
-    AUTHENTICATED_ORIGIN: 'https://' + OTHER_HOST + ':' + HTTPS_PORT
+    HTTP_ORIGIN: 'http://' + ORIGINAL_HOST + HTTP_PORT_ELIDED,
+    HTTPS_ORIGIN: 'https://' + ORIGINAL_HOST + HTTPS_PORT_ELIDED,
+    HTTPS_ORIGIN_WITH_CREDS: 'https://foo:bar@' + ORIGINAL_HOST + HTTPS_PORT_ELIDED,
+    HTTP_ORIGIN_WITH_DIFFERENT_PORT: 'http://' + ORIGINAL_HOST + HTTP_PORT2_ELIDED,
+    HTTP_REMOTE_ORIGIN: 'http://' + REMOTE_HOST + HTTP_PORT_ELIDED,
+    HTTP_NOTSAMESITE_ORIGIN: 'http://' + NOTSAMESITE_HOST + HTTP_PORT_ELIDED,
+    HTTP_REMOTE_ORIGIN_WITH_DIFFERENT_PORT: 'http://' + REMOTE_HOST + HTTP_PORT2_ELIDED,
+    HTTPS_REMOTE_ORIGIN: 'https://' + REMOTE_HOST + HTTPS_PORT_ELIDED,
+    HTTPS_REMOTE_ORIGIN_WITH_CREDS: 'https://foo:bar@' + REMOTE_HOST + HTTPS_PORT_ELIDED,
+    UNAUTHENTICATED_ORIGIN: 'http://' + OTHER_HOST + HTTP_PORT_ELIDED,
+    AUTHENTICATED_ORIGIN: 'https://' + OTHER_HOST + HTTPS_PORT_ELIDED
   };
 }
 
 function get_port(loc) {
   // When a default port is used, location.port returns the empty string.
   // To compare with wptserve `ports` substitution we need a port...
   // loc can be Location/<a>/<area>/URL, but assumes http/https only.
   if (loc.port) {