diff --git a/components/net/about_loader.rs b/components/net/about_loader.rs index e5b1756cac38..92f910cbca01 100644 --- a/components/net/about_loader.rs +++ b/components/net/about_loader.rs @@ -36,6 +36,7 @@ pub fn factory(mut load_data: LoadData, headers: None, status: Some(RawStatus(200, "OK".into())), https_state: HttpsState::None, + referrer: None, }; if let Ok(chan) = start_sending_sniffed_opt(start_chan, metadata, diff --git a/components/net/blob_loader.rs b/components/net/blob_loader.rs index e12cdab9804f..26448b6fec69 100644 --- a/components/net/blob_loader.rs +++ b/components/net/blob_loader.rs @@ -51,6 +51,7 @@ pub fn load_blob(load_data: LoadData, start_chan: LoadConsumer, // https://w3c.github.io/FileAPI/#TwoHundredOK status: Some(RawStatus(200, "OK".into())), https_state: HttpsState::None, + referrer: None }; if let Ok(chan) = diff --git a/components/net/http_loader.rs b/components/net/http_loader.rs index fa768670c745..65cba761925a 100644 --- a/components/net/http_loader.rs +++ b/components/net/http_loader.rs @@ -1070,6 +1070,7 @@ pub fn load(load_data: &LoadData, } else { HttpsState::None }; + metadata.referrer = referrer_url; // Only notify the devtools about the final request that received a response. if let Some(msg) = msg { diff --git a/components/net_traits/lib.rs b/components/net_traits/lib.rs index 60163bb090a3..875bbd106aad 100644 --- a/components/net_traits/lib.rs +++ b/components/net_traits/lib.rs @@ -565,6 +565,9 @@ pub struct Metadata { /// Is successful HTTPS connection pub https_state: HttpsState, + + /// Referrer Url + pub referrer: Option, } impl Metadata { @@ -578,6 +581,7 @@ impl Metadata { // https://fetch.spec.whatwg.org/#concept-response-status-message status: Some(RawStatus(200, "OK".into())), https_state: HttpsState::None, + referrer: None, } } diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 68cd619ba430..1c3eccbf06ca 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -239,6 +239,8 @@ pub struct Document { origin: Origin, /// https://w3c.github.io/webappsec-referrer-policy/#referrer-policy-states referrer_policy: Cell>, + /// https://html.spec.whatwg.org/multipage/#dom-document-referrer + referrer: Option, } #[derive(JSTraceable, HeapSizeOf)] @@ -1629,7 +1631,8 @@ impl Document { content_type: Option, last_modified: Option, source: DocumentSource, - doc_loader: DocumentLoader) + doc_loader: DocumentLoader, + referrer: Option) -> Document { let url = url.unwrap_or_else(|| Url::parse("about:blank").unwrap()); @@ -1716,6 +1719,7 @@ impl Document { origin: origin, //TODO - setting this for now so no Referer header set referrer_policy: Cell::new(Some(ReferrerPolicy::NoReferrer)), + referrer: referrer, } } @@ -1732,7 +1736,8 @@ impl Document { None, None, DocumentSource::NotFromParser, - docloader)) + docloader, + None)) } pub fn new(window: &Window, @@ -1742,7 +1747,8 @@ impl Document { content_type: Option, last_modified: Option, source: DocumentSource, - doc_loader: DocumentLoader) + doc_loader: DocumentLoader, + referrer: Option) -> Root { let document = reflect_dom_object(box Document::new_inherited(window, browsing_context, @@ -1751,7 +1757,8 @@ impl Document { content_type, last_modified, source, - doc_loader), + doc_loader, + referrer), GlobalRef::Window(window), DocumentBinding::Wrap); { @@ -1815,7 +1822,8 @@ impl Document { None, None, DocumentSource::NotFromParser, - DocumentLoader::new(&self.loader())); + DocumentLoader::new(&self.loader()), + None); new_doc.appropriate_template_contents_owner_document.set(Some(&new_doc)); new_doc }) @@ -1934,6 +1942,14 @@ impl DocumentMethods for Document { } } + // https://html.spec.whatwg.org/multipage/#dom-document-referrer + fn Referrer(&self) -> DOMString { + match self.referrer { + Some(ref referrer) => DOMString::from(referrer.to_string()), + None => DOMString::new() + } + } + // https://dom.spec.whatwg.org/#dom-document-documenturi fn DocumentURI(&self) -> USVString { self.URL() diff --git a/components/script/dom/domimplementation.rs b/components/script/dom/domimplementation.rs index 30974ea2f462..1e29ce324b32 100644 --- a/components/script/dom/domimplementation.rs +++ b/components/script/dom/domimplementation.rs @@ -129,7 +129,8 @@ impl DOMImplementationMethods for DOMImplementation { None, None, DocumentSource::NotFromParser, - loader); + loader, + None); { // Step 3. diff --git a/components/script/dom/domparser.rs b/components/script/dom/domparser.rs index 346b8f801706..e47492d87e5b 100644 --- a/components/script/dom/domparser.rs +++ b/components/script/dom/domparser.rs @@ -68,7 +68,8 @@ impl DOMParserMethods for DOMParser { Some(content_type), None, DocumentSource::FromParser, - loader); + loader, + None); parse_html(document.r(), s, url, ParseContext::Owner(None)); document.set_ready_state(DocumentReadyState::Complete); Ok(document) @@ -82,7 +83,8 @@ impl DOMParserMethods for DOMParser { Some(content_type), None, DocumentSource::NotFromParser, - loader); + loader, + None); parse_xml(document.r(), s, url, xml::ParseContext::Owner(None)); Ok(document) } diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index 811716088b69..03ec5496efa0 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -1721,7 +1721,7 @@ impl Node { let document = Document::new(window, None, Some((*document.url()).clone()), is_html_doc, None, - None, DocumentSource::NotFromParser, loader); + None, DocumentSource::NotFromParser, loader, None); Root::upcast::(document) }, NodeTypeId::Element(..) => { diff --git a/components/script/dom/webidls/Document.webidl b/components/script/dom/webidls/Document.webidl index 6b365378c923..81a6c032df7e 100644 --- a/components/script/dom/webidls/Document.webidl +++ b/components/script/dom/webidls/Document.webidl @@ -82,7 +82,7 @@ partial /*sealed*/ interface Document { [/*PutForwards=href, */Unforgeable] readonly attribute Location? location; readonly attribute DOMString domain; - // readonly attribute DOMString referrer; + readonly attribute DOMString referrer; [Throws] attribute DOMString cookie; readonly attribute DOMString lastModified; diff --git a/components/script/dom/xmldocument.rs b/components/script/dom/xmldocument.rs index b291c912089a..52ebce5f55c6 100644 --- a/components/script/dom/xmldocument.rs +++ b/components/script/dom/xmldocument.rs @@ -41,7 +41,8 @@ impl XMLDocument { content_type, last_modified, source, - doc_loader), + doc_loader, + None), } } diff --git a/components/script/dom/xmlhttprequest.rs b/components/script/dom/xmlhttprequest.rs index 148a51c8c6ba..4a6dba72f6f8 100644 --- a/components/script/dom/xmlhttprequest.rs +++ b/components/script/dom/xmlhttprequest.rs @@ -1234,7 +1234,9 @@ impl XMLHttpRequest { is_html_document, content_type, None, - DocumentSource::FromParser, docloader) + DocumentSource::FromParser, + docloader, + None) } fn filter_response_headers(&self) -> Headers { diff --git a/components/script/parse/html.rs b/components/script/parse/html.rs index 87aa7a6b2938..e1109cfc0087 100644 --- a/components/script/parse/html.rs +++ b/components/script/parse/html.rs @@ -279,7 +279,8 @@ pub fn parse_html_fragment(context_node: &Node, IsHTMLDocument::HTMLDocument, None, None, DocumentSource::FromParser, - loader); + loader, + None); // Step 2. document.set_quirks_mode(context_document.quirks_mode()); diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index e116ace1be41..c99a9985c784 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -1704,6 +1704,11 @@ impl ScriptThread { _ => IsHTMLDocument::HTMLDocument, }; + let referrer = match metadata.referrer { + Some(ref referrer) => Some(referrer.clone().into_string()), + None => None, + }; + let document = Document::new(window.r(), Some(&browsing_context), Some(final_url.clone()), @@ -1711,7 +1716,8 @@ impl ScriptThread { content_type, last_modified, DocumentSource::FromParser, - loader); + loader, + referrer); if using_new_context { browsing_context.init(&document); } else { diff --git a/tests/wpt/metadata/XMLHttpRequest/responsexml-document-properties.htm.ini b/tests/wpt/metadata/XMLHttpRequest/responsexml-document-properties.htm.ini index 3ff6b5afb2b6..2d5b2b753d51 100644 --- a/tests/wpt/metadata/XMLHttpRequest/responsexml-document-properties.htm.ini +++ b/tests/wpt/metadata/XMLHttpRequest/responsexml-document-properties.htm.ini @@ -3,9 +3,6 @@ [domain] expected: FAIL - [referrer] - expected: FAIL - [readyState] expected: FAIL diff --git a/tests/wpt/metadata/html/dom/interfaces.html.ini b/tests/wpt/metadata/html/dom/interfaces.html.ini index 92990e9dab8e..58ff349823fd 100644 --- a/tests/wpt/metadata/html/dom/interfaces.html.ini +++ b/tests/wpt/metadata/html/dom/interfaces.html.ini @@ -3,9 +3,6 @@ [Document interface: attribute domain] expected: FAIL - [Document interface: attribute referrer] - expected: FAIL - [Document interface: attribute dir] expected: FAIL @@ -6990,9 +6987,6 @@ [Document interface: document.implementation.createDocument(null, "", null) must inherit property "enableStyleSheetsForSet" with the proper type (33)] expected: FAIL - [Document interface: document.implementation.createDocument(null, "", null) must inherit property "referrer" with the proper type (36)] - expected: FAIL - [Document interface: document.implementation.createDocument(null, "", null) must inherit property "dir" with the proper type (42)] expected: FAIL @@ -7350,9 +7344,6 @@ [Document interface: new Document() must have own property "location"] expected: FAIL - [Document interface: new Document() must inherit property "referrer" with the proper type (36)] - expected: FAIL - [Document interface: new Document() must inherit property "dir" with the proper type (42)] expected: FAIL diff --git a/tests/wpt/mozilla/tests/mozilla/referrer-policy/generic/referrer-policy-test-case.js b/tests/wpt/mozilla/tests/mozilla/referrer-policy/generic/referrer-policy-test-case.js index 8e011be374f3..a2e1887530a9 100644 --- a/tests/wpt/mozilla/tests/mozilla/referrer-policy/generic/referrer-policy-test-case.js +++ b/tests/wpt/mozilla/tests/mozilla/referrer-policy/generic/referrer-policy-test-case.js @@ -105,11 +105,10 @@ function ReferrerPolicyTestCase(scenario, testDescription, sanityChecker) { // Check the reported URL. test.step(function() { - // TODO - can uncomment when Document::Referrer is implemented - // assert_equals(result.referrer, - // t._expectedReferrerUrl, - // "Reported Referrer URL is '" + - // t._scenario.referrer_url + "'."); + assert_equals(result.referrer, + t._expectedReferrerUrl, + "Reported Referrer URL is '" + + t._scenario.referrer_url + "'."); assert_equals(result.headers.referer, t._expectedReferrerUrl, "Reported Referrer URL from HTTP header is '" + diff --git a/tests/wpt/mozilla/tests/mozilla/referrer-policy/generic/template/document.html.template b/tests/wpt/mozilla/tests/mozilla/referrer-policy/generic/template/document.html.template index 7be7fcc2abff..fa2baa63cf80 100644 --- a/tests/wpt/mozilla/tests/mozilla/referrer-policy/generic/template/document.html.template +++ b/tests/wpt/mozilla/tests/mozilla/referrer-policy/generic/template/document.html.template @@ -16,7 +16,7 @@ return(false); } - var referrer = 'referrer' in document ? document.referrer : undefined; + var referrer = document.referrer.length > 0 ? document.referrer : undefined; var result = { location: document.location.toString(),