Bug 1615967 - Move customUserAgent to BrowsingContext. r=nika,remote-protocol-reviewers

Differential Revision: https://phabricator.services.mozilla.com/D63040

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Matt Woodrow 2020-02-24 02:15:03 +00:00
Родитель 843a0e51f0
Коммит f5dd8136c6
18 изменённых файлов: 88 добавлений и 81 удалений

Просмотреть файл

@ -140,6 +140,10 @@ CustomizedReload.prototype = {
.getInterface(Ci.nsIWebNavigation); .getInterface(Ci.nsIWebNavigation);
}, },
get browsingContext() {
return this.docShell.browsingContext;
},
start() { start() {
if (!this.waitForReloadCompleted) { if (!this.waitForReloadCompleted) {
this.waitForReloadCompleted = new Promise((resolve, reject) => { this.waitForReloadCompleted = new Promise((resolve, reject) => {
@ -147,7 +151,7 @@ CustomizedReload.prototype = {
this.rejectReloadCompleted = reject; this.rejectReloadCompleted = reject;
if (this.userAgent) { if (this.userAgent) {
this.docShell.customUserAgent = this.userAgent; this.browsingContext.customUserAgent = this.userAgent;
} }
let reloadFlags = Ci.nsIWebNavigation.LOAD_FLAGS_NONE; let reloadFlags = Ci.nsIWebNavigation.LOAD_FLAGS_NONE;
@ -265,8 +269,11 @@ CustomizedReload.prototype = {
} }
// Reset the customized user agent. // Reset the customized user agent.
if (this.userAgent && this.docShell.customUserAgent == this.userAgent) { if (
this.docShell.customUserAgent = null; this.userAgent &&
this.browsingContext.customUserAgent == this.userAgent
) {
this.browsingContext.customUserAgent = null;
} }
if (error) { if (error) {

Просмотреть файл

@ -316,12 +316,12 @@ const ResponsiveActor = protocol.ActorClassWithSpec(responsiveSpec, {
if (this._previousUserAgentOverride === undefined) { if (this._previousUserAgentOverride === undefined) {
this._previousUserAgentOverride = this.getUserAgentOverride(); this._previousUserAgentOverride = this.getUserAgentOverride();
} }
this.docShell.customUserAgent = userAgent; this.docShell.browsingContext.customUserAgent = userAgent;
return true; return true;
}, },
getUserAgentOverride() { getUserAgentOverride() {
return this.docShell.customUserAgent; return this.docShell.browsingContext.customUserAgent;
}, },
clearUserAgentOverride() { clearUserAgentOverride() {

Просмотреть файл

@ -1346,6 +1346,45 @@ void BrowsingContext::DidSet(FieldIndex<IDX_Muted>) {
}); });
} }
void BrowsingContext::SetCustomUserAgent(const nsAString& aUserAgent) {
Top()->SetUserAgentOverride(aUserAgent);
}
void BrowsingContext::DidSet(FieldIndex<IDX_UserAgentOverride>) {
MOZ_ASSERT(IsTop());
PreOrderWalk([&](BrowsingContext* aContext) {
nsIDocShell* shell = aContext->GetDocShell();
if (shell) {
shell->ClearCachedUserAgent();
}
});
}
bool BrowsingContext::CanSet(FieldIndex<IDX_UserAgentOverride>,
const nsString& aUserAgent,
ContentParent* aSource) {
if (!IsTop()) {
return false;
}
if (aSource) {
MOZ_ASSERT(XRE_IsParentProcess());
// Double-check ownership if we aren't the setter.
if (!Canonical()->IsOwnedByProcess(aSource->ChildID()) &&
aSource->ChildID() != Canonical()->GetInFlightProcessId()) {
return false;
}
} else if (!IsInProcess() && !XRE_IsParentProcess()) {
// Don't allow this to be set from content processes that
// don't own the BrowsingContext.
return false;
}
return true;
}
bool BrowsingContext::CanSet(FieldIndex<IDX_EmbedderInnerWindowId>, bool BrowsingContext::CanSet(FieldIndex<IDX_EmbedderInnerWindowId>,
const uint64_t& aValue, ContentParent* aSource) { const uint64_t& aValue, ContentParent* aSource) {
// Generally allow clearing this. We may want to be more precise about this // Generally allow clearing this. We may want to be more precise about this

Просмотреть файл

@ -107,7 +107,8 @@ class WindowProxyHolder;
FIELD(GVInaudibleAutoplayRequestStatus, GVAutoplayRequestStatus) \ FIELD(GVInaudibleAutoplayRequestStatus, GVAutoplayRequestStatus) \
/* ScreenOrientation-related APIs */ \ /* ScreenOrientation-related APIs */ \
FIELD(CurrentOrientationAngle, float) \ FIELD(CurrentOrientationAngle, float) \
FIELD(CurrentOrientationType, mozilla::dom::OrientationType) FIELD(CurrentOrientationType, mozilla::dom::OrientationType) \
FIELD(UserAgentOverride, nsString)
// BrowsingContext, in this context, is the cross process replicated // BrowsingContext, in this context, is the cross process replicated
// environment in which information about documents is stored. In // environment in which information about documents is stored. In
@ -466,6 +467,11 @@ class BrowsingContext : public nsISupports, public nsWrapperCache {
const WindowPostMessageOptions& aOptions, const WindowPostMessageOptions& aOptions,
nsIPrincipal& aSubjectPrincipal, ErrorResult& aError); nsIPrincipal& aSubjectPrincipal, ErrorResult& aError);
void GetCustomUserAgent(nsString& aUserAgent) {
aUserAgent = Top()->GetUserAgentOverride();
}
void SetCustomUserAgent(const nsAString& aUserAgent);
JSObject* WrapObject(JSContext* aCx); JSObject* WrapObject(JSContext* aCx);
static JSObject* ReadStructuredClone(JSContext* aCx, static JSObject* ReadStructuredClone(JSContext* aCx,
@ -627,6 +633,10 @@ class BrowsingContext : public nsISupports, public nsWrapperCache {
void DidSet(FieldIndex<IDX_AncestorLoading>); void DidSet(FieldIndex<IDX_AncestorLoading>);
void DidSet(FieldIndex<IDX_UserAgentOverride>);
bool CanSet(FieldIndex<IDX_UserAgentOverride>, const nsString& aUserAgent,
ContentParent* aSource);
template <size_t I, typename T> template <size_t I, typename T>
bool CanSet(FieldIndex<I>, const T&, ContentParent*) { bool CanSet(FieldIndex<I>, const T&, ContentParent*) {
return true; return true;

Просмотреть файл

@ -2343,14 +2343,7 @@ nsDocShell::NameEquals(const nsAString& aName, bool* aResult) {
} }
NS_IMETHODIMP NS_IMETHODIMP
nsDocShell::GetCustomUserAgent(nsAString& aCustomUserAgent) { nsDocShell::ClearCachedUserAgent() {
aCustomUserAgent = mCustomUserAgent;
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::SetCustomUserAgent(const nsAString& aCustomUserAgent) {
mCustomUserAgent = aCustomUserAgent;
RefPtr<nsGlobalWindowInner> win = RefPtr<nsGlobalWindowInner> win =
mScriptGlobal ? mScriptGlobal->GetCurrentInnerWindowInternal() : nullptr; mScriptGlobal ? mScriptGlobal->GetCurrentInnerWindowInternal() : nullptr;
if (win) { if (win) {
@ -2360,13 +2353,6 @@ nsDocShell::SetCustomUserAgent(const nsAString& aCustomUserAgent) {
} }
} }
uint32_t childCount = mChildList.Length();
for (uint32_t i = 0; i < childCount; ++i) {
nsCOMPtr<nsIDocShell> childShell = do_QueryInterface(ChildAt(i));
if (childShell) {
childShell->SetCustomUserAgent(aCustomUserAgent);
}
}
return NS_OK; return NS_OK;
} }
@ -2628,7 +2614,6 @@ nsresult nsDocShell::SetDocLoaderParent(nsDocLoader* aParent) {
// If parent is another docshell, we inherit all their flags for // If parent is another docshell, we inherit all their flags for
// allowing plugins, scripting etc. // allowing plugins, scripting etc.
bool value; bool value;
nsString customUserAgent;
nsCOMPtr<nsIDocShell> parentAsDocShell(do_QueryInterface(parent)); nsCOMPtr<nsIDocShell> parentAsDocShell(do_QueryInterface(parent));
if (parentAsDocShell) { if (parentAsDocShell) {
@ -2663,10 +2648,6 @@ nsresult nsDocShell::SetDocLoaderParent(nsDocLoader* aParent) {
if (NS_SUCCEEDED(parentAsDocShell->GetIsActive(&value))) { if (NS_SUCCEEDED(parentAsDocShell->GetIsActive(&value))) {
SetIsActive(value); SetIsActive(value);
} }
if (NS_SUCCEEDED(parentAsDocShell->GetCustomUserAgent(customUserAgent)) &&
!customUserAgent.IsEmpty()) {
SetCustomUserAgent(customUserAgent);
}
if (NS_FAILED(parentAsDocShell->GetAllowDNSPrefetch(&value))) { if (NS_FAILED(parentAsDocShell->GetAllowDNSPrefetch(&value))) {
value = false; value = false;
} }

Просмотреть файл

@ -1093,7 +1093,6 @@ class nsDocShell final : public nsDocLoader,
nsID mHistoryID; nsID mHistoryID;
nsString mTitle; nsString mTitle;
nsString mCustomUserAgent;
nsCString mOriginalUriString; nsCString mOriginalUriString;
nsWeakPtr mOpener; nsWeakPtr mOpener;
nsTObserverArray<nsWeakPtr> mPrivacyObservers; nsTObserverArray<nsWeakPtr> mPrivacyObservers;

Просмотреть файл

@ -178,11 +178,6 @@ interface nsIDocShell : nsIDocShellTreeItem
*/ */
attribute EventTarget chromeEventHandler; attribute EventTarget chromeEventHandler;
/**
* This allows chrome to set a custom User agent on a specific docshell
*/
attribute AString customUserAgent;
/** /**
* Whether CSS error reporting is enabled. * Whether CSS error reporting is enabled.
*/ */
@ -408,6 +403,8 @@ interface nsIDocShell : nsIDocShellTreeItem
*/ */
void finishRestore(); void finishRestore();
void clearCachedUserAgent();
/* Track whether we're currently restoring a document presentation. */ /* Track whether we're currently restoring a document presentation. */
readonly attribute boolean restoringDocument; readonly attribute boolean restoringDocument;

Просмотреть файл

@ -9,12 +9,12 @@ const URL = "data:text/html;charset=utf-8,<iframe id='test-iframe'></iframe>";
async function contentTask() { async function contentTask() {
let docshell = docShell; let docshell = docShell;
is( is(
docshell.customUserAgent, docshell.browsingContext.customUserAgent,
"", "",
"There should initially be no customUserAgent" "There should initially be no customUserAgent"
); );
docshell.customUserAgent = "foo"; docshell.browsingContext.customUserAgent = "foo";
is( is(
content.navigator.userAgent, content.navigator.userAgent,
"foo", "foo",

Просмотреть файл

@ -254,7 +254,7 @@ void Navigator::GetUserAgent(nsAString& aUserAgent, CallerType aCallerType,
nsIDocShell* docshell = window->GetDocShell(); nsIDocShell* docshell = window->GetDocShell();
nsString customUserAgent; nsString customUserAgent;
if (docshell) { if (docshell) {
docshell->GetCustomUserAgent(customUserAgent); docshell->GetBrowsingContext()->GetCustomUserAgent(customUserAgent);
if (!customUserAgent.IsEmpty()) { if (!customUserAgent.IsEmpty()) {
aUserAgent = customUserAgent; aUserAgent = customUserAgent;

Просмотреть файл

@ -34,6 +34,8 @@ interface BrowsingContext {
readonly attribute WindowProxy? window; readonly attribute WindowProxy? window;
attribute [TreatNullAs=EmptyString] DOMString customUserAgent;
/** /**
* The sandbox flags on the browsing context. These reflect the value of the * The sandbox flags on the browsing context. These reflect the value of the
* sandbox attribute of the associated IFRAME or CSP-protectable content, if * sandbox attribute of the associated IFRAME or CSP-protectable content, if

Просмотреть файл

@ -98,7 +98,7 @@ class GeckoViewSettingsChild extends GeckoViewChildModule {
this._userAgentMode = aMode; this._userAgentMode = aMode;
const docShell = content && GeckoViewUtils.getRootDocShell(content); const docShell = content && GeckoViewUtils.getRootDocShell(content);
if (docShell) { if (docShell) {
docShell.customUserAgent = this.userAgent; docShell.browsingContext.customUserAgent = this.userAgent;
} else { } else {
warn`Failed to set custom user agent. Doc shell not found`; warn`Failed to set custom user agent. Doc shell not found`;
} }
@ -115,7 +115,7 @@ class GeckoViewSettingsChild extends GeckoViewChildModule {
this._userAgentOverride = aUserAgent; this._userAgentOverride = aUserAgent;
const docShell = content && GeckoViewUtils.getRootDocShell(content); const docShell = content && GeckoViewUtils.getRootDocShell(content);
if (docShell) { if (docShell) {
docShell.customUserAgent = this.userAgent; docShell.browsingContext.customUserAgent = this.userAgent;
} else { } else {
warn`Failed to set custom user agent. Doc shell not found`; warn`Failed to set custom user agent. Doc shell not found`;
} }

Просмотреть файл

@ -129,10 +129,6 @@ DocumentChannelChild::AsyncOpen(nsIStreamListener* aListener) {
if (mTiming) { if (mTiming) {
args.timing() = Some(mTiming); args.timing() = Some(mTiming);
} }
nsDocShell* docshell = GetDocShell();
if (docshell) {
docshell->GetCustomUserAgent(args.customUserAgent());
}
nsCOMPtr<nsIBrowserChild> iBrowserChild; nsCOMPtr<nsIBrowserChild> iBrowserChild;
NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup, NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup,

Просмотреть файл

@ -43,8 +43,8 @@ bool DocumentChannelParent::Init(BrowserParent* aBrowser,
aArgs.loadFlags(), aArgs.loadType(), aArgs.cacheKey(), aArgs.loadFlags(), aArgs.loadType(), aArgs.cacheKey(),
aArgs.isActive(), aArgs.isTopLevelDoc(), aArgs.isActive(), aArgs.isTopLevelDoc(),
aArgs.hasNonEmptySandboxingFlags(), aArgs.topWindowURI(), aArgs.hasNonEmptySandboxingFlags(), aArgs.topWindowURI(),
aArgs.contentBlockingAllowListPrincipal(), aArgs.customUserAgent(), aArgs.contentBlockingAllowListPrincipal(), aArgs.channelId(),
aArgs.channelId(), aArgs.asyncOpenTime(), aArgs.documentOpenFlags(), aArgs.asyncOpenTime(), aArgs.documentOpenFlags(),
aArgs.pluginsAllowed(), aArgs.timing().refOr(nullptr), &rv)) { aArgs.pluginsAllowed(), aArgs.timing().refOr(nullptr), &rv)) {
return SendFailedAsyncOpen(rv); return SendFailedAsyncOpen(rv);
} }

Просмотреть файл

@ -255,9 +255,9 @@ bool DocumentLoadListener::Open(
bool aIsActive, bool aIsTopLevelDoc, bool aHasNonEmptySandboxingFlags, bool aIsActive, bool aIsTopLevelDoc, bool aHasNonEmptySandboxingFlags,
const Maybe<URIParams>& aTopWindowURI, const Maybe<URIParams>& aTopWindowURI,
const Maybe<PrincipalInfo>& aContentBlockingAllowListPrincipal, const Maybe<PrincipalInfo>& aContentBlockingAllowListPrincipal,
const nsString& aCustomUserAgent, const uint64_t& aChannelId, const uint64_t& aChannelId, const TimeStamp& aAsyncOpenTime,
const TimeStamp& aAsyncOpenTime, const Maybe<uint32_t>& aDocumentOpenFlags, const Maybe<uint32_t>& aDocumentOpenFlags, bool aPluginsAllowed,
bool aPluginsAllowed, nsDOMNavigationTiming* aTiming, nsresult* aRv) { nsDOMNavigationTiming* aTiming, nsresult* aRv) {
LOG(("DocumentLoadListener Open [this=%p, uri=%s]", this, LOG(("DocumentLoadListener Open [this=%p, uri=%s]", this,
aLoadState->URI()->GetSpecOrDefault().get())); aLoadState->URI()->GetSpecOrDefault().get()));
@ -285,15 +285,6 @@ bool DocumentLoadListener::Open(
httpBaseChannel->SetContentBlockingAllowListPrincipal( httpBaseChannel->SetContentBlockingAllowListPrincipal(
contentBlockingAllowListPrincipal); contentBlockingAllowListPrincipal);
} }
// The content process docshell can specify a custom override
// for the user agent value. If we had one, then add it to
// the header now.
if (!aCustomUserAgent.IsEmpty()) {
NS_ConvertUTF16toUTF8 utf8CustomUserAgent(aCustomUserAgent);
*aRv = httpBaseChannel->SetRequestHeader(NS_LITERAL_CSTRING("User-Agent"),
utf8CustomUserAgent, false);
}
} }
nsCOMPtr<nsIPrivateBrowsingChannel> privateChannel = nsCOMPtr<nsIPrivateBrowsingChannel> privateChannel =

Просмотреть файл

@ -77,8 +77,7 @@ class DocumentLoadListener : public nsIInterfaceRequestor,
bool aHasNonEmptySandboxingFlags, bool aHasNonEmptySandboxingFlags,
const Maybe<ipc::URIParams>& aTopWindowURI, const Maybe<ipc::URIParams>& aTopWindowURI,
const Maybe<ipc::PrincipalInfo>& aContentBlockingAllowListPrincipal, const Maybe<ipc::PrincipalInfo>& aContentBlockingAllowListPrincipal,
const nsString& aCustomUserAgent, const uint64_t& aChannelId, const uint64_t& aChannelId, const TimeStamp& aAsyncOpenTime,
const TimeStamp& aAsyncOpenTime,
const Maybe<uint32_t>& aDocumentOpenFlags, bool aPluginsAllowed, const Maybe<uint32_t>& aDocumentOpenFlags, bool aPluginsAllowed,
nsDOMNavigationTiming* aTiming, nsresult* aRv); nsDOMNavigationTiming* aTiming, nsresult* aRv);

Просмотреть файл

@ -403,7 +403,6 @@ struct DocumentChannelCreationArgs {
PrincipalInfo? contentBlockingAllowListPrincipal; PrincipalInfo? contentBlockingAllowListPrincipal;
TimeStamp asyncOpenTime; TimeStamp asyncOpenTime;
nsString? initiatorType; nsString? initiatorType;
nsString customUserAgent;
uint64_t channelId; uint64_t channelId;
uint32_t loadFlags; uint32_t loadFlags;
uint32_t loadType; uint32_t loadType;

Просмотреть файл

@ -25,6 +25,7 @@
#include "mozilla/Services.h" #include "mozilla/Services.h"
#include "mozilla/Telemetry.h" #include "mozilla/Telemetry.h"
#include "mozilla/Tokenizer.h" #include "mozilla/Tokenizer.h"
#include "mozilla/dom/BrowsingContext.h"
#include "mozilla/dom/Performance.h" #include "mozilla/dom/Performance.h"
#include "mozilla/dom/PerformanceStorage.h" #include "mozilla/dom/PerformanceStorage.h"
#include "mozilla/net/PartiallySeekableInputStream.h" #include "mozilla/net/PartiallySeekableInputStream.h"
@ -42,6 +43,7 @@
#include "nsICachingChannel.h" #include "nsICachingChannel.h"
#include "nsIChannelEventSink.h" #include "nsIChannelEventSink.h"
#include "nsIConsoleService.h" #include "nsIConsoleService.h"
#include "nsIContentPolicy.h"
#include "nsICookieService.h" #include "nsICookieService.h"
#include "nsIDOMWindowUtils.h" #include "nsIDOMWindowUtils.h"
#include "nsIDocShell.h" #include "nsIDocShell.h"
@ -485,35 +487,20 @@ HttpBaseChannel::SetTRRMode(nsIRequest::TRRMode aTRRMode) {
NS_IMETHODIMP NS_IMETHODIMP
HttpBaseChannel::SetDocshellUserAgentOverride() { HttpBaseChannel::SetDocshellUserAgentOverride() {
// This sets the docshell specific user agent override RefPtr<dom::BrowsingContext> bc;
nsresult rv; MOZ_ALWAYS_SUCCEEDS(mLoadInfo->GetBrowsingContext(getter_AddRefs(bc)));
nsCOMPtr<nsILoadContext> loadContext; if (!bc) {
NS_QueryNotificationCallbacks(this, loadContext);
if (!loadContext) {
return NS_OK; return NS_OK;
} }
nsCOMPtr<mozIDOMWindowProxy> domWindow; const nsString& customUserAgent = bc->GetUserAgentOverride();
loadContext->GetAssociatedWindow(getter_AddRefs(domWindow)); if (customUserAgent.IsEmpty() || customUserAgent.IsVoid()) {
if (!domWindow) {
return NS_OK;
}
auto* pDomWindow = nsPIDOMWindowOuter::From(domWindow);
nsIDocShell* docshell = pDomWindow->GetDocShell();
if (!docshell) {
return NS_OK;
}
nsString customUserAgent;
docshell->GetCustomUserAgent(customUserAgent);
if (customUserAgent.IsEmpty()) {
return NS_OK; return NS_OK;
} }
NS_ConvertUTF16toUTF8 utf8CustomUserAgent(customUserAgent); NS_ConvertUTF16toUTF8 utf8CustomUserAgent(customUserAgent);
rv = SetRequestHeader(NS_LITERAL_CSTRING("User-Agent"), utf8CustomUserAgent, nsresult rv = SetRequestHeader(NS_LITERAL_CSTRING("User-Agent"),
false); utf8CustomUserAgent, false);
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
return NS_OK; return NS_OK;

Просмотреть файл

@ -43,7 +43,7 @@ class Emulation extends ContentProcessDomain {
} }
_setCustomUserAgent(userAgent) { _setCustomUserAgent(userAgent) {
this.docShell.customUserAgent = userAgent; this.docShell.browsingContext.customUserAgent = userAgent;
} }
_setDPPXOverride(dppx) { _setDPPXOverride(dppx) {