mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 704320 - Parse and implement meta tag-based referrer policies for documents and nsHttpChannels. (r=bz,mcmanus)
This commit is contained in:
parent
41b6632668
commit
290f6d6062
@ -187,8 +187,10 @@ let SessionHistoryInternal = {
|
||||
|
||||
// We will include the property only if it's truthy to save a couple of
|
||||
// bytes when the resulting object is stringified and saved to disk.
|
||||
if (shEntry.referrerURI)
|
||||
if (shEntry.referrerURI) {
|
||||
entry.referrer = shEntry.referrerURI.spec;
|
||||
entry.referrerPolicy = shEntry.referrerPolicy;
|
||||
}
|
||||
|
||||
if (shEntry.srcdocData)
|
||||
entry.srcdocData = shEntry.srcdocData;
|
||||
@ -340,8 +342,10 @@ let SessionHistoryInternal = {
|
||||
shEntry.loadType = Ci.nsIDocShellLoadInfo.loadHistory;
|
||||
if (entry.contentType)
|
||||
shEntry.contentType = entry.contentType;
|
||||
if (entry.referrer)
|
||||
if (entry.referrer) {
|
||||
shEntry.referrerURI = Utils.makeURI(entry.referrer);
|
||||
shEntry.referrerPolicy = entry.referrerPolicy;
|
||||
}
|
||||
if (entry.isSrcdocEntry)
|
||||
shEntry.srcdocData = entry.srcdocData;
|
||||
if (entry.baseURI)
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "nsDocShellCID.h"
|
||||
#include "nsDOMCID.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "mozilla/net/ReferrerPolicy.h"
|
||||
#include "nsRect.h"
|
||||
#include "prenv.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
@ -554,6 +555,7 @@ struct SendPingInfo {
|
||||
bool requireSameHost;
|
||||
nsIURI *target;
|
||||
nsIURI *referrer;
|
||||
uint32_t referrerPolicy;
|
||||
};
|
||||
|
||||
static void
|
||||
@ -633,7 +635,7 @@ SendPing(void *closure, nsIContent *content, nsIURI *uri, nsIIOService *ios)
|
||||
// over an encrypted connection and its address does not have the same
|
||||
// origin as "ping URL", send a referrer.
|
||||
if (!sameOrigin && !referrerIsSecure)
|
||||
httpChan->SetReferrer(info->referrer);
|
||||
httpChan->SetReferrerWithPolicy(info->referrer, info->referrerPolicy);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIUploadChannel2> uploadChan = do_QueryInterface(httpChan);
|
||||
@ -691,7 +693,10 @@ SendPing(void *closure, nsIContent *content, nsIURI *uri, nsIIOService *ios)
|
||||
|
||||
// Spec: http://whatwg.org/specs/web-apps/current-work/#ping
|
||||
static void
|
||||
DispatchPings(nsIContent *content, nsIURI *target, nsIURI *referrer)
|
||||
DispatchPings(nsIContent *content,
|
||||
nsIURI *target,
|
||||
nsIURI *referrer,
|
||||
uint32_t referrerPolicy)
|
||||
{
|
||||
SendPingInfo info;
|
||||
|
||||
@ -703,6 +708,7 @@ DispatchPings(nsIContent *content, nsIURI *target, nsIURI *referrer)
|
||||
info.numPings = 0;
|
||||
info.target = target;
|
||||
info.referrer = referrer;
|
||||
info.referrerPolicy = referrerPolicy;
|
||||
|
||||
ForEachPing(content, SendPing, &info);
|
||||
}
|
||||
@ -1346,6 +1352,7 @@ nsDocShell::LoadURI(nsIURI * aURI,
|
||||
bool inheritOwner = false;
|
||||
bool ownerIsExplicit = false;
|
||||
bool sendReferrer = true;
|
||||
uint32_t referrerPolicy = mozilla::net::RP_Default;
|
||||
bool isSrcdoc = false;
|
||||
nsCOMPtr<nsISHEntry> shEntry;
|
||||
nsXPIDLString target;
|
||||
@ -1379,6 +1386,7 @@ nsDocShell::LoadURI(nsIURI * aURI,
|
||||
aLoadInfo->GetPostDataStream(getter_AddRefs(postStream));
|
||||
aLoadInfo->GetHeadersStream(getter_AddRefs(headersStream));
|
||||
aLoadInfo->GetSendReferrer(&sendReferrer);
|
||||
aLoadInfo->GetReferrerPolicy(&referrerPolicy);
|
||||
aLoadInfo->GetIsSrcdocLoad(&isSrcdoc);
|
||||
aLoadInfo->GetSrcdocData(srcdoc);
|
||||
aLoadInfo->GetSourceDocShell(getter_AddRefs(sourceDocShell));
|
||||
@ -1602,6 +1610,7 @@ nsDocShell::LoadURI(nsIURI * aURI,
|
||||
|
||||
return InternalLoad(aURI,
|
||||
referrer,
|
||||
referrerPolicy,
|
||||
owner,
|
||||
flags,
|
||||
target.get(),
|
||||
@ -5265,8 +5274,8 @@ nsDocShell::LoadErrorPage(nsIURI *aURI, const char16_t *aURL,
|
||||
rv = NS_NewURI(getter_AddRefs(errorPageURI), errorPageUrl);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return InternalLoad(errorPageURI, nullptr, nullptr,
|
||||
INTERNAL_LOAD_FLAGS_INHERIT_OWNER, nullptr, nullptr,
|
||||
return InternalLoad(errorPageURI, nullptr, mozilla::net::RP_Default,
|
||||
nullptr, INTERNAL_LOAD_FLAGS_INHERIT_OWNER, nullptr, nullptr,
|
||||
NullString(), nullptr, nullptr, LOAD_ERROR_PAGE,
|
||||
nullptr, true, NullString(), this, nullptr, nullptr,
|
||||
nullptr);
|
||||
@ -5328,6 +5337,7 @@ nsDocShell::Reload(uint32_t aReloadFlags)
|
||||
}
|
||||
rv = InternalLoad(mCurrentURI,
|
||||
mReferrerURI,
|
||||
mReferrerPolicy,
|
||||
principal,
|
||||
flags,
|
||||
nullptr, // No window target
|
||||
@ -9230,7 +9240,8 @@ void CopyFavicon(nsIURI *aOldURI, nsIURI *aNewURI, bool inPrivateBrowsing)
|
||||
class InternalLoadEvent : public nsRunnable
|
||||
{
|
||||
public:
|
||||
InternalLoadEvent(nsDocShell* aDocShell, nsIURI * aURI, nsIURI * aReferrer,
|
||||
InternalLoadEvent(nsDocShell* aDocShell, nsIURI * aURI,
|
||||
nsIURI * aReferrer, uint32_t aReferrerPolicy,
|
||||
nsISupports * aOwner, uint32_t aFlags,
|
||||
const char* aTypeHint, nsIInputStream * aPostData,
|
||||
nsIInputStream * aHeadersData, uint32_t aLoadType,
|
||||
@ -9241,6 +9252,7 @@ public:
|
||||
mDocShell(aDocShell),
|
||||
mURI(aURI),
|
||||
mReferrer(aReferrer),
|
||||
mReferrerPolicy(aReferrerPolicy),
|
||||
mOwner(aOwner),
|
||||
mPostData(aPostData),
|
||||
mHeadersData(aHeadersData),
|
||||
@ -9258,7 +9270,9 @@ public:
|
||||
}
|
||||
|
||||
NS_IMETHOD Run() {
|
||||
return mDocShell->InternalLoad(mURI, mReferrer, mOwner, mFlags,
|
||||
return mDocShell->InternalLoad(mURI, mReferrer,
|
||||
mReferrerPolicy,
|
||||
mOwner, mFlags,
|
||||
nullptr, mTypeHint.get(),
|
||||
NullString(), mPostData, mHeadersData,
|
||||
mLoadType, mSHEntry, mFirstParty,
|
||||
@ -9276,6 +9290,7 @@ private:
|
||||
nsRefPtr<nsDocShell> mDocShell;
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
nsCOMPtr<nsIURI> mReferrer;
|
||||
uint32_t mReferrerPolicy;
|
||||
nsCOMPtr<nsISupports> mOwner;
|
||||
nsCOMPtr<nsIInputStream> mPostData;
|
||||
nsCOMPtr<nsIInputStream> mHeadersData;
|
||||
@ -9330,6 +9345,7 @@ nsDocShell::CreatePrincipalFromReferrer(nsIURI* aReferrer,
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::InternalLoad(nsIURI * aURI,
|
||||
nsIURI * aReferrer,
|
||||
uint32_t aReferrerPolicy,
|
||||
nsISupports * aOwner,
|
||||
uint32_t aFlags,
|
||||
const char16_t *aWindowTarget,
|
||||
@ -9586,6 +9602,7 @@ nsDocShell::InternalLoad(nsIURI * aURI,
|
||||
if (NS_SUCCEEDED(rv) && targetDocShell) {
|
||||
rv = targetDocShell->InternalLoad(aURI,
|
||||
aReferrer,
|
||||
aReferrerPolicy,
|
||||
owner,
|
||||
aFlags,
|
||||
nullptr, // No window target
|
||||
@ -9666,7 +9683,8 @@ nsDocShell::InternalLoad(nsIURI * aURI,
|
||||
|
||||
// Do this asynchronously
|
||||
nsCOMPtr<nsIRunnable> ev =
|
||||
new InternalLoadEvent(this, aURI, aReferrer, aOwner, aFlags,
|
||||
new InternalLoadEvent(this, aURI, aReferrer,
|
||||
aReferrerPolicy, aOwner, aFlags,
|
||||
aTypeHint, aPostData, aHeadersData,
|
||||
aLoadType, aSHEntry, aFirstParty, aSrcdoc,
|
||||
aSourceDocShell, aBaseURI);
|
||||
@ -10118,6 +10136,7 @@ nsDocShell::InternalLoad(nsIURI * aURI,
|
||||
nsCOMPtr<nsIRequest> req;
|
||||
rv = DoURILoad(aURI, aReferrer,
|
||||
!(aFlags & INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER),
|
||||
aReferrerPolicy,
|
||||
owner, aTypeHint, aFileName, aPostData, aHeadersData,
|
||||
aFirstParty, aDocShell, getter_AddRefs(req),
|
||||
(aFlags & INTERNAL_LOAD_FLAGS_FIRST_LOAD) != 0,
|
||||
@ -10191,6 +10210,7 @@ nsresult
|
||||
nsDocShell::DoURILoad(nsIURI * aURI,
|
||||
nsIURI * aReferrerURI,
|
||||
bool aSendReferrer,
|
||||
uint32_t aReferrerPolicy,
|
||||
nsISupports * aOwner,
|
||||
const char * aTypeHint,
|
||||
const nsAString & aFileName,
|
||||
@ -10520,7 +10540,7 @@ nsDocShell::DoURILoad(nsIURI * aURI,
|
||||
// Set the referrer explicitly
|
||||
if (aReferrerURI && aSendReferrer) {
|
||||
// Referrer is currenly only set for link clicks here.
|
||||
httpChannel->SetReferrer(aReferrerURI);
|
||||
httpChannel->SetReferrerWithPolicy(aReferrerURI, aReferrerPolicy);
|
||||
}
|
||||
}
|
||||
|
||||
@ -10856,6 +10876,11 @@ nsDocShell::SetupReferrerFromChannel(nsIChannel * aChannel)
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
SetReferrerURI(referrer);
|
||||
}
|
||||
uint32_t referrerPolicy;
|
||||
rv = httpChannel->GetReferrerPolicy(&referrerPolicy);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
SetReferrerPolicy(referrerPolicy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -11123,6 +11148,12 @@ nsDocShell::SetReferrerURI(nsIURI * aURI)
|
||||
mReferrerURI = aURI; // This assigment addrefs
|
||||
}
|
||||
|
||||
void
|
||||
nsDocShell::SetReferrerPolicy(uint32_t referrerPolicy)
|
||||
{
|
||||
mReferrerPolicy = referrerPolicy;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// nsDocShell: Session History
|
||||
//*****************************************************************************
|
||||
@ -11552,6 +11583,7 @@ nsDocShell::AddToSessionHistory(nsIURI * aURI, nsIChannel * aChannel,
|
||||
// Get the post data & referrer
|
||||
nsCOMPtr<nsIInputStream> inputStream;
|
||||
nsCOMPtr<nsIURI> referrerURI;
|
||||
uint32_t referrerPolicy = mozilla::net::RP_Default;
|
||||
nsCOMPtr<nsISupports> cacheKey;
|
||||
nsCOMPtr<nsISupports> owner = aOwner;
|
||||
bool expired = false;
|
||||
@ -11578,6 +11610,7 @@ nsDocShell::AddToSessionHistory(nsIURI * aURI, nsIChannel * aChannel,
|
||||
uploadChannel->GetUploadStream(getter_AddRefs(inputStream));
|
||||
}
|
||||
httpChannel->GetReferrer(getter_AddRefs(referrerURI));
|
||||
httpChannel->GetReferrerPolicy(&referrerPolicy);
|
||||
|
||||
discardLayoutState = ShouldDiscardLayoutState(httpChannel);
|
||||
}
|
||||
@ -11608,6 +11641,7 @@ nsDocShell::AddToSessionHistory(nsIURI * aURI, nsIChannel * aChannel,
|
||||
mHistoryID,
|
||||
mDynamicallyCreated);
|
||||
entry->SetReferrerURI(referrerURI);
|
||||
entry->SetReferrerPolicy(referrerPolicy);
|
||||
nsCOMPtr<nsIInputStreamChannel> inStrmChan = do_QueryInterface(aChannel);
|
||||
if (inStrmChan) {
|
||||
bool isSrcdocChannel;
|
||||
@ -11707,6 +11741,7 @@ nsDocShell::LoadHistoryEntry(nsISHEntry * aEntry, uint32_t aLoadType)
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsCOMPtr<nsIInputStream> postData;
|
||||
nsCOMPtr<nsIURI> referrerURI;
|
||||
uint32_t referrerPolicy;
|
||||
nsAutoCString contentType;
|
||||
nsCOMPtr<nsISupports> owner;
|
||||
|
||||
@ -11715,6 +11750,8 @@ nsDocShell::LoadHistoryEntry(nsISHEntry * aEntry, uint32_t aLoadType)
|
||||
NS_ENSURE_SUCCESS(aEntry->GetURI(getter_AddRefs(uri)), NS_ERROR_FAILURE);
|
||||
NS_ENSURE_SUCCESS(aEntry->GetReferrerURI(getter_AddRefs(referrerURI)),
|
||||
NS_ERROR_FAILURE);
|
||||
NS_ENSURE_SUCCESS(aEntry->GetReferrerPolicy(&referrerPolicy),
|
||||
NS_ERROR_FAILURE);
|
||||
NS_ENSURE_SUCCESS(aEntry->GetPostData(getter_AddRefs(postData)),
|
||||
NS_ERROR_FAILURE);
|
||||
NS_ENSURE_SUCCESS(aEntry->GetContentType(contentType), NS_ERROR_FAILURE);
|
||||
@ -11791,6 +11828,7 @@ nsDocShell::LoadHistoryEntry(nsISHEntry * aEntry, uint32_t aLoadType)
|
||||
// first created. bug 947716 has been created to address this issue.
|
||||
rv = InternalLoad(uri,
|
||||
referrerURI,
|
||||
referrerPolicy,
|
||||
owner,
|
||||
flags,
|
||||
nullptr, // No window target
|
||||
@ -13192,6 +13230,7 @@ nsDocShell::OnLinkClickSync(nsIContent *aContent,
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> referer = refererDoc->GetDocumentURI();
|
||||
uint32_t refererPolicy = refererDoc->GetReferrerPolicy();
|
||||
|
||||
// referer could be null here in some odd cases, but that's ok,
|
||||
// we'll just load the link w/o sending a referer in those cases.
|
||||
@ -13220,6 +13259,7 @@ nsDocShell::OnLinkClickSync(nsIContent *aContent,
|
||||
|
||||
nsresult rv = InternalLoad(clonedURI, // New URI
|
||||
referer, // Referer URI
|
||||
refererPolicy, // Referer policy
|
||||
aContent->NodePrincipal(), // Owner is our node's
|
||||
// principal
|
||||
flags,
|
||||
@ -13237,7 +13277,7 @@ nsDocShell::OnLinkClickSync(nsIContent *aContent,
|
||||
aDocShell, // DocShell out-param
|
||||
aRequest); // Request out-param
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
DispatchPings(aContent, aURI, referer);
|
||||
DispatchPings(aContent, aURI, referer, refererPolicy);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
@ -310,6 +310,7 @@ protected:
|
||||
virtual nsresult DoURILoad(nsIURI * aURI,
|
||||
nsIURI * aReferrer,
|
||||
bool aSendReferrer,
|
||||
uint32_t aReferrerPolicy,
|
||||
nsISupports * aOwner,
|
||||
const char * aTypeHint,
|
||||
const nsAString & aFileName,
|
||||
@ -358,6 +359,7 @@ protected:
|
||||
bool aCloneSHChildren);
|
||||
|
||||
virtual void SetReferrerURI(nsIURI * aURI);
|
||||
virtual void SetReferrerPolicy(uint32_t referrerPolicy);
|
||||
|
||||
// Session History
|
||||
virtual bool ShouldAddToSessionHistory(nsIURI * aURI);
|
||||
@ -752,6 +754,7 @@ protected:
|
||||
// mCurrentURI should be marked immutable on set if possible.
|
||||
nsCOMPtr<nsIURI> mCurrentURI;
|
||||
nsCOMPtr<nsIURI> mReferrerURI;
|
||||
uint32_t mReferrerPolicy;
|
||||
nsRefPtr<nsGlobalWindow> mScriptGlobal;
|
||||
nsCOMPtr<nsISHistory> mSessionHistory;
|
||||
nsCOMPtr<nsIGlobalHistory2> mGlobalHistory;
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "mozilla/net/ReferrerPolicy.h"
|
||||
|
||||
//*****************************************************************************
|
||||
//*** nsDocShellLoadInfo: Object Management
|
||||
@ -19,6 +20,7 @@ nsDocShellLoadInfo::nsDocShellLoadInfo()
|
||||
: mInheritOwner(false),
|
||||
mOwnerIsExplicit(false),
|
||||
mSendReferrer(true),
|
||||
mReferrerPolicy(mozilla::net::RP_Default),
|
||||
mLoadType(nsIDocShellLoadInfo::loadNormal),
|
||||
mIsSrcdocLoad(false)
|
||||
{
|
||||
@ -192,6 +194,18 @@ NS_IMETHODIMP nsDocShellLoadInfo::SetSendReferrer(bool aSendReferrer)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDocShellLoadInfo::GetReferrerPolicy(nsDocShellInfoReferrerPolicy* aReferrerPolicy)
|
||||
{
|
||||
*aReferrerPolicy = mReferrerPolicy;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDocShellLoadInfo::SetReferrerPolicy(nsDocShellInfoReferrerPolicy aReferrerPolicy)
|
||||
{
|
||||
mReferrerPolicy = aReferrerPolicy;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDocShellLoadInfo::GetIsSrcdocLoad(bool* aIsSrcdocLoad)
|
||||
{
|
||||
*aIsSrcdocLoad = mIsSrcdocLoad;
|
||||
|
@ -37,6 +37,7 @@ protected:
|
||||
bool mInheritOwner;
|
||||
bool mOwnerIsExplicit;
|
||||
bool mSendReferrer;
|
||||
nsDocShellInfoReferrerPolicy mReferrerPolicy;
|
||||
nsDocShellInfoLoadType mLoadType;
|
||||
nsCOMPtr<nsISHEntry> mSHEntry;
|
||||
nsString mTarget;
|
||||
|
@ -54,7 +54,7 @@ interface nsITabParent;
|
||||
|
||||
typedef unsigned long nsLoadFlags;
|
||||
|
||||
[scriptable, builtinclass, uuid(4e3de242-0b2a-4cf0-81b5-a5fe8628431c)]
|
||||
[scriptable, builtinclass, uuid(c2756385-bc54-417b-9ae4-c5a40053a2a3)]
|
||||
interface nsIDocShell : nsIDocShellTreeItem
|
||||
{
|
||||
/**
|
||||
@ -132,6 +132,7 @@ interface nsIDocShell : nsIDocShellTreeItem
|
||||
*
|
||||
* @param aURI - The URI to load.
|
||||
* @param aReferrer - Referring URI
|
||||
* @param aReferrerPolicy - Referrer policy
|
||||
* @param aOwner - Owner (security principal)
|
||||
* @param aInheritOwner - Flag indicating whether the owner of the current
|
||||
* document should be inherited if aOwner is null.
|
||||
@ -157,6 +158,7 @@ interface nsIDocShell : nsIDocShellTreeItem
|
||||
*/
|
||||
[noscript]void internalLoad(in nsIURI aURI,
|
||||
in nsIURI aReferrer,
|
||||
in unsigned long aReferrerPolicy,
|
||||
in nsISupports aOwner,
|
||||
in uint32_t aFlags,
|
||||
in wstring aWindowTarget,
|
||||
|
@ -17,8 +17,9 @@ interface nsISHEntry;
|
||||
interface nsIDocShell;
|
||||
|
||||
typedef long nsDocShellInfoLoadType;
|
||||
typedef unsigned long nsDocShellInfoReferrerPolicy;
|
||||
|
||||
[scriptable, uuid(c8d3b1e1-565a-427e-9d68-b109910ce9b7)]
|
||||
[scriptable, uuid(c63e9d64-490d-48bf-8013-b5d8ee4dbc25)]
|
||||
interface nsIDocShellLoadInfo : nsISupports
|
||||
{
|
||||
/** This is the referrer for the load. */
|
||||
@ -85,6 +86,11 @@ interface nsIDocShellLoadInfo : nsISupports
|
||||
*/
|
||||
attribute boolean sendReferrer;
|
||||
|
||||
/** Referrer policy for the load. This attribute holds one of
|
||||
* the values (REFERRER_POLICY_*) defined in nsIHttpChannel.
|
||||
*/
|
||||
attribute nsDocShellInfoReferrerPolicy referrerPolicy;
|
||||
|
||||
/** True if the docshell has been created to load an iframe where the
|
||||
* srcdoc attribute has been set. Set when srcdocData is specified.
|
||||
*/
|
||||
|
@ -30,7 +30,7 @@ class nsSHEntryShared;
|
||||
[ptr] native nsDocShellEditorDataPtr(nsDocShellEditorData);
|
||||
[ptr] native nsSHEntryShared(nsSHEntryShared);
|
||||
|
||||
[scriptable, uuid(9eed7e92-1121-46f2-95e5-2f5c0dca46f0)]
|
||||
[scriptable, uuid(d5fbeb10-f373-4677-b69a-2694aa706cac)]
|
||||
interface nsISHEntry : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -64,6 +64,11 @@ interface nsISHEntry : nsISupports
|
||||
/** Referrer URI */
|
||||
attribute nsIURI referrerURI;
|
||||
|
||||
/** Referrer policy, holding one of the values (REFERRER_POLICY_*)
|
||||
* defined in nsIHttpChannel.
|
||||
*/
|
||||
attribute unsigned long referrerPolicy;
|
||||
|
||||
/** Content viewer, for fast restoration of presentation */
|
||||
attribute nsIContentViewer contentViewer;
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "nsIStructuredCloneContainer.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIURI.h"
|
||||
#include "mozilla/net/ReferrerPolicy.h"
|
||||
#include <algorithm>
|
||||
|
||||
namespace dom = mozilla::dom;
|
||||
@ -27,7 +28,8 @@ static uint32_t gEntryID = 0;
|
||||
|
||||
|
||||
nsSHEntry::nsSHEntry()
|
||||
: mLoadType(0)
|
||||
: mReferrerPolicy(mozilla::net::RP_Default)
|
||||
, mLoadType(0)
|
||||
, mID(gEntryID++)
|
||||
, mScrollPositionX(0)
|
||||
, mScrollPositionY(0)
|
||||
@ -42,6 +44,7 @@ nsSHEntry::nsSHEntry(const nsSHEntry &other)
|
||||
: mShared(other.mShared)
|
||||
, mURI(other.mURI)
|
||||
, mReferrerURI(other.mReferrerURI)
|
||||
, mReferrerPolicy(other.mReferrerPolicy)
|
||||
, mTitle(other.mTitle)
|
||||
, mPostData(other.mPostData)
|
||||
, mLoadType(0) // XXX why not copy?
|
||||
@ -134,6 +137,18 @@ NS_IMETHODIMP nsSHEntry::SetReferrerURI(nsIURI *aReferrerURI)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsSHEntry::GetReferrerPolicy(uint32_t *aReferrerPolicy)
|
||||
{
|
||||
*aReferrerPolicy = mReferrerPolicy;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsSHEntry::SetReferrerPolicy(uint32_t aReferrerPolicy)
|
||||
{
|
||||
mReferrerPolicy = aReferrerPolicy;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::SetContentViewer(nsIContentViewer *aViewer)
|
||||
{
|
||||
|
@ -50,6 +50,7 @@ private:
|
||||
// See nsSHEntry.idl for comments on these members.
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
nsCOMPtr<nsIURI> mReferrerURI;
|
||||
uint32_t mReferrerPolicy;
|
||||
nsString mTitle;
|
||||
nsCOMPtr<nsIInputStream> mPostData;
|
||||
uint32_t mLoadType;
|
||||
|
@ -1539,6 +1539,8 @@ static already_AddRefed<mozilla::dom::NodeInfo> nullNodeInfo;
|
||||
// ==================================================================
|
||||
nsIDocument::nsIDocument()
|
||||
: nsINode(nullNodeInfo),
|
||||
mReferrerPolicySet(false),
|
||||
mReferrerPolicy(mozilla::net::RP_Default),
|
||||
mCharacterSet(NS_LITERAL_CSTRING("ISO-8859-1")),
|
||||
mNodeInfoManager(nullptr),
|
||||
mCompatMode(eCompatibility_FullStandards),
|
||||
@ -3701,6 +3703,20 @@ nsDocument::SetHeaderData(nsIAtom* aHeaderField, const nsAString& aData)
|
||||
aHeaderField == nsGkAtoms::viewport_user_scalable) {
|
||||
mViewportType = Unknown;
|
||||
}
|
||||
|
||||
// Referrer policy spec says to ignore any empty referrer policies.
|
||||
if (aHeaderField == nsGkAtoms::referrer && !aData.IsEmpty()) {
|
||||
ReferrerPolicy policy = mozilla::net::ReferrerPolicyFromString(aData);
|
||||
|
||||
// Referrer policy spec (section 6.1) says that once the referrer policy
|
||||
// is set, any future attempts to change it result in No-Referrer.
|
||||
if (!mReferrerPolicySet) {
|
||||
mReferrerPolicy = policy;
|
||||
mReferrerPolicySet = true;
|
||||
} else if (mReferrerPolicy != policy) {
|
||||
mReferrerPolicy = mozilla::net::RP_No_Referrer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -120,6 +120,7 @@ class nsIdentifierMapEntry : public nsStringHashKey
|
||||
{
|
||||
public:
|
||||
typedef mozilla::dom::Element Element;
|
||||
typedef mozilla::net::ReferrerPolicy ReferrerPolicy;
|
||||
|
||||
explicit nsIdentifierMapEntry(const nsAString& aKey) :
|
||||
nsStringHashKey(&aKey), mNameContentList(nullptr)
|
||||
|
@ -432,6 +432,8 @@ nsFrameLoader::ReallyStartLoadingInternal()
|
||||
}
|
||||
}
|
||||
|
||||
loadInfo->SetReferrerPolicy(mOwnerContent->OwnerDoc()->GetReferrerPolicy());
|
||||
|
||||
// Default flags:
|
||||
int32_t flags = nsIWebNavigation::LOAD_FLAGS_NONE;
|
||||
|
||||
|
@ -582,6 +582,7 @@ GK_ATOM(menupopup, "menupopup")
|
||||
GK_ATOM(menuseparator, "menuseparator")
|
||||
GK_ATOM(message, "message")
|
||||
GK_ATOM(meta, "meta")
|
||||
GK_ATOM(referrer, "referrer")
|
||||
GK_ATOM(meter, "meter")
|
||||
GK_ATOM(method, "method")
|
||||
GK_ATOM(microdataProperties, "microdataProperties")
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "nsPIDOMWindow.h" // for use in inline functions
|
||||
#include "nsPropertyTable.h" // for member
|
||||
#include "nsTHashtable.h" // for member
|
||||
#include "mozilla/net/ReferrerPolicy.h" // for member
|
||||
#include "nsWeakReference.h"
|
||||
#include "mozilla/dom/DocumentBinding.h"
|
||||
#include "mozilla/WeakPtr.h"
|
||||
@ -169,6 +170,7 @@ class nsIDocument : public nsINode
|
||||
{
|
||||
typedef mozilla::dom::GlobalObject GlobalObject;
|
||||
public:
|
||||
typedef mozilla::net::ReferrerPolicy ReferrerPolicy;
|
||||
typedef mozilla::dom::Element Element;
|
||||
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IDOCUMENT_IID)
|
||||
@ -271,6 +273,15 @@ public:
|
||||
*/
|
||||
virtual void SetChromeXHRDocBaseURI(nsIURI* aURI) = 0;
|
||||
|
||||
/**
|
||||
* Return the referrer policy of the document. Return "default" if there's no
|
||||
* valid meta referrer tag found in the document.
|
||||
*/
|
||||
ReferrerPolicy GetReferrerPolicy() const
|
||||
{
|
||||
return mReferrerPolicy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the principal responsible for this document.
|
||||
*/
|
||||
@ -2468,6 +2479,9 @@ protected:
|
||||
|
||||
nsWeakPtr mDocumentLoadGroup;
|
||||
|
||||
bool mReferrerPolicySet;
|
||||
ReferrerPolicy mReferrerPolicy;
|
||||
|
||||
mozilla::WeakPtr<nsDocShell> mDocumentContainer;
|
||||
|
||||
nsCString mCharacterSet;
|
||||
|
@ -77,7 +77,21 @@ HTMLMetaElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsAutoString content;
|
||||
rv = GetContent(content);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsContentUtils::ProcessViewportInfo(aDocument, content);
|
||||
nsContentUtils::ProcessViewportInfo(aDocument, content);
|
||||
}
|
||||
if (aDocument &&
|
||||
AttrValueIs(kNameSpaceID_None, nsGkAtoms::name, nsGkAtoms::referrer, eIgnoreCase)) {
|
||||
nsAutoString content;
|
||||
rv = GetContent(content);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Referrer Policy spec requires a <meta name="referrer" tag to be in the
|
||||
// <head> element.
|
||||
Element* headElt = aDocument->GetHeadElement();
|
||||
if (headElt && nsContentUtils::ContentIsDescendantOf(this, headElt)) {
|
||||
content = nsContentUtils::TrimWhitespace<nsContentUtils::IsHTMLWhitespace>(content);
|
||||
aDocument->SetHeaderData(nsGkAtoms::referrer, content);
|
||||
}
|
||||
}
|
||||
CreateAndDispatchEvent(aDocument, NS_LITERAL_STRING("DOMMetaAdded"));
|
||||
return rv;
|
||||
|
61
netwerk/base/public/ReferrerPolicy.h
Normal file
61
netwerk/base/public/ReferrerPolicy.h
Normal file
@ -0,0 +1,61 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef ReferrerPolicy_h__
|
||||
#define ReferrerPolicy_h__
|
||||
|
||||
#include "nsStringGlue.h"
|
||||
#include "nsIHttpChannel.h"
|
||||
|
||||
namespace mozilla { namespace net {
|
||||
|
||||
enum ReferrerPolicy {
|
||||
/* spec tokens: never no-referrer */
|
||||
RP_No_Referrer = nsIHttpChannel::REFERRER_POLICY_NO_REFERRER,
|
||||
|
||||
/* spec tokens: origin */
|
||||
RP_Origin = nsIHttpChannel::REFERRER_POLICY_ORIGIN,
|
||||
|
||||
/* spec tokens: default no-referrer-when-downgrade */
|
||||
RP_No_Referrer_When_Downgrade = nsIHttpChannel::REFERRER_POLICY_NO_REFERRER_WHEN_DOWNGRADE,
|
||||
RP_Default = nsIHttpChannel::REFERRER_POLICY_NO_REFERRER_WHEN_DOWNGRADE,
|
||||
|
||||
/* spec tokens: origin-when-crossorigin */
|
||||
RP_Origin_When_Crossorigin = nsIHttpChannel::REFERRER_POLICY_ORIGIN_WHEN_XORIGIN,
|
||||
|
||||
/* spec tokens: always unsafe-url */
|
||||
RP_Unsafe_URL = nsIHttpChannel::REFERRER_POLICY_UNSAFE_URL
|
||||
};
|
||||
|
||||
inline ReferrerPolicy
|
||||
ReferrerPolicyFromString(const nsAString& content)
|
||||
{
|
||||
// This is implemented step by step as described in the Referrer Policy
|
||||
// specification, section 6.4 "Determine token's Policy".
|
||||
if (content.LowerCaseEqualsLiteral("never") ||
|
||||
content.LowerCaseEqualsLiteral("no-referrer")) {
|
||||
return RP_No_Referrer;
|
||||
}
|
||||
if (content.LowerCaseEqualsLiteral("origin")) {
|
||||
return RP_Origin;
|
||||
}
|
||||
if (content.LowerCaseEqualsLiteral("default") ||
|
||||
content.LowerCaseEqualsLiteral("no-referrer-when-downgrade")) {
|
||||
return RP_No_Referrer_When_Downgrade;
|
||||
}
|
||||
if (content.LowerCaseEqualsLiteral("origin-when-crossorigin")) {
|
||||
return RP_Origin_When_Crossorigin;
|
||||
}
|
||||
if (content.LowerCaseEqualsLiteral("always") ||
|
||||
content.LowerCaseEqualsLiteral("unsafe-url")) {
|
||||
return RP_Unsafe_URL;
|
||||
}
|
||||
// Spec says if none of the previous match, use No_Referrer.
|
||||
return RP_No_Referrer;
|
||||
|
||||
}
|
||||
|
||||
} } //namespace mozilla::net
|
||||
|
||||
#endif
|
@ -144,6 +144,10 @@ EXPORTS += [
|
||||
'nsURIHashKey.h',
|
||||
]
|
||||
|
||||
EXPORTS.mozilla.net += [
|
||||
'ReferrerPolicy.h',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
|
||||
EXPORTS += [
|
||||
'NetStatistics.h',
|
||||
|
@ -76,6 +76,7 @@ HttpBaseChannel::HttpBaseChannel()
|
||||
, mProxyResolveFlags(0)
|
||||
, mContentDispositionHint(UINT32_MAX)
|
||||
, mHttpHandler(gHttpHandler)
|
||||
, mReferrerPolicy(REFERRER_POLICY_NO_REFERRER_WHEN_DOWNGRADE)
|
||||
, mRedirectCount(0)
|
||||
, mForcePending(false)
|
||||
{
|
||||
@ -898,15 +899,38 @@ HttpBaseChannel::GetReferrer(nsIURI **referrer)
|
||||
|
||||
NS_IMETHODIMP
|
||||
HttpBaseChannel::SetReferrer(nsIURI *referrer)
|
||||
{
|
||||
return SetReferrerWithPolicy(referrer, REFERRER_POLICY_NO_REFERRER_WHEN_DOWNGRADE);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HttpBaseChannel::GetReferrerPolicy(uint32_t *referrerPolicy)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(referrerPolicy);
|
||||
*referrerPolicy = mReferrerPolicy;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HttpBaseChannel::SetReferrerWithPolicy(nsIURI *referrer,
|
||||
uint32_t referrerPolicy)
|
||||
{
|
||||
ENSURE_CALLED_BEFORE_CONNECT();
|
||||
|
||||
// clear existing referrer, if any
|
||||
mReferrer = nullptr;
|
||||
mRequestHead.ClearHeader(nsHttp::Referer);
|
||||
mReferrerPolicy = REFERRER_POLICY_NO_REFERRER_WHEN_DOWNGRADE;
|
||||
|
||||
if (!referrer)
|
||||
return NS_OK;
|
||||
if (!referrer) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Don't send referrer at all when the meta referrer setting is "no-referrer"
|
||||
if (referrerPolicy == REFERRER_POLICY_NO_REFERRER) {
|
||||
mReferrerPolicy = REFERRER_POLICY_NO_REFERRER;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// 0: never send referer
|
||||
// 1: send referer for direct user action
|
||||
@ -929,12 +953,14 @@ HttpBaseChannel::SetReferrer(nsIURI *referrer)
|
||||
|
||||
// check referrer blocking pref
|
||||
uint32_t referrerLevel;
|
||||
if (mLoadFlags & LOAD_INITIAL_DOCUMENT_URI)
|
||||
if (mLoadFlags & LOAD_INITIAL_DOCUMENT_URI) {
|
||||
referrerLevel = 1; // user action
|
||||
else
|
||||
} else {
|
||||
referrerLevel = 2; // inline content
|
||||
if (userReferrerLevel < referrerLevel)
|
||||
}
|
||||
if (userReferrerLevel < referrerLevel) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> referrerGrip;
|
||||
nsresult rv;
|
||||
@ -992,8 +1018,7 @@ HttpBaseChannel::SetReferrer(nsIURI *referrer)
|
||||
rv = referrer->SchemeIs(*scheme, &match);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
if (!match)
|
||||
return NS_OK; // kick out....
|
||||
if (!match) return NS_OK; // kick out....
|
||||
|
||||
//
|
||||
// Handle secure referrals.
|
||||
@ -1003,28 +1028,52 @@ HttpBaseChannel::SetReferrer(nsIURI *referrer)
|
||||
//
|
||||
rv = referrer->SchemeIs("https", &match);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (match) {
|
||||
rv = mURI->SchemeIs("https", &match);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (!match)
|
||||
return NS_OK;
|
||||
|
||||
if (!gHttpHandler->SendSecureXSiteReferrer()) {
|
||||
nsAutoCString referrerHost;
|
||||
nsAutoCString host;
|
||||
// It's ok to send referrer for https-to-http scenarios if the referrer
|
||||
// policy is "unsafe-url" or "origin".
|
||||
if (referrerPolicy != REFERRER_POLICY_UNSAFE_URL &&
|
||||
referrerPolicy != REFERRER_POLICY_ORIGIN) {
|
||||
|
||||
rv = referrer->GetAsciiHost(referrerHost);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
// in other referrer policies, https->http is not allowed...
|
||||
if (!match) return NS_OK;
|
||||
|
||||
rv = mURI->GetAsciiHost(host);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
// ...and https->https is possibly only allowed if the hosts match.
|
||||
if (!gHttpHandler->SendSecureXSiteReferrer()) {
|
||||
nsAutoCString referrerHost;
|
||||
nsAutoCString host;
|
||||
|
||||
// GetAsciiHost returns lowercase hostname.
|
||||
if (!referrerHost.Equals(host))
|
||||
return NS_OK;
|
||||
rv = referrer->GetAsciiHost(referrerHost);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = mURI->GetAsciiHost(host);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// GetAsciiHost returns lowercase hostname.
|
||||
if (!referrerHost.Equals(host))
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// for cross-origin-based referrer changes (not just host-based), figure out
|
||||
// if the referrer is being sent cross-origin.
|
||||
nsCOMPtr<nsIURI> loadingURI;
|
||||
bool isCrossOrigin = true;
|
||||
if (mLoadInfo) {
|
||||
mLoadInfo->LoadingPrincipal()->GetURI(getter_AddRefs(loadingURI));
|
||||
}
|
||||
if (loadingURI) {
|
||||
nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
|
||||
rv = ssm->CheckSameOriginURI(loadingURI, mURI, false);
|
||||
isCrossOrigin = NS_FAILED(rv);
|
||||
} else {
|
||||
NS_WARNING("no loading principal available via loadInfo, assumming load is cross-origin");
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> clone;
|
||||
//
|
||||
// we need to clone the referrer, so we can:
|
||||
@ -1032,6 +1081,7 @@ HttpBaseChannel::SetReferrer(nsIURI *referrer)
|
||||
// (2) keep a reference to it after returning from this function
|
||||
//
|
||||
// Use CloneIgnoringRef to strip away any fragment per RFC 2616 section 14.36
|
||||
// and Referrer Policy section 6.3.5.
|
||||
rv = referrer->CloneIgnoringRef(getter_AddRefs(clone));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
@ -1077,11 +1127,22 @@ HttpBaseChannel::SetReferrer(nsIURI *referrer)
|
||||
}
|
||||
|
||||
// strip away any userpass; we don't want to be giving out passwords ;-)
|
||||
// This is required by Referrer Policy stripping algorithm.
|
||||
rv = clone->SetUserPass(EmptyCString());
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsAutoCString spec;
|
||||
|
||||
// site-specified referrer trimming may affect the trim level
|
||||
// "unsafe-url" behaves like "origin" (send referrer in the same situations) but
|
||||
// "unsafe-url" sends the whole referrer and origin removes the path.
|
||||
// "origin-when-cross-origin" trims the referrer only when the request is
|
||||
// cross-origin.
|
||||
if (referrerPolicy == REFERRER_POLICY_ORIGIN ||
|
||||
(isCrossOrigin && referrerPolicy == REFERRER_POLICY_ORIGIN_WHEN_XORIGIN)) {
|
||||
userReferrerTrimmingPolicy = 2;
|
||||
}
|
||||
|
||||
// check how much referer to send
|
||||
switch (userReferrerTrimmingPolicy) {
|
||||
|
||||
@ -1117,8 +1178,11 @@ HttpBaseChannel::SetReferrer(nsIURI *referrer)
|
||||
}
|
||||
|
||||
// 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;
|
||||
mRequestHead.SetHeader(nsHttp::Referer, spec);
|
||||
mReferrerPolicy = referrerPolicy;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -2071,7 +2135,7 @@ HttpBaseChannel::SetupReplacementChannel(nsIURI *newURI,
|
||||
}
|
||||
// convey the referrer if one was used for this channel to the next one
|
||||
if (mReferrer)
|
||||
httpChannel->SetReferrer(mReferrer);
|
||||
httpChannel->SetReferrerWithPolicy(mReferrer, mReferrerPolicy);
|
||||
// convey the mAllowPipelining and mAllowSTS flags
|
||||
httpChannel->SetAllowPipelining(mAllowPipelining);
|
||||
httpChannel->SetAllowSTS(mAllowSTS);
|
||||
|
@ -133,6 +133,8 @@ public:
|
||||
NS_IMETHOD SetRequestMethod(const nsACString& aMethod);
|
||||
NS_IMETHOD GetReferrer(nsIURI **referrer);
|
||||
NS_IMETHOD SetReferrer(nsIURI *referrer);
|
||||
NS_IMETHOD GetReferrerPolicy(uint32_t *referrerPolicy);
|
||||
NS_IMETHOD SetReferrerWithPolicy(nsIURI *referrer, uint32_t referrerPolicy);
|
||||
NS_IMETHOD GetRequestHeader(const nsACString& aHeader, nsACString& aValue);
|
||||
NS_IMETHOD SetRequestHeader(const nsACString& aHeader,
|
||||
const nsACString& aValue, bool aMerge);
|
||||
@ -383,6 +385,8 @@ protected:
|
||||
|
||||
nsRefPtr<nsHttpHandler> mHttpHandler; // keep gHttpHandler alive
|
||||
|
||||
uint32_t mReferrerPolicy;
|
||||
|
||||
// Performance tracking
|
||||
// The initiator type (for this resource) - how was the resource referenced in
|
||||
// the HTML file.
|
||||
|
@ -274,6 +274,7 @@ HttpChannelParent::DoAsyncOpen( const URIParams& aURI,
|
||||
mChannel->SetDocumentURI(docUri);
|
||||
if (referrerUri)
|
||||
mChannel->SetReferrerInternal(referrerUri);
|
||||
//TODO set referrer policy too (in patch 5)
|
||||
if (apiRedirectToUri)
|
||||
mChannel->RedirectTo(apiRedirectToUri);
|
||||
if (topWindowUri)
|
||||
|
@ -14,7 +14,7 @@ interface nsIHttpHeaderVisitor;
|
||||
* the inspection of the resulting HTTP response status and headers when they
|
||||
* become available.
|
||||
*/
|
||||
[scriptable, uuid(1bc753ad-5b88-454d-b4c0-4fd34cce6d96)]
|
||||
[scriptable, uuid(82083578-fb78-4f9a-953c-cecbae500697)]
|
||||
interface nsIHttpChannel : nsIChannel
|
||||
{
|
||||
/**************************************************************************
|
||||
@ -55,6 +55,33 @@ interface nsIHttpChannel : nsIChannel
|
||||
*/
|
||||
attribute nsIURI referrer;
|
||||
|
||||
/**
|
||||
* Referrer policies. See ReferrerPolicy.h for more details.
|
||||
*/
|
||||
|
||||
/* default state, doesn't send referrer from https->http */
|
||||
const unsigned long REFERRER_POLICY_NO_REFERRER_WHEN_DOWNGRADE = 0;
|
||||
/* sends no referrer */
|
||||
const unsigned long REFERRER_POLICY_NO_REFERRER = 1;
|
||||
/* only sends the origin of the referring URL */
|
||||
const unsigned long REFERRER_POLICY_ORIGIN = 2;
|
||||
/* same as default, but reduced to ORIGIN when cross-origin. */
|
||||
const unsigned long REFERRER_POLICY_ORIGIN_WHEN_XORIGIN = 3;
|
||||
/* always sends the referrer, even on downgrade. */
|
||||
const unsigned long REFERRER_POLICY_UNSAFE_URL = 4;
|
||||
|
||||
/**
|
||||
* Get the HTTP referrer policy. The policy is retrieved from the meta
|
||||
* referrer tag, which can be one of many values (see ReferrerPolicy.h for
|
||||
* more details).
|
||||
*/
|
||||
readonly attribute unsigned long referrerPolicy;
|
||||
|
||||
/**
|
||||
* Set the HTTP referrer URI with a referrer policy.
|
||||
*/
|
||||
void setReferrerWithPolicy(in nsIURI referrer, in unsigned long referrerPolicy);
|
||||
|
||||
/**
|
||||
* Get the value of a particular request header.
|
||||
*
|
||||
|
@ -607,6 +607,21 @@ nsViewSourceChannel::SetReferrer(nsIURI * aReferrer)
|
||||
mHttpChannel->SetReferrer(aReferrer);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsViewSourceChannel::GetReferrerPolicy(uint32_t *aReferrerPolicy)
|
||||
{
|
||||
return !mHttpChannel ? NS_ERROR_NULL_POINTER :
|
||||
mHttpChannel->GetReferrerPolicy(aReferrerPolicy);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsViewSourceChannel::SetReferrerWithPolicy(nsIURI * aReferrer,
|
||||
uint32_t aReferrerPolicy)
|
||||
{
|
||||
return !mHttpChannel ? NS_ERROR_NULL_POINTER :
|
||||
mHttpChannel->SetReferrerWithPolicy(aReferrer, aReferrerPolicy);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsViewSourceChannel::GetRequestHeader(const nsACString & aHeader,
|
||||
nsACString & aValue)
|
||||
|
@ -27,6 +27,9 @@ nsHtml5SpeculativeLoad::Perform(nsHtml5TreeOpExecutor* aExecutor)
|
||||
case eSpeculativeLoadBase:
|
||||
aExecutor->SetSpeculationBase(mUrl);
|
||||
break;
|
||||
case eSpeculativeLoadMetaReferrer:
|
||||
aExecutor->SetSpeculationReferrerPolicy(mMetaReferrerPolicy);
|
||||
break;
|
||||
case eSpeculativeLoadImage:
|
||||
aExecutor->PreloadImage(mUrl, mCrossOrigin);
|
||||
break;
|
||||
|
@ -6,6 +6,7 @@
|
||||
#define nsHtml5SpeculativeLoad_h
|
||||
|
||||
#include "nsString.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
||||
class nsHtml5TreeOpExecutor;
|
||||
|
||||
@ -14,6 +15,7 @@ enum eHtml5SpeculativeLoad {
|
||||
eSpeculativeLoadUninitialized,
|
||||
#endif
|
||||
eSpeculativeLoadBase,
|
||||
eSpeculativeLoadMetaReferrer,
|
||||
eSpeculativeLoadImage,
|
||||
eSpeculativeLoadScript,
|
||||
eSpeculativeLoadScriptFromHead,
|
||||
@ -35,6 +37,14 @@ class nsHtml5SpeculativeLoad {
|
||||
mUrl.Assign(aUrl);
|
||||
}
|
||||
|
||||
inline void InitMetaReferrerPolicy(const nsAString& aReferrerPolicy) {
|
||||
NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
|
||||
"Trying to reinitialize a speculative load!");
|
||||
mOpCode = eSpeculativeLoadMetaReferrer;
|
||||
mMetaReferrerPolicy.Assign(
|
||||
nsContentUtils::TrimWhitespace<nsContentUtils::IsHTMLWhitespace>(aReferrerPolicy));
|
||||
}
|
||||
|
||||
inline void InitImage(const nsAString& aUrl,
|
||||
const nsAString& aCrossOrigin)
|
||||
{
|
||||
@ -116,6 +126,7 @@ class nsHtml5SpeculativeLoad {
|
||||
private:
|
||||
eHtml5SpeculativeLoad mOpCode;
|
||||
nsString mUrl;
|
||||
nsString mMetaReferrerPolicy;
|
||||
/**
|
||||
* If mOpCode is eSpeculativeLoadStyle or eSpeculativeLoadScript[FromHead]
|
||||
* then this is the value of the "charset" attribute. For
|
||||
|
@ -189,6 +189,15 @@ nsHtml5TreeBuilder::createElement(int32_t aNamespace, nsIAtom* aName,
|
||||
if (url) {
|
||||
mSpeculativeLoadQueue.AppendElement()->InitBase(*url);
|
||||
}
|
||||
} else if (nsHtml5Atoms::meta == aName) {
|
||||
if (nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString(
|
||||
"referrer",
|
||||
aAttributes->getValue(nsHtml5AttributeName::ATTR_NAME))) {
|
||||
nsString* referrerPolicy = aAttributes->getValue(nsHtml5AttributeName::ATTR_CONTENT);
|
||||
if (referrerPolicy) {
|
||||
mSpeculativeLoadQueue.AppendElement()->InitMetaReferrerPolicy(*referrerPolicy);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case kNameSpaceID_SVG:
|
||||
|
@ -63,6 +63,8 @@ static nsITimer* gFlushTimer = nullptr;
|
||||
nsHtml5TreeOpExecutor::nsHtml5TreeOpExecutor()
|
||||
: nsHtml5DocumentBuilder(false)
|
||||
, mPreloadedURLs(23) // Mean # of preloadable resources per page on dmoz
|
||||
, mSpeculationReferrerPolicyWasSet(false)
|
||||
, mSpeculationReferrerPolicy(mozilla::net::RP_Default)
|
||||
{
|
||||
// zeroing operator new for everything else
|
||||
}
|
||||
@ -952,6 +954,27 @@ nsHtml5TreeOpExecutor::SetSpeculationBase(const nsAString& aURL)
|
||||
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Failed to create a URI");
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeOpExecutor::SetSpeculationReferrerPolicy(const nsAString& aReferrerPolicy)
|
||||
{
|
||||
ReferrerPolicy policy = mozilla::net::ReferrerPolicyFromString(aReferrerPolicy);
|
||||
|
||||
if (mSpeculationReferrerPolicyWasSet &&
|
||||
policy != mSpeculationReferrerPolicy) {
|
||||
// According to the Referrer Policy spec, if there's already been a policy
|
||||
// set and another attempt is made to set a _different_ policy, the result
|
||||
// is a "No Referrer" policy.
|
||||
mSpeculationReferrerPolicy = mozilla::net::RP_No_Referrer;
|
||||
}
|
||||
else {
|
||||
// Record "speculated" referrer policy locally and thread through the
|
||||
// speculation phase. The actual referrer policy will be set by
|
||||
// HTMLMetaElement::BindToTree().
|
||||
mSpeculationReferrerPolicyWasSet = true;
|
||||
mSpeculationReferrerPolicy = policy;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_NS_HTML5_TREE_OP_EXECUTOR_FLUSH
|
||||
uint32_t nsHtml5TreeOpExecutor::sAppendBatchMaxSize = 0;
|
||||
uint32_t nsHtml5TreeOpExecutor::sAppendBatchSlotsExamined = 0;
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "nsHashKeys.h"
|
||||
#include "mozilla/LinkedList.h"
|
||||
#include "nsHtml5DocumentBuilder.h"
|
||||
#include "mozilla/net/ReferrerPolicy.h"
|
||||
|
||||
class nsHtml5Parser;
|
||||
class nsHtml5TreeBuilder;
|
||||
@ -36,6 +37,7 @@ class nsHtml5TreeOpExecutor MOZ_FINAL : public nsHtml5DocumentBuilder,
|
||||
public mozilla::LinkedListElement<nsHtml5TreeOpExecutor>
|
||||
{
|
||||
friend class nsHtml5FlushLoopGuard;
|
||||
typedef mozilla::net::ReferrerPolicy ReferrerPolicy;
|
||||
|
||||
public:
|
||||
NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
|
||||
@ -67,6 +69,12 @@ class nsHtml5TreeOpExecutor MOZ_FINAL : public nsHtml5DocumentBuilder,
|
||||
|
||||
nsCOMPtr<nsIURI> mSpeculationBaseURI;
|
||||
|
||||
/**
|
||||
* Need to keep track of whether the referrer policy was already set.
|
||||
*/
|
||||
bool mSpeculationReferrerPolicyWasSet;
|
||||
ReferrerPolicy mSpeculationReferrerPolicy;
|
||||
|
||||
nsCOMPtr<nsIURI> mViewSourceBaseURI;
|
||||
|
||||
/**
|
||||
@ -257,6 +265,8 @@ class nsHtml5TreeOpExecutor MOZ_FINAL : public nsHtml5DocumentBuilder,
|
||||
void PreloadImage(const nsAString& aURL, const nsAString& aCrossOrigin);
|
||||
|
||||
void SetSpeculationBase(const nsAString& aURL);
|
||||
|
||||
void SetSpeculationReferrerPolicy(const nsAString& aReferrerPolicy);
|
||||
|
||||
void AddBase(const nsAString& aURL);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user