Bug 1251873 - Store the trimmed referrer URL on HTTP channel if a trimming referrer policy is in effect; r=mcmanus
☠☠ backed out by a25a526db6ad ☠ ☠
authorEhsan Akhgari <ehsan.akhgari@gmail.com>
Mon, 29 Feb 2016 14:50:20 -0500
changeset 322486 fc5cc380ddb34a2939d2a5bc2a6121b879b5fa95
parent 322485 d37744e8ec76bdb6507e73959cb8b46b03a89b1f
child 322487 954c9e9408fdebff893dc430a733981e43499b63
push id5913
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 16:57:49 +0000
treeherdermozilla-beta@dcaf0a6fa115 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmcmanus
bugs1251873
milestone47.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1251873 - Store the trimmed referrer URL on HTTP channel if a trimming referrer policy is in effect; r=mcmanus Failure to do this will result in the consumers of nsIHttpChannel::GetReferrer() observing the wrong referrer. The test in this patch shows the scenarios which would fail under such conditions.
netwerk/protocol/http/HttpBaseChannel.cpp
netwerk/test/unit/test_referrer_policy.js
netwerk/test/unit/xpcshell.ini
--- a/netwerk/protocol/http/HttpBaseChannel.cpp
+++ b/netwerk/protocol/http/HttpBaseChannel.cpp
@@ -1500,16 +1500,22 @@ HttpBaseChannel::SetReferrerWithPolicy(n
 
   default:
     // full URI
     rv = clone->GetAsciiSpec(spec);
     if (NS_FAILED(rv)) return rv;
     break;
   }
 
+  // If any user trimming policy is in effect, use the trimmed URI.
+  if (userReferrerTrimmingPolicy) {
+    rv = NS_NewURI(getter_AddRefs(clone), spec);
+    if (NS_FAILED(rv)) return rv;
+  }
+
   // finally, remember the referrer URI and set the Referer header.
   rv = SetRequestHeader(NS_LITERAL_CSTRING("Referer"), spec, false);
   if (NS_FAILED(rv)) return rv;
 
   mReferrer = clone;
   mReferrerPolicy = referrerPolicy;
   return NS_OK;
 }
new file mode 100644
--- /dev/null
+++ b/netwerk/test/unit/test_referrer_policy.js
@@ -0,0 +1,77 @@
+Cu.import("resource://gre/modules/NetUtil.jsm");
+
+function test_policy(test) {
+  do_print("Running test: " + test.toSource());
+
+  var uri = NetUtil.newURI(test.url, "", null)
+  var chan = NetUtil.newChannel({
+    uri: uri,
+    loadUsingSystemPrincipal: true
+  });
+
+  var referrer = NetUtil.newURI(test.referrer, "", null);
+  chan.QueryInterface(Components.interfaces.nsIHttpChannel);
+  chan.setReferrerWithPolicy(referrer, test.policy);
+  if (test.expectedHeader === undefined) {
+    try {
+      chan.getRequestHeader("Referer");
+      do_throw("Should not find a Referer header!");
+    } catch(e) {
+    }
+    do_check_eq(chan.referrer, null);
+  } else {
+    var header = chan.getRequestHeader("Referer");
+    do_check_eq(header, test.expectedHeader);
+    do_check_eq(chan.referrer.spec, test.expectedReferrerSpec);
+  }
+}
+
+const nsIHttpChannel = Ci.nsIHttpChannel;
+var gTests = [
+  {
+    policy: nsIHttpChannel.REFERRER_POLICY_DEFAULT,
+    url: "https://test.example/foo",
+    referrer: "https://test.example/referrer",
+    expectedHeader: "https://test.example/referrer",
+    expectedReferrerSpec: "https://test.example/referrer"
+  },
+  {
+    policy: nsIHttpChannel.REFERRER_POLICY_DEFAULT,
+    url: "http://test.example/foo",
+    referrer: "https://test.example/referrer",
+    expectedHeader: undefined,
+    expectedReferrerSpec: undefined
+  },
+  {
+    policy: nsIHttpChannel.REFERRER_POLICY_NO_REFERRER,
+    url: "https://test.example/foo",
+    referrer: "https://test.example/referrer",
+    expectedHeader: undefined,
+    expectedReferrerSpec: undefined
+  },
+  {
+    policy: nsIHttpChannel.REFERRER_POLICY_ORIGIN,
+    url: "https://test.example/foo",
+    referrer: "https://test.example/referrer",
+    expectedHeader: "https://test.example",
+    expectedReferrerSpec: "https://test.example/"
+  },
+  {
+    policy: nsIHttpChannel.REFERRER_POLICY_UNSAFE_URL,
+    url: "https://test.example/foo",
+    referrer: "https://test.example/referrer",
+    expectedHeader: "https://test.example/referrer",
+    expectedReferrerSpec: "https://test.example/referrer"
+  },
+  {
+    policy: nsIHttpChannel.REFERRER_POLICY_UNSAFE_URL,
+    url: "http://test.example/foo",
+    referrer: "https://test.example/referrer",
+    expectedHeader: "https://test.example/referrer",
+    expectedReferrerSpec: "https://test.example/referrer"
+  },
+];
+
+function run_test() {
+  gTests.forEach(test => test_policy(test));
+}
--- a/netwerk/test/unit/xpcshell.ini
+++ b/netwerk/test/unit/xpcshell.ini
@@ -310,16 +310,17 @@ run-sequentially = Hardcoded hash value 
 [test_unix_domain.js]
 # The xpcshell temp directory on Android doesn't seem to let us create
 # Unix domain sockets. (Perhaps it's a FAT filesystem?)
 skip-if = os == "android"
 [test_addr_in_use_error.js]
 [test_about_networking.js]
 [test_ping_aboutnetworking.js]
 [test_referrer.js]
+[test_referrer_policy.js]
 [test_predictor.js]
 # Android version detection w/in gecko does not work right on infra, so we just
 # disable this test on all android versions, even though it's enabled on 2.3+ in
 # the wild.
 skip-if = os == "android"
 [test_signature_extraction.js]
 skip-if = os != "win"
 [test_synthesized_response.js]