Bug 1773192 - Referrer header missing after calling history.replaceState and clicking back button. r=smaug

Differential Revision: https://phabricator.services.mozilla.com/D149176
This commit is contained in:
Peter Van der Beken 2022-06-15 11:32:16 +00:00
parent a8165074bc
commit c55748ac0b
8 changed files with 116 additions and 9 deletions

View File

@ -11466,6 +11466,7 @@ nsresult nsDocShell::UpdateURLAndHistory(Document* aDocument, nsIURI* aNewURI,
UpdateActiveEntry(false,
/* aPreviousScrollPos = */ Some(scrollPos), aNewURI,
/* aOriginalURI = */ nullptr,
/* aReferrerInfo = */ nullptr,
/* aTriggeringPrincipal = */ aDocument->NodePrincipal(),
csp, title, scrollRestorationIsManual, aData,
uriWasModified);
@ -11508,12 +11509,17 @@ nsresult nsDocShell::UpdateURLAndHistory(Document* aDocument, nsIURI* aNewURI,
// in our case. We could also set it to aNewURI, with the same result.
// We don't use aTitle here, see bug 544535.
nsString title;
nsCOMPtr<nsIReferrerInfo> referrerInfo;
if (mActiveEntry) {
title = mActiveEntry->GetTitle();
referrerInfo = mActiveEntry->GetReferrerInfo();
} else {
referrerInfo = nullptr;
}
UpdateActiveEntry(
true, /* aPreviousScrollPos = */ Nothing(), aNewURI, aNewURI,
aDocument->NodePrincipal(), aDocument->GetCsp(), title,
/* aReferrerInfo = */ referrerInfo, aDocument->NodePrincipal(),
aDocument->GetCsp(), title,
mActiveEntry && mActiveEntry->GetScrollRestorationIsManual(), aData,
uriWasModified);
} else {
@ -11933,10 +11939,10 @@ nsresult nsDocShell::AddToSessionHistory(
void nsDocShell::UpdateActiveEntry(
bool aReplace, const Maybe<nsPoint>& aPreviousScrollPos, nsIURI* aURI,
nsIURI* aOriginalURI, nsIPrincipal* aTriggeringPrincipal,
nsIContentSecurityPolicy* aCsp, const nsAString& aTitle,
bool aScrollRestorationIsManual, nsIStructuredCloneContainer* aData,
bool aURIWasModified) {
nsIURI* aOriginalURI, nsIReferrerInfo* aReferrerInfo,
nsIPrincipal* aTriggeringPrincipal, nsIContentSecurityPolicy* aCsp,
const nsAString& aTitle, bool aScrollRestorationIsManual,
nsIStructuredCloneContainer* aData, bool aURIWasModified) {
MOZ_ASSERT(mozilla::SessionHistoryInParent());
MOZ_ASSERT(aURI, "uri is null");
MOZ_ASSERT(mLoadType == LOAD_PUSHSTATE,
@ -11965,6 +11971,7 @@ void nsDocShell::UpdateActiveEntry(
aURI, aTriggeringPrincipal, nullptr, nullptr, aCsp, mContentTypeHint);
}
mActiveEntry->SetOriginalURI(aOriginalURI);
mActiveEntry->SetReferrerInfo(aReferrerInfo);
mActiveEntry->SetTitle(aTitle);
mActiveEntry->SetStateData(static_cast<nsStructuredCloneContainer*>(aData));
mActiveEntry->SetURIWasModified(aURIWasModified);

View File

@ -640,10 +640,10 @@ class nsDocShell final : public nsDocLoader,
void UpdateActiveEntry(
bool aReplace, const mozilla::Maybe<nsPoint>& aPreviousScrollPos,
nsIURI* aURI, nsIURI* aOriginalURI, nsIPrincipal* aTriggeringPrincipal,
nsIContentSecurityPolicy* aCsp, const nsAString& aTitle,
bool aScrollRestorationIsManual, nsIStructuredCloneContainer* aData,
bool aURIWasModified);
nsIURI* aURI, nsIURI* aOriginalURI, nsIReferrerInfo* aReferrerInfo,
nsIPrincipal* aTriggeringPrincipal, nsIContentSecurityPolicy* aCsp,
const nsAString& aTitle, bool aScrollRestorationIsManual,
nsIStructuredCloneContainer* aData, bool aURIWasModified);
nsresult AddChildSHEntry(nsISHEntry* aCloneRef, nsISHEntry* aNewEntry,
int32_t aChildOffset, uint32_t aLoadType,

View File

@ -71,6 +71,11 @@ class SessionHistoryInfo {
mResultPrincipalURI = aResultPrincipalURI;
}
nsIReferrerInfo* GetReferrerInfo() { return mReferrerInfo; }
void SetReferrerInfo(nsIReferrerInfo* aReferrerInfo) {
mReferrerInfo = aReferrerInfo;
}
bool HasPostData() const { return mPostData; }
already_AddRefed<nsIInputStream> GetPostData() const;
void SetPostData(nsIInputStream* aPostData);

View File

@ -0,0 +1,13 @@
<script>
let bc = new BroadcastChannel("bug1743353");
bc.addEventListener("message", ({ data }) => {
if (data == "next") {
location = "file_bug1773192_2.html";
} else if (data == "close") {
window.close();
}
});
window.addEventListener("pageshow", () => {
bc.postMessage({ location: location.href, referrer: document.referrer });
});
</script>

View File

@ -0,0 +1,13 @@
<html>
<head>
<meta http-equiv="Cache-Control" content="no-cache, no-store">
<meta name="referrer" content="same-origin">
</head>
<body>
<form method="POST" action="file_bug1773192_3.sjs"></form>
<script>
history.replaceState({}, "", document.referrer);
document.forms[0].submit();
</script>
</body>
</html>

View File

@ -0,0 +1,3 @@
function handleRequest(request, response) {
response.write("<script>history.back();</script>");
}

View File

@ -140,6 +140,11 @@ support-files =
[test_bug1747033.html]
support-files =
file_bug1747033.sjs
[test_bug1773192.html]
support-files =
file_bug1773192_1.html
file_bug1773192_2.html
file_bug1773192_3.sjs
[test_close_onpagehide_by_history_back.html]
[test_close_onpagehide_by_window_close.html]
[test_compressed_multipart.html]

View File

@ -0,0 +1,61 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test referrer with going back</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
<script>
SimpleTest.waitForExplicitFinish();
// file_bug1773192_1.html will send a message with some data on pageshow.
function waitForData(bc) {
return new Promise(resolve => {
bc.addEventListener(
"message",
({ data }) => {
resolve(data);
},
{ once: true }
);
});
}
async function runTest() {
let bc = new BroadcastChannel("bug1743353");
let getData = waitForData(bc);
window.open("file_bug1773192_1.html", "", "noreferrer");
await getData.then(({ referrer }) => {
is(referrer, "", "Referrer should be empty at first.");
});
getData = waitForData(bc);
// When file_bug1773192_1.html receives this message it will navigate to
// file_bug1773192_2.html. file_bug1773192_2.html removes itself from
// history with replaceState and submits a form with the POST method to
// file_bug1773192_3.sjs. file_bug1773192_3.sjs goes back in history.
// We should end up back at file_bug1773192_1.html, which will send a
// message with some data on pageshow.
bc.postMessage("next");
await getData.then(({ location, referrer }) => {
let firstURL = new URL("file_bug1773192_1.html", location).toString();
is(location, firstURL, "Location should be the first page again.");
is(referrer, firstURL, "Referrer should also be the first page.");
});
bc.postMessage("close");
SimpleTest.finish();
}
</script>
</head>
<body onload="runTest();">
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test"></pre>
</body>
</html>