| function wrapResult(server_data) { |
| return { |
| referrer: server_data.headers.referer, |
| headers: server_data.headers |
| } |
| } |
| |
| // NOTE: This method only strips the fragment and is not in accordance to the |
| // recommended draft specification: |
| // https://w3c.github.io/webappsec/specs/referrer-policy/#null |
| // TODO(kristijanburnik): Implement this helper as defined by spec once added |
| // scenarios for URLs containing username/password/etc. |
| function stripUrlForUseAsReferrer(url) { |
| return url.replace(/#.*$/, ""); |
| } |
| |
| function normalizePort(targetPort) { |
| var defaultPorts = [80, 443]; |
| var isDefaultPortForProtocol = (defaultPorts.indexOf(targetPort) >= 0); |
| |
| return (targetPort == "" || isDefaultPortForProtocol) ? |
| "" : ":" + targetPort; |
| } |
| |
| function ReferrerPolicyTestCase(scenario, testDescription, sanityChecker) { |
| // Pass and skip rest of the test if browser does not support fetch. |
| if (scenario.subresource == "fetch-request" && !window.fetch) { |
| // TODO(kristijanburnik): This should be refactored. |
| return { |
| start: function() { |
| test(function() { assert_true(true); }, |
| "[ReferrerPolicyTestCase] Skipping test: Fetch is not supported."); |
| } |
| }; |
| } |
| |
| // This check is A NOOP in release. |
| sanityChecker.checkScenario(scenario); |
| |
| var subresourceInvoker = { |
| "a-tag": requestViaAnchor, |
| "area-tag": requestViaArea, |
| "fetch-request": requestViaFetch, |
| "iframe-tag": requestViaIframe, |
| "img-tag": requestViaImageForReferrerPolicy, |
| "script-tag": requestViaScript, |
| "worker-request": url => requestViaDedicatedWorker(url, {}), |
| "module-worker": url => requestViaDedicatedWorker(url, {type: "module"}), |
| "shared-worker": requestViaSharedWorker, |
| "xhr-request": requestViaXhr |
| }; |
| |
| const subresourcePath = { |
| "a-tag": "/common/security-features/subresource/document.py", |
| "area-tag": "/common/security-features/subresource/document.py", |
| "fetch-request": "/common/security-features/subresource/xhr.py", |
| "iframe-tag": "/common/security-features/subresource/document.py", |
| "img-tag": "/common/security-features/subresource/image.py", |
| "script-tag": "/common/security-features/subresource/script.py", |
| "worker-request": "/common/security-features/subresource/worker.py", |
| "module-worker": "/common/security-features/subresource/worker.py", |
| "shared-worker": "/common/security-features/subresource/shared-worker.py", |
| "xhr-request": "/common/security-features/subresource/xhr.py" |
| }; |
| |
| var referrerUrlResolver = { |
| "omitted": function() { |
| return undefined; |
| }, |
| "origin": function() { |
| return self.origin + "/"; |
| }, |
| "stripped-referrer": function() { |
| return stripUrlForUseAsReferrer(location.toString()); |
| } |
| }; |
| |
| var t = { |
| _scenario: scenario, |
| _testDescription: testDescription, |
| _constructSubresourceUrl: function() { |
| // TODO(kristijanburnik): We should assert that these two domains are |
| // different. E.g. If someone runs the tets over www, this would fail. |
| var domainForOrigin = { |
| "cross-origin":"{{domains[www1]}}", |
| "same-origin": location.hostname |
| }; |
| |
| // Values obtained and replaced by the wptserve pipeline: |
| // http://wptserve.readthedocs.org/en/latest/pipes.html#built-in-pipes |
| var portForProtocol = { |
| "http": parseInt("{{ports[http][0]}}"), |
| "https": parseInt("{{ports[https][0]}}") |
| } |
| |
| var targetPort = portForProtocol[t._scenario.target_protocol]; |
| |
| return t._scenario.target_protocol + "://" + |
| domainForOrigin[t._scenario.origin] + |
| normalizePort(targetPort) + |
| subresourcePath[t._scenario.subresource] + |
| "?redirection=" + t._scenario["redirection"] + |
| "&cache_destroyer=" + (new Date()).getTime(); |
| }, |
| |
| _constructExpectedReferrerUrl: function() { |
| return referrerUrlResolver[t._scenario.referrer_url](); |
| }, |
| |
| // Returns a promise. |
| _invokeSubresource: function(resourceRequestUrl) { |
| var invoker = subresourceInvoker[t._scenario.subresource]; |
| // Depending on the delivery method, extend the subresource element with |
| // these attributes. |
| var elementAttributesForDeliveryMethod = { |
| "attr-referrer": {referrerPolicy: t._scenario.referrer_policy}, |
| "rel-noreferrer": {rel: "noreferrer"} |
| }; |
| |
| var delivery_method = t._scenario.delivery_method; |
| |
| if (delivery_method in elementAttributesForDeliveryMethod) { |
| return invoker(resourceRequestUrl, |
| elementAttributesForDeliveryMethod[delivery_method], |
| t._scenario.referrer_policy); |
| } else { |
| return invoker(resourceRequestUrl, {}, t._scenario.referrer_policy); |
| } |
| }, |
| |
| start: function() { |
| promise_test(test => { |
| const resourceRequestUrl = t._constructSubresourceUrl(); |
| const expectedReferrerUrl = t._constructExpectedReferrerUrl(); |
| return t._invokeSubresource(resourceRequestUrl) |
| .then(result => { |
| // Check if the result is in valid format. NOOP in release. |
| sanityChecker.checkSubresourceResult( |
| test, t._scenario, resourceRequestUrl, result); |
| |
| // Check the reported URL. |
| assert_equals(result.referrer, |
| expectedReferrerUrl, |
| "Reported Referrer URL is '" + |
| t._scenario.referrer_url + "'."); |
| assert_equals(result.headers.referer, |
| expectedReferrerUrl, |
| "Reported Referrer URL from HTTP header is '" + |
| expectedReferrerUrl + "'"); |
| }); |
| }, t._testDescription); |
| } |
| } |
| |
| return t; |
| } |