зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1575744 - P2. Add nsIProcessSwitchRequestor interface. r=mayhemer,nika
Will allow for SessionStore.jsm process switching to be used by other objects than nsHttpChannel. Differential Revision: https://phabricator.services.mozilla.com/D46015 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
02d8a3d841
Коммит
db9dcef811
|
@ -2606,8 +2606,8 @@ var SessionStoreInternal = {
|
||||||
},
|
},
|
||||||
|
|
||||||
// Examine the channel response to see if we should change the process
|
// Examine the channel response to see if we should change the process
|
||||||
// performing the given load.
|
// performing the given load. aRequestor implements nsIProcessSwitchRequestor
|
||||||
onMayChangeProcess(aChannel) {
|
onMayChangeProcess(aRequestor) {
|
||||||
if (
|
if (
|
||||||
!E10SUtils.useHttpResponseProcessSelection() &&
|
!E10SUtils.useHttpResponseProcessSelection() &&
|
||||||
!E10SUtils.useCrossOriginOpenerPolicy()
|
!E10SUtils.useCrossOriginOpenerPolicy()
|
||||||
|
@ -2615,19 +2615,26 @@ var SessionStoreInternal = {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
aChannel.QueryInterface(Ci.nsIHttpChannel);
|
let switchRequestor;
|
||||||
|
try {
|
||||||
|
switchRequestor = aRequestor.QueryInterface(Ci.nsIProcessSwitchRequestor);
|
||||||
|
} catch (e) {
|
||||||
|
debug(`[process-switch]: object not compatible with process switching `);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!aChannel.isDocument || !aChannel.loadInfo) {
|
const channel = switchRequestor.channel;
|
||||||
|
if (!channel.isDocument || !channel.loadInfo) {
|
||||||
return; // Not a document load.
|
return; // Not a document load.
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that the document has a corresponding BrowsingContext.
|
// Check that the document has a corresponding BrowsingContext.
|
||||||
let browsingContext;
|
let browsingContext;
|
||||||
let cp = aChannel.loadInfo.externalContentPolicyType;
|
let cp = channel.loadInfo.externalContentPolicyType;
|
||||||
if (cp == Ci.nsIContentPolicy.TYPE_DOCUMENT) {
|
if (cp == Ci.nsIContentPolicy.TYPE_DOCUMENT) {
|
||||||
browsingContext = aChannel.loadInfo.browsingContext;
|
browsingContext = channel.loadInfo.browsingContext;
|
||||||
} else {
|
} else {
|
||||||
browsingContext = aChannel.loadInfo.frameBrowsingContext;
|
browsingContext = channel.loadInfo.frameBrowsingContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!browsingContext) {
|
if (!browsingContext) {
|
||||||
|
@ -2691,7 +2698,7 @@ var SessionStoreInternal = {
|
||||||
|
|
||||||
// Determine the process type the load should be performed in.
|
// Determine the process type the load should be performed in.
|
||||||
let resultPrincipal = Services.scriptSecurityManager.getChannelResultPrincipal(
|
let resultPrincipal = Services.scriptSecurityManager.getChannelResultPrincipal(
|
||||||
aChannel
|
channel
|
||||||
);
|
);
|
||||||
let remoteType = E10SUtils.getRemoteTypeForPrincipal(
|
let remoteType = E10SUtils.getRemoteTypeForPrincipal(
|
||||||
resultPrincipal,
|
resultPrincipal,
|
||||||
|
@ -2703,7 +2710,7 @@ var SessionStoreInternal = {
|
||||||
if (
|
if (
|
||||||
currentRemoteType == remoteType &&
|
currentRemoteType == remoteType &&
|
||||||
(!E10SUtils.useCrossOriginOpenerPolicy() ||
|
(!E10SUtils.useCrossOriginOpenerPolicy() ||
|
||||||
!aChannel.hasCrossOriginOpenerPolicyMismatch())
|
!switchRequestor.hasCrossOriginOpenerPolicyMismatch())
|
||||||
) {
|
) {
|
||||||
debug(`[process-switch]: type (${remoteType}) is compatible - ignoring`);
|
debug(`[process-switch]: type (${remoteType}) is compatible - ignoring`);
|
||||||
return;
|
return;
|
||||||
|
@ -2719,7 +2726,7 @@ var SessionStoreInternal = {
|
||||||
|
|
||||||
const isCOOPSwitch =
|
const isCOOPSwitch =
|
||||||
E10SUtils.useCrossOriginOpenerPolicy() &&
|
E10SUtils.useCrossOriginOpenerPolicy() &&
|
||||||
aChannel.hasCrossOriginOpenerPolicyMismatch();
|
switchRequestor.hasCrossOriginOpenerPolicyMismatch();
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
// DANGER ZONE: Perform a process switch into the new process. This is
|
// DANGER ZONE: Perform a process switch into the new process. This is
|
||||||
|
@ -2729,11 +2736,11 @@ var SessionStoreInternal = {
|
||||||
let tabPromise = this._doProcessSwitch(
|
let tabPromise = this._doProcessSwitch(
|
||||||
browsingContext,
|
browsingContext,
|
||||||
remoteType,
|
remoteType,
|
||||||
aChannel,
|
channel,
|
||||||
identifier,
|
identifier,
|
||||||
isCOOPSwitch
|
isCOOPSwitch
|
||||||
);
|
);
|
||||||
aChannel.switchProcessTo(tabPromise, identifier);
|
switchRequestor.switchProcessTo(tabPromise, identifier);
|
||||||
},
|
},
|
||||||
|
|
||||||
/* ........ nsISessionStore API .............. */
|
/* ........ nsISessionStore API .............. */
|
||||||
|
|
|
@ -37,3 +37,41 @@ interface nsICrossProcessSwitchChannel : nsISupports
|
||||||
*/
|
*/
|
||||||
void triggerCrossProcessSwitch(in nsIHttpChannel channel, in uint64_t identifier);
|
void triggerCrossProcessSwitch(in nsIHttpChannel channel, in uint64_t identifier);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The nsIProcessSwitchRequestor interface allows clients to instruct
|
||||||
|
* SessionStore.jsm that a channel setup has completed and a process switch
|
||||||
|
* may be required. This works alongside the on-may-change-process observer
|
||||||
|
* notification.
|
||||||
|
* This interface must be used only from the XPCOM main thread.
|
||||||
|
*/
|
||||||
|
[scriptable, uuid(fce8497b-c57c-4557-b360-3efefc83eff5)]
|
||||||
|
interface nsIProcessSwitchRequestor : nsISupports
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The underlying channel object that was intercepted and that could trigger
|
||||||
|
* a process.
|
||||||
|
*/
|
||||||
|
readonly attribute nsIChannel channel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instructs the callee to be loaded in a new process. Like 'redirectTo'
|
||||||
|
* this can only be used on channels that have not yet called their
|
||||||
|
* listener's OnStartRequest(). Can only be called during the
|
||||||
|
* http-on-may-change-process observer notification.
|
||||||
|
*
|
||||||
|
* @param aTabPromise a promise which resolves to a nsIRemotTab object
|
||||||
|
* which the load will proceed in.
|
||||||
|
* @param aIdentifier a 64-bit ID which will be provided to the
|
||||||
|
* ChildProcessChannelListener.
|
||||||
|
*/
|
||||||
|
[must_use] void switchProcessTo(in Promise aTabPromise,
|
||||||
|
in unsigned long long aIdentifier);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to determine if there is a Cross-Origin-Opener-Policy mismatch
|
||||||
|
* that would require switching the channel to another process.
|
||||||
|
* @throws NS_ERROR_NOT_AVAILABLE if we don't have a responseHead
|
||||||
|
*/
|
||||||
|
[must_use] boolean hasCrossOriginOpenerPolicyMismatch();
|
||||||
|
};
|
||||||
|
|
|
@ -1926,17 +1926,6 @@ HttpBaseChannel::RedirectTo(nsIURI* targetURI) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
HttpBaseChannel::SwitchProcessTo(mozilla::dom::Promise* aBrowserParent,
|
|
||||||
uint64_t aIdentifier) {
|
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
HttpBaseChannel::HasCrossOriginOpenerPolicyMismatch(bool* aMismatch) {
|
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
HttpBaseChannel::UpgradeToSecure() {
|
HttpBaseChannel::UpgradeToSecure() {
|
||||||
// Upgrades are handled internally between http-on-modify-request and
|
// Upgrades are handled internally between http-on-modify-request and
|
||||||
|
|
|
@ -219,9 +219,6 @@ class HttpBaseChannel : public nsHashPropertyBag,
|
||||||
NS_IMETHOD GetResponseStatusText(nsACString& aValue) override;
|
NS_IMETHOD GetResponseStatusText(nsACString& aValue) override;
|
||||||
NS_IMETHOD GetRequestSucceeded(bool* aValue) override;
|
NS_IMETHOD GetRequestSucceeded(bool* aValue) override;
|
||||||
NS_IMETHOD RedirectTo(nsIURI* newURI) override;
|
NS_IMETHOD RedirectTo(nsIURI* newURI) override;
|
||||||
NS_IMETHOD SwitchProcessTo(mozilla::dom::Promise* aBrowserParent,
|
|
||||||
uint64_t aIdentifier) override;
|
|
||||||
NS_IMETHOD HasCrossOriginOpenerPolicyMismatch(bool* aMismatch) override;
|
|
||||||
NS_IMETHOD UpgradeToSecure() override;
|
NS_IMETHOD UpgradeToSecure() override;
|
||||||
NS_IMETHOD GetRequestContextID(uint64_t* aRCID) override;
|
NS_IMETHOD GetRequestContextID(uint64_t* aRCID) override;
|
||||||
NS_IMETHOD GetTransferSize(uint64_t* aTransferSize) override;
|
NS_IMETHOD GetTransferSize(uint64_t* aTransferSize) override;
|
||||||
|
|
|
@ -273,17 +273,6 @@ NullHttpChannel::RedirectTo(nsIURI* aNewURI) {
|
||||||
return NS_ERROR_NOT_IMPLEMENTED;
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
NullHttpChannel::SwitchProcessTo(mozilla::dom::Promise* aBrowserParent,
|
|
||||||
uint64_t aIdentifier) {
|
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
NullHttpChannel::HasCrossOriginOpenerPolicyMismatch(bool* aMismatch) {
|
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
NullHttpChannel::UpgradeToSecure() { return NS_ERROR_NOT_IMPLEMENTED; }
|
NullHttpChannel::UpgradeToSecure() { return NS_ERROR_NOT_IMPLEMENTED; }
|
||||||
|
|
||||||
|
|
|
@ -6139,6 +6139,7 @@ NS_INTERFACE_MAP_BEGIN(nsHttpChannel)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
|
NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIChannelWithDivertableParentListener)
|
NS_INTERFACE_MAP_ENTRY(nsIChannelWithDivertableParentListener)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIRequestTailUnblockCallback)
|
NS_INTERFACE_MAP_ENTRY(nsIRequestTailUnblockCallback)
|
||||||
|
NS_INTERFACE_MAP_ENTRY(nsIProcessSwitchRequestor)
|
||||||
NS_INTERFACE_MAP_ENTRY_CONCRETE(nsHttpChannel)
|
NS_INTERFACE_MAP_ENTRY_CONCRETE(nsHttpChannel)
|
||||||
NS_INTERFACE_MAP_END_INHERITING(HttpBaseChannel)
|
NS_INTERFACE_MAP_END_INHERITING(HttpBaseChannel)
|
||||||
|
|
||||||
|
@ -7285,6 +7286,15 @@ class DomPromiseListener final : dom::PromiseNativeHandler {
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS0(DomPromiseListener)
|
NS_IMPL_ISUPPORTS0(DomPromiseListener)
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// nsHttpChannel::nsIProcessSwitchRequestor
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsHttpChannel::GetChannel(nsIChannel** aChannel) {
|
||||||
|
*aChannel = do_AddRef(this).take();
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP nsHttpChannel::SwitchProcessTo(
|
NS_IMETHODIMP nsHttpChannel::SwitchProcessTo(
|
||||||
dom::Promise* aContentProcessIdPromise, uint64_t aIdentifier) {
|
dom::Promise* aContentProcessIdPromise, uint64_t aIdentifier) {
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
@ -7310,6 +7320,19 @@ NS_IMETHODIMP nsHttpChannel::SwitchProcessTo(
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This method returns the cached result of running the Cross-Origin-Opener
|
||||||
|
// policy compare algorithm by calling ComputeCrossOriginOpenerPolicyMismatch
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsHttpChannel::HasCrossOriginOpenerPolicyMismatch(bool* aMismatch) {
|
||||||
|
MOZ_ASSERT(aMismatch);
|
||||||
|
if (!aMismatch) {
|
||||||
|
return NS_ERROR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
*aMismatch = mHasCrossOriginOpenerPolicyMismatch;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
nsresult nsHttpChannel::StartCrossProcessRedirect() {
|
nsresult nsHttpChannel::StartCrossProcessRedirect() {
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
|
@ -7373,19 +7396,6 @@ static bool CompareCrossOriginOpenerPolicies(
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method returns the cached result of running the Cross-Origin-Opener
|
|
||||||
// policy compare algorithm by calling ComputeCrossOriginOpenerPolicyMismatch
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsHttpChannel::HasCrossOriginOpenerPolicyMismatch(bool* aMismatch) {
|
|
||||||
MOZ_ASSERT(aMismatch);
|
|
||||||
if (!aMismatch) {
|
|
||||||
return NS_ERROR_INVALID_ARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
*aMismatch = mHasCrossOriginOpenerPolicyMismatch;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This runs steps 1-5 of the algorithm when navigating a top level document.
|
// This runs steps 1-5 of the algorithm when navigating a top level document.
|
||||||
// See https://gist.github.com/annevk/6f2dd8c79c77123f39797f6bdac43f3e
|
// See https://gist.github.com/annevk/6f2dd8c79c77123f39797f6bdac43f3e
|
||||||
nsresult nsHttpChannel::ComputeCrossOriginOpenerPolicyMismatch() {
|
nsresult nsHttpChannel::ComputeCrossOriginOpenerPolicyMismatch() {
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include "mozilla/extensions/PStreamFilterParent.h"
|
#include "mozilla/extensions/PStreamFilterParent.h"
|
||||||
#include "mozilla/Mutex.h"
|
#include "mozilla/Mutex.h"
|
||||||
#include "nsIRemoteTab.h"
|
#include "nsIRemoteTab.h"
|
||||||
|
#include "nsICrossProcessSwitchChannel.h"
|
||||||
|
|
||||||
class nsDNSPrefetch;
|
class nsDNSPrefetch;
|
||||||
class nsICancelable;
|
class nsICancelable;
|
||||||
|
@ -78,7 +79,8 @@ class nsHttpChannel final : public HttpBaseChannel,
|
||||||
public nsIChannelWithDivertableParentListener,
|
public nsIChannelWithDivertableParentListener,
|
||||||
public nsIRaceCacheWithNetwork,
|
public nsIRaceCacheWithNetwork,
|
||||||
public nsIRequestTailUnblockCallback,
|
public nsIRequestTailUnblockCallback,
|
||||||
public nsITimerCallback {
|
public nsITimerCallback,
|
||||||
|
public nsIProcessSwitchRequestor {
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS_INHERITED
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
NS_DECL_NSIREQUESTOBSERVER
|
NS_DECL_NSIREQUESTOBSERVER
|
||||||
|
@ -100,6 +102,7 @@ class nsHttpChannel final : public HttpBaseChannel,
|
||||||
NS_DECL_NSIRACECACHEWITHNETWORK
|
NS_DECL_NSIRACECACHEWITHNETWORK
|
||||||
NS_DECL_NSITIMERCALLBACK
|
NS_DECL_NSITIMERCALLBACK
|
||||||
NS_DECL_NSIREQUESTTAILUNBLOCKCALLBACK
|
NS_DECL_NSIREQUESTTAILUNBLOCKCALLBACK
|
||||||
|
NS_DECL_NSIPROCESSSWITCHREQUESTOR
|
||||||
|
|
||||||
// nsIHttpAuthenticableChannel. We can't use
|
// nsIHttpAuthenticableChannel. We can't use
|
||||||
// NS_DECL_NSIHTTPAUTHENTICABLECHANNEL because it duplicates cancel() and
|
// NS_DECL_NSIHTTPAUTHENTICABLECHANNEL because it duplicates cancel() and
|
||||||
|
@ -150,9 +153,6 @@ class nsHttpChannel final : public HttpBaseChannel,
|
||||||
NS_IMETHOD AsyncOpen(nsIStreamListener* aListener) override;
|
NS_IMETHOD AsyncOpen(nsIStreamListener* aListener) override;
|
||||||
// nsIHttpChannel
|
// nsIHttpChannel
|
||||||
NS_IMETHOD GetEncodedBodySize(uint64_t* aEncodedBodySize) override;
|
NS_IMETHOD GetEncodedBodySize(uint64_t* aEncodedBodySize) override;
|
||||||
NS_IMETHOD SwitchProcessTo(mozilla::dom::Promise* aBrowserParent,
|
|
||||||
uint64_t aIdentifier) override;
|
|
||||||
NS_IMETHOD HasCrossOriginOpenerPolicyMismatch(bool* aMismatch) override;
|
|
||||||
// nsIHttpChannelInternal
|
// nsIHttpChannelInternal
|
||||||
NS_IMETHOD SetupFallbackChannel(const char* aFallbackKey) override;
|
NS_IMETHOD SetupFallbackChannel(const char* aFallbackKey) override;
|
||||||
NS_IMETHOD SetChannelIsForDownload(bool aChannelIsForDownload) override;
|
NS_IMETHOD SetChannelIsForDownload(bool aChannelIsForDownload) override;
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "nsHttpChannel.h"
|
#include "nsHttpChannel.h"
|
||||||
#include "nsHttpAuthCache.h"
|
#include "nsHttpAuthCache.h"
|
||||||
#include "nsStandardURL.h"
|
#include "nsStandardURL.h"
|
||||||
|
#include "nsICrossProcessSwitchChannel.h"
|
||||||
#include "nsIDOMWindow.h"
|
#include "nsIDOMWindow.h"
|
||||||
#include "nsIHttpChannel.h"
|
#include "nsIHttpChannel.h"
|
||||||
#include "nsIStandardURL.h"
|
#include "nsIStandardURL.h"
|
||||||
|
@ -806,6 +807,14 @@ void nsHttpHandler::NotifyObservers(nsIChannel* chan, const char* event) {
|
||||||
if (obsService) obsService->NotifyObservers(chan, event, nullptr);
|
if (obsService) obsService->NotifyObservers(chan, event, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nsHttpHandler::NotifyObservers(nsIProcessSwitchRequestor* request,
|
||||||
|
const char* event) {
|
||||||
|
LOG(("nsHttpHandler::NotifyObservers [request=%p event=\"%s\"]\n", request,
|
||||||
|
event));
|
||||||
|
nsCOMPtr<nsIObserverService> obsService = services::GetObserverService();
|
||||||
|
if (obsService) obsService->NotifyObservers(request, event, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
nsresult nsHttpHandler::AsyncOnChannelRedirect(
|
nsresult nsHttpHandler::AsyncOnChannelRedirect(
|
||||||
nsIChannel* oldChan, nsIChannel* newChan, uint32_t flags,
|
nsIChannel* oldChan, nsIChannel* newChan, uint32_t flags,
|
||||||
nsIEventTarget* mainThreadEventTarget) {
|
nsIEventTarget* mainThreadEventTarget) {
|
||||||
|
|
|
@ -29,6 +29,7 @@ class nsIHttpChannel;
|
||||||
class nsIPrefBranch;
|
class nsIPrefBranch;
|
||||||
class nsICancelable;
|
class nsICancelable;
|
||||||
class nsICookieService;
|
class nsICookieService;
|
||||||
|
class nsIProcessSwitchRequestor;
|
||||||
class nsIIOService;
|
class nsIIOService;
|
||||||
class nsIRequestContextService;
|
class nsIRequestContextService;
|
||||||
class nsISiteSecurityService;
|
class nsISiteSecurityService;
|
||||||
|
@ -407,8 +408,8 @@ class nsHttpHandler final : public nsIHttpProtocolHandler,
|
||||||
NotifyObservers(chan, NS_HTTP_ON_EXAMINE_CACHED_RESPONSE_TOPIC);
|
NotifyObservers(chan, NS_HTTP_ON_EXAMINE_CACHED_RESPONSE_TOPIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnMayChangeProcess(nsIHttpChannel* chan) {
|
void OnMayChangeProcess(nsIProcessSwitchRequestor* request) {
|
||||||
NotifyObservers(chan, NS_HTTP_ON_MAY_CHANGE_PROCESS_TOPIC);
|
NotifyObservers(request, NS_HTTP_ON_MAY_CHANGE_PROCESS_TOPIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generates the host:port string for use in the Host: header as well as the
|
// Generates the host:port string for use in the Host: header as well as the
|
||||||
|
@ -479,6 +480,7 @@ class nsHttpHandler final : public nsIHttpProtocolHandler,
|
||||||
MOZ_MUST_USE nsresult InitConnectionMgr();
|
MOZ_MUST_USE nsresult InitConnectionMgr();
|
||||||
|
|
||||||
void NotifyObservers(nsIChannel* chan, const char* event);
|
void NotifyObservers(nsIChannel* chan, const char* event);
|
||||||
|
void NotifyObservers(nsIProcessSwitchRequestor* request, const char* event);
|
||||||
|
|
||||||
void SetFastOpenOSSupport();
|
void SetFastOpenOSSupport();
|
||||||
|
|
||||||
|
|
|
@ -415,26 +415,6 @@ interface nsIHttpChannel : nsIIdentChannel
|
||||||
*/
|
*/
|
||||||
[must_use] void redirectTo(in nsIURI aTargetURI);
|
[must_use] void redirectTo(in nsIURI aTargetURI);
|
||||||
|
|
||||||
/**
|
|
||||||
* Instructs the channel to be loaded in a new process. Like 'redirectTo'
|
|
||||||
* this can only be used on channels that have not yet called their
|
|
||||||
* listener's OnStartRequest().
|
|
||||||
*
|
|
||||||
* @param aTabPromise a promise which resolves to a nsIRemotTab object
|
|
||||||
* which the load will proceed in.
|
|
||||||
* @param aIdentifier a 64-bit ID which will be provided to the
|
|
||||||
* ChildProcessChannelListener.
|
|
||||||
*/
|
|
||||||
[must_use] void switchProcessTo(in Promise aTabPromise,
|
|
||||||
in unsigned long long aIdentifier);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used to determine if there is a Cross-Origin-Opener-Policy mismatch
|
|
||||||
* that would require switching the channel to another process.
|
|
||||||
* @throws NS_ERROR_NOT_AVAILABLE if we don't have a responseHead
|
|
||||||
*/
|
|
||||||
[must_use] boolean hasCrossOriginOpenerPolicyMismatch();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flags a channel to be upgraded to HTTPS.
|
* Flags a channel to be upgraded to HTTPS.
|
||||||
*
|
*
|
||||||
|
|
|
@ -175,9 +175,9 @@ interface nsIHttpProtocolHandler : nsIProxiedProtocolHandler
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The observer of this topic is notified before before the response for a HTTP
|
* The observer of this topic is notified before before the response for a HTTP
|
||||||
* load is available. The "subject" of the notification is the nsIHttpChannel
|
* load is available. The "subject" of the notification is the
|
||||||
* instance. Observers may call "switchProcessTo" to perform a process switch
|
* nsIProcessSwitchRequestor instance. Observers may call "switchProcessTo" to
|
||||||
* while this is being run.
|
* perform a process switch while this is being run.
|
||||||
*/
|
*/
|
||||||
#define NS_HTTP_ON_MAY_CHANGE_PROCESS_TOPIC "http-on-may-change-process"
|
#define NS_HTTP_ON_MAY_CHANGE_PROCESS_TOPIC "http-on-may-change-process"
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,8 @@ EXPORTS += [
|
||||||
FINAL_LIBRARY = 'xul'
|
FINAL_LIBRARY = 'xul'
|
||||||
LOCAL_INCLUDES += [
|
LOCAL_INCLUDES += [
|
||||||
'/netwerk/base',
|
'/netwerk/base',
|
||||||
|
# For nsHttpChannel.h
|
||||||
|
'/netwerk/protocol/http',
|
||||||
]
|
]
|
||||||
|
|
||||||
include('/ipc/chromium/chromium-config.mozbuild')
|
include('/ipc/chromium/chromium-config.mozbuild')
|
||||||
|
|
|
@ -5,17 +5,18 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include "nsViewSourceChannel.h"
|
#include "nsViewSourceChannel.h"
|
||||||
#include "nsIIOService.h"
|
|
||||||
#include "nsMimeTypes.h"
|
|
||||||
#include "nsNetUtil.h"
|
|
||||||
#include "nsContentUtils.h"
|
|
||||||
#include "nsIHttpHeaderVisitor.h"
|
|
||||||
#include "nsContentSecurityManager.h"
|
|
||||||
#include "nsServiceManagerUtils.h"
|
|
||||||
#include "nsIInputStreamChannel.h"
|
|
||||||
#include "mozilla/DebugOnly.h"
|
#include "mozilla/DebugOnly.h"
|
||||||
#include "mozilla/NullPrincipal.h"
|
#include "mozilla/NullPrincipal.h"
|
||||||
|
#include "nsContentSecurityManager.h"
|
||||||
|
#include "nsContentUtils.h"
|
||||||
|
#include "nsHttpChannel.h"
|
||||||
|
#include "nsIHttpHeaderVisitor.h"
|
||||||
|
#include "nsIIOService.h"
|
||||||
|
#include "nsIInputStreamChannel.h"
|
||||||
#include "nsIReferrerInfo.h"
|
#include "nsIReferrerInfo.h"
|
||||||
|
#include "nsMimeTypes.h"
|
||||||
|
#include "nsNetUtil.h"
|
||||||
|
#include "nsServiceManagerUtils.h"
|
||||||
|
|
||||||
NS_IMPL_ADDREF(nsViewSourceChannel)
|
NS_IMPL_ADDREF(nsViewSourceChannel)
|
||||||
NS_IMPL_RELEASE(nsViewSourceChannel)
|
NS_IMPL_RELEASE(nsViewSourceChannel)
|
||||||
|
@ -40,6 +41,8 @@ NS_INTERFACE_MAP_BEGIN(nsViewSourceChannel)
|
||||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIRequest, nsIViewSourceChannel)
|
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIRequest, nsIViewSourceChannel)
|
||||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIChannel, nsIViewSourceChannel)
|
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIChannel, nsIViewSourceChannel)
|
||||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIViewSourceChannel)
|
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIViewSourceChannel)
|
||||||
|
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIProcessSwitchRequestor,
|
||||||
|
IsNsHttpChannel())
|
||||||
NS_INTERFACE_MAP_END
|
NS_INTERFACE_MAP_END
|
||||||
|
|
||||||
nsresult nsViewSourceChannel::Init(nsIURI* uri, nsILoadInfo* aLoadInfo) {
|
nsresult nsViewSourceChannel::Init(nsIURI* uri, nsILoadInfo* aLoadInfo) {
|
||||||
|
@ -942,24 +945,6 @@ nsViewSourceChannel::RedirectTo(nsIURI* uri) {
|
||||||
return !mHttpChannel ? NS_ERROR_NULL_POINTER : mHttpChannel->RedirectTo(uri);
|
return !mHttpChannel ? NS_ERROR_NULL_POINTER : mHttpChannel->RedirectTo(uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsViewSourceChannel::SwitchProcessTo(mozilla::dom::Promise* aBrowserParent,
|
|
||||||
uint64_t aIdentifier) {
|
|
||||||
return !mHttpChannel
|
|
||||||
? NS_ERROR_NULL_POINTER
|
|
||||||
: mHttpChannel->SwitchProcessTo(aBrowserParent, aIdentifier);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsViewSourceChannel::HasCrossOriginOpenerPolicyMismatch(bool* aMismatch) {
|
|
||||||
MOZ_ASSERT(aMismatch);
|
|
||||||
if (!aMismatch) {
|
|
||||||
return NS_ERROR_INVALID_ARG;
|
|
||||||
}
|
|
||||||
*aMismatch = false;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsViewSourceChannel::UpgradeToSecure() {
|
nsViewSourceChannel::UpgradeToSecure() {
|
||||||
return !mHttpChannel ? NS_ERROR_NULL_POINTER
|
return !mHttpChannel ? NS_ERROR_NULL_POINTER
|
||||||
|
@ -1057,3 +1042,49 @@ void nsViewSourceChannel::SetHasSandboxedAuxiliaryNavigations(
|
||||||
aHasSandboxedAuxiliaryNavigations);
|
aHasSandboxedAuxiliaryNavigations);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// nsViewSourceChannel::nsIProcessSwitchRequestor
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsViewSourceChannel::GetChannel(nsIChannel** aChannel) {
|
||||||
|
if (!IsNsHttpChannel()) {
|
||||||
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
|
}
|
||||||
|
*aChannel = mHttpChannel;
|
||||||
|
NS_ADDREF(*aChannel);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsViewSourceChannel::SwitchProcessTo(mozilla::dom::Promise* aBrowserParent,
|
||||||
|
uint64_t aIdentifier) {
|
||||||
|
if (!IsNsHttpChannel()) {
|
||||||
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
|
}
|
||||||
|
nsCOMPtr<mozilla::net::nsHttpChannel> httpChannel =
|
||||||
|
do_QueryInterface(mHttpChannel);
|
||||||
|
return httpChannel->SwitchProcessTo(aBrowserParent, aIdentifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsViewSourceChannel::HasCrossOriginOpenerPolicyMismatch(bool* aMismatch) {
|
||||||
|
if (!IsNsHttpChannel()) {
|
||||||
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
|
}
|
||||||
|
MOZ_ASSERT(aMismatch);
|
||||||
|
if (!aMismatch) {
|
||||||
|
return NS_ERROR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
*aMismatch = false;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nsViewSourceChannel::IsNsHttpChannel() const {
|
||||||
|
if (!mHttpChannel) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
nsCOMPtr<mozilla::net::nsHttpChannel> httpChannel =
|
||||||
|
do_QueryInterface(mHttpChannel);
|
||||||
|
return !!httpChannel;
|
||||||
|
}
|
||||||
|
|
|
@ -6,18 +6,19 @@
|
||||||
#ifndef nsViewSourceChannel_h___
|
#ifndef nsViewSourceChannel_h___
|
||||||
#define nsViewSourceChannel_h___
|
#define nsViewSourceChannel_h___
|
||||||
|
|
||||||
#include "nsString.h"
|
|
||||||
#include "nsCOMPtr.h"
|
|
||||||
#include "nsIViewSourceChannel.h"
|
|
||||||
#include "nsIURI.h"
|
|
||||||
#include "nsIStreamListener.h"
|
|
||||||
#include "nsIHttpChannel.h"
|
|
||||||
#include "nsIHttpChannelInternal.h"
|
|
||||||
#include "nsICachingChannel.h"
|
|
||||||
#include "nsIApplicationCacheChannel.h"
|
|
||||||
#include "nsIFormPOSTActionChannel.h"
|
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
#include "mozilla/net/NeckoChannelParams.h"
|
#include "mozilla/net/NeckoChannelParams.h"
|
||||||
|
#include "nsCOMPtr.h"
|
||||||
|
#include "nsIApplicationCacheChannel.h"
|
||||||
|
#include "nsICachingChannel.h"
|
||||||
|
#include "nsICrossProcessSwitchChannel.h"
|
||||||
|
#include "nsIFormPOSTActionChannel.h"
|
||||||
|
#include "nsIHttpChannel.h"
|
||||||
|
#include "nsIHttpChannelInternal.h"
|
||||||
|
#include "nsIStreamListener.h"
|
||||||
|
#include "nsIURI.h"
|
||||||
|
#include "nsIViewSourceChannel.h"
|
||||||
|
#include "nsString.h"
|
||||||
|
|
||||||
class nsViewSourceChannel final : public nsIViewSourceChannel,
|
class nsViewSourceChannel final : public nsIViewSourceChannel,
|
||||||
public nsIStreamListener,
|
public nsIStreamListener,
|
||||||
|
@ -25,7 +26,8 @@ class nsViewSourceChannel final : public nsIViewSourceChannel,
|
||||||
public nsIHttpChannelInternal,
|
public nsIHttpChannelInternal,
|
||||||
public nsICachingChannel,
|
public nsICachingChannel,
|
||||||
public nsIApplicationCacheChannel,
|
public nsIApplicationCacheChannel,
|
||||||
public nsIFormPOSTActionChannel {
|
public nsIFormPOSTActionChannel,
|
||||||
|
public nsIProcessSwitchRequestor {
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
NS_DECL_NSIREQUEST
|
NS_DECL_NSIREQUEST
|
||||||
|
@ -35,6 +37,7 @@ class nsViewSourceChannel final : public nsIViewSourceChannel,
|
||||||
NS_DECL_NSISTREAMLISTENER
|
NS_DECL_NSISTREAMLISTENER
|
||||||
NS_DECL_NSIREQUESTOBSERVER
|
NS_DECL_NSIREQUESTOBSERVER
|
||||||
NS_DECL_NSIHTTPCHANNEL
|
NS_DECL_NSIHTTPCHANNEL
|
||||||
|
NS_DECL_NSIPROCESSSWITCHREQUESTOR
|
||||||
NS_FORWARD_SAFE_NSICACHEINFOCHANNEL(mCacheInfoChannel)
|
NS_FORWARD_SAFE_NSICACHEINFOCHANNEL(mCacheInfoChannel)
|
||||||
NS_FORWARD_SAFE_NSICACHINGCHANNEL(mCachingChannel)
|
NS_FORWARD_SAFE_NSICACHINGCHANNEL(mCachingChannel)
|
||||||
NS_FORWARD_SAFE_NSIAPPLICATIONCACHECHANNEL(mApplicationCacheChannel)
|
NS_FORWARD_SAFE_NSIAPPLICATIONCACHECHANNEL(mApplicationCacheChannel)
|
||||||
|
@ -82,6 +85,9 @@ class nsViewSourceChannel final : public nsIViewSourceChannel,
|
||||||
bool mIsDocument; // keeps track of the LOAD_DOCUMENT_URI flag
|
bool mIsDocument; // keeps track of the LOAD_DOCUMENT_URI flag
|
||||||
bool mOpened;
|
bool mOpened;
|
||||||
bool mIsSrcdocChannel;
|
bool mIsSrcdocChannel;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool IsNsHttpChannel() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* nsViewSourceChannel_h___ */
|
#endif /* nsViewSourceChannel_h___ */
|
||||||
|
|
|
@ -40,26 +40,28 @@ ProcessChooser.prototype = {
|
||||||
Services.obs.removeObserver(this, "http-on-may-change-process");
|
Services.obs.removeObserver(this, "http-on-may-change-process");
|
||||||
},
|
},
|
||||||
|
|
||||||
examine(aChannel) {
|
examine(aRequestor) {
|
||||||
if (this.channel && this.channel != aChannel) {
|
const channel = aRequestor.channel;
|
||||||
|
|
||||||
|
if (this.channel && this.channel != channel) {
|
||||||
// Hack: this is just so we don't get redirected multiple times.
|
// Hack: this is just so we don't get redirected multiple times.
|
||||||
info("same channel. give null");
|
info("same channel. give null");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aChannel.URI.host != this.toDomain) {
|
if (channel.URI.host != this.toDomain) {
|
||||||
info("wrong host for channel " + aChannel.URI.host);
|
info("wrong host for channel " + channel.URI.host);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let redirects = aChannel.loadInfo.redirectChain;
|
let redirects = channel.loadInfo.redirectChain;
|
||||||
if (redirects[redirects.length - 1].principal.URI.host != this.fromDomain) {
|
if (redirects[redirects.length - 1].principal.URI.host != this.fromDomain) {
|
||||||
info("didn't find redirect");
|
info("didn't find redirect");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
info("setting channel");
|
info("setting channel");
|
||||||
this.channel = aChannel;
|
this.channel = channel;
|
||||||
let self = this;
|
let self = this;
|
||||||
|
|
||||||
info("unregistering");
|
info("unregistering");
|
||||||
|
@ -79,13 +81,13 @@ ProcessChooser.prototype = {
|
||||||
});
|
});
|
||||||
|
|
||||||
info("calling switchprocessto");
|
info("calling switchprocessto");
|
||||||
aChannel.switchProcessTo(tabPromise, identifier);
|
aRequestor.switchProcessTo(tabPromise, identifier);
|
||||||
},
|
},
|
||||||
|
|
||||||
observe(aSubject, aTopic, aData) {
|
observe(aSubject, aTopic, aData) {
|
||||||
switch (aTopic) {
|
switch (aTopic) {
|
||||||
case "http-on-may-change-process":
|
case "http-on-may-change-process":
|
||||||
this.examine(aSubject.QueryInterface(Ci.nsIHttpChannel));
|
this.examine(aSubject.QueryInterface(Ci.nsIProcessSwitchRequestor));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ok(false, "Unexpected topic observed!");
|
ok(false, "Unexpected topic observed!");
|
||||||
|
|
Загрузка…
Ссылка в новой задаче