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 286150 fc5cc380ddb34a2939d2a5bc2a6121b879b5fa95
parent 286149 d37744e8ec76bdb6507e73959cb8b46b03a89b1f
child 286151 954c9e9408fdebff893dc430a733981e43499b63
push id30039
push usercbook@mozilla.com
push dateTue, 01 Mar 2016 11:02:11 +0000
treeherdermozilla-central@5cafa6f3019b [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]