зеркало из 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
|
||||
// performing the given load.
|
||||
onMayChangeProcess(aChannel) {
|
||||
// performing the given load. aRequestor implements nsIProcessSwitchRequestor
|
||||
onMayChangeProcess(aRequestor) {
|
||||
if (
|
||||
!E10SUtils.useHttpResponseProcessSelection() &&
|
||||
!E10SUtils.useCrossOriginOpenerPolicy()
|
||||
|
@ -2615,19 +2615,26 @@ var SessionStoreInternal = {
|
|||
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.
|
||||
}
|
||||
|
||||
// Check that the document has a corresponding BrowsingContext.
|
||||
let browsingContext;
|
||||
let cp = aChannel.loadInfo.externalContentPolicyType;
|
||||
let cp = channel.loadInfo.externalContentPolicyType;
|
||||
if (cp == Ci.nsIContentPolicy.TYPE_DOCUMENT) {
|
||||
browsingContext = aChannel.loadInfo.browsingContext;
|
||||
browsingContext = channel.loadInfo.browsingContext;
|
||||
} else {
|
||||
browsingContext = aChannel.loadInfo.frameBrowsingContext;
|
||||
browsingContext = channel.loadInfo.frameBrowsingContext;
|
||||
}
|
||||
|
||||
if (!browsingContext) {
|
||||
|
@ -2691,7 +2698,7 @@ var SessionStoreInternal = {
|
|||
|
||||
// Determine the process type the load should be performed in.
|
||||
let resultPrincipal = Services.scriptSecurityManager.getChannelResultPrincipal(
|
||||
aChannel
|
||||
channel
|
||||
);
|
||||
let remoteType = E10SUtils.getRemoteTypeForPrincipal(
|
||||
resultPrincipal,
|
||||
|
@ -2703,7 +2710,7 @@ var SessionStoreInternal = {
|
|||
if (
|
||||
currentRemoteType == remoteType &&
|
||||
(!E10SUtils.useCrossOriginOpenerPolicy() ||
|
||||
!aChannel.hasCrossOriginOpenerPolicyMismatch())
|
||||
!switchRequestor.hasCrossOriginOpenerPolicyMismatch())
|
||||
) {
|
||||
debug(`[process-switch]: type (${remoteType}) is compatible - ignoring`);
|
||||
return;
|
||||
|
@ -2719,7 +2726,7 @@ var SessionStoreInternal = {
|
|||
|
||||
const isCOOPSwitch =
|
||||
E10SUtils.useCrossOriginOpenerPolicy() &&
|
||||
aChannel.hasCrossOriginOpenerPolicyMismatch();
|
||||
switchRequestor.hasCrossOriginOpenerPolicyMismatch();
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// DANGER ZONE: Perform a process switch into the new process. This is
|
||||
|
@ -2729,11 +2736,11 @@ var SessionStoreInternal = {
|
|||
let tabPromise = this._doProcessSwitch(
|
||||
browsingContext,
|
||||
remoteType,
|
||||
aChannel,
|
||||
channel,
|
||||
identifier,
|
||||
isCOOPSwitch
|
||||
);
|
||||
aChannel.switchProcessTo(tabPromise, identifier);
|
||||
switchRequestor.switchProcessTo(tabPromise, identifier);
|
||||
},
|
||||
|
||||
/* ........ nsISessionStore API .............. */
|
||||
|
|
|
@ -37,3 +37,41 @@ interface nsICrossProcessSwitchChannel : nsISupports
|
|||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
HttpBaseChannel::UpgradeToSecure() {
|
||||
// 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 GetRequestSucceeded(bool* aValue) 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 GetRequestContextID(uint64_t* aRCID) override;
|
||||
NS_IMETHOD GetTransferSize(uint64_t* aTransferSize) override;
|
||||
|
|
|
@ -273,17 +273,6 @@ NullHttpChannel::RedirectTo(nsIURI* aNewURI) {
|
|||
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
|
||||
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(nsIChannelWithDivertableParentListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIRequestTailUnblockCallback)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIProcessSwitchRequestor)
|
||||
NS_INTERFACE_MAP_ENTRY_CONCRETE(nsHttpChannel)
|
||||
NS_INTERFACE_MAP_END_INHERITING(HttpBaseChannel)
|
||||
|
||||
|
@ -7285,6 +7286,15 @@ class DomPromiseListener final : dom::PromiseNativeHandler {
|
|||
|
||||
NS_IMPL_ISUPPORTS0(DomPromiseListener)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsHttpChannel::nsIProcessSwitchRequestor
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP nsHttpChannel::GetChannel(nsIChannel** aChannel) {
|
||||
*aChannel = do_AddRef(this).take();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsHttpChannel::SwitchProcessTo(
|
||||
dom::Promise* aContentProcessIdPromise, uint64_t aIdentifier) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
@ -7310,6 +7320,19 @@ NS_IMETHODIMP nsHttpChannel::SwitchProcessTo(
|
|||
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 rv;
|
||||
|
||||
|
@ -7373,19 +7396,6 @@ static bool CompareCrossOriginOpenerPolicies(
|
|||
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.
|
||||
// See https://gist.github.com/annevk/6f2dd8c79c77123f39797f6bdac43f3e
|
||||
nsresult nsHttpChannel::ComputeCrossOriginOpenerPolicyMismatch() {
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "mozilla/extensions/PStreamFilterParent.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "nsIRemoteTab.h"
|
||||
#include "nsICrossProcessSwitchChannel.h"
|
||||
|
||||
class nsDNSPrefetch;
|
||||
class nsICancelable;
|
||||
|
@ -78,7 +79,8 @@ class nsHttpChannel final : public HttpBaseChannel,
|
|||
public nsIChannelWithDivertableParentListener,
|
||||
public nsIRaceCacheWithNetwork,
|
||||
public nsIRequestTailUnblockCallback,
|
||||
public nsITimerCallback {
|
||||
public nsITimerCallback,
|
||||
public nsIProcessSwitchRequestor {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
|
@ -100,6 +102,7 @@ class nsHttpChannel final : public HttpBaseChannel,
|
|||
NS_DECL_NSIRACECACHEWITHNETWORK
|
||||
NS_DECL_NSITIMERCALLBACK
|
||||
NS_DECL_NSIREQUESTTAILUNBLOCKCALLBACK
|
||||
NS_DECL_NSIPROCESSSWITCHREQUESTOR
|
||||
|
||||
// nsIHttpAuthenticableChannel. We can't use
|
||||
// NS_DECL_NSIHTTPAUTHENTICABLECHANNEL because it duplicates cancel() and
|
||||
|
@ -150,9 +153,6 @@ class nsHttpChannel final : public HttpBaseChannel,
|
|||
NS_IMETHOD AsyncOpen(nsIStreamListener* aListener) override;
|
||||
// nsIHttpChannel
|
||||
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
|
||||
NS_IMETHOD SetupFallbackChannel(const char* aFallbackKey) override;
|
||||
NS_IMETHOD SetChannelIsForDownload(bool aChannelIsForDownload) override;
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "nsHttpChannel.h"
|
||||
#include "nsHttpAuthCache.h"
|
||||
#include "nsStandardURL.h"
|
||||
#include "nsICrossProcessSwitchChannel.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsIHttpChannel.h"
|
||||
#include "nsIStandardURL.h"
|
||||
|
@ -806,6 +807,14 @@ void nsHttpHandler::NotifyObservers(nsIChannel* chan, const char* event) {
|
|||
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(
|
||||
nsIChannel* oldChan, nsIChannel* newChan, uint32_t flags,
|
||||
nsIEventTarget* mainThreadEventTarget) {
|
||||
|
|
|
@ -29,6 +29,7 @@ class nsIHttpChannel;
|
|||
class nsIPrefBranch;
|
||||
class nsICancelable;
|
||||
class nsICookieService;
|
||||
class nsIProcessSwitchRequestor;
|
||||
class nsIIOService;
|
||||
class nsIRequestContextService;
|
||||
class nsISiteSecurityService;
|
||||
|
@ -407,8 +408,8 @@ class nsHttpHandler final : public nsIHttpProtocolHandler,
|
|||
NotifyObservers(chan, NS_HTTP_ON_EXAMINE_CACHED_RESPONSE_TOPIC);
|
||||
}
|
||||
|
||||
void OnMayChangeProcess(nsIHttpChannel* chan) {
|
||||
NotifyObservers(chan, NS_HTTP_ON_MAY_CHANGE_PROCESS_TOPIC);
|
||||
void OnMayChangeProcess(nsIProcessSwitchRequestor* request) {
|
||||
NotifyObservers(request, NS_HTTP_ON_MAY_CHANGE_PROCESS_TOPIC);
|
||||
}
|
||||
|
||||
// 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();
|
||||
|
||||
void NotifyObservers(nsIChannel* chan, const char* event);
|
||||
void NotifyObservers(nsIProcessSwitchRequestor* request, const char* event);
|
||||
|
||||
void SetFastOpenOSSupport();
|
||||
|
||||
|
|
|
@ -415,26 +415,6 @@ interface nsIHttpChannel : nsIIdentChannel
|
|||
*/
|
||||
[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.
|
||||
*
|
||||
|
|
|
@ -175,9 +175,9 @@ interface nsIHttpProtocolHandler : nsIProxiedProtocolHandler
|
|||
|
||||
/**
|
||||
* 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
|
||||
* instance. Observers may call "switchProcessTo" to perform a process switch
|
||||
* while this is being run.
|
||||
* load is available. The "subject" of the notification is the
|
||||
* nsIProcessSwitchRequestor instance. Observers may call "switchProcessTo" to
|
||||
* perform a process switch while this is being run.
|
||||
*/
|
||||
#define NS_HTTP_ON_MAY_CHANGE_PROCESS_TOPIC "http-on-may-change-process"
|
||||
|
||||
|
|
|
@ -22,6 +22,8 @@ EXPORTS += [
|
|||
FINAL_LIBRARY = 'xul'
|
||||
LOCAL_INCLUDES += [
|
||||
'/netwerk/base',
|
||||
# For nsHttpChannel.h
|
||||
'/netwerk/protocol/http',
|
||||
]
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
|
|
@ -5,17 +5,18 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#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/NullPrincipal.h"
|
||||
#include "nsContentSecurityManager.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsHttpChannel.h"
|
||||
#include "nsIHttpHeaderVisitor.h"
|
||||
#include "nsIIOService.h"
|
||||
#include "nsIInputStreamChannel.h"
|
||||
#include "nsIReferrerInfo.h"
|
||||
#include "nsMimeTypes.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
|
||||
NS_IMPL_ADDREF(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(nsIChannel, nsIViewSourceChannel)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIViewSourceChannel)
|
||||
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIProcessSwitchRequestor,
|
||||
IsNsHttpChannel())
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
nsresult nsViewSourceChannel::Init(nsIURI* uri, nsILoadInfo* aLoadInfo) {
|
||||
|
@ -942,24 +945,6 @@ nsViewSourceChannel::RedirectTo(nsIURI* 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
|
||||
nsViewSourceChannel::UpgradeToSecure() {
|
||||
return !mHttpChannel ? NS_ERROR_NULL_POINTER
|
||||
|
@ -1057,3 +1042,49 @@ void nsViewSourceChannel::SetHasSandboxedAuxiliaryNavigations(
|
|||
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___
|
||||
#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/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,
|
||||
public nsIStreamListener,
|
||||
|
@ -25,7 +26,8 @@ class nsViewSourceChannel final : public nsIViewSourceChannel,
|
|||
public nsIHttpChannelInternal,
|
||||
public nsICachingChannel,
|
||||
public nsIApplicationCacheChannel,
|
||||
public nsIFormPOSTActionChannel {
|
||||
public nsIFormPOSTActionChannel,
|
||||
public nsIProcessSwitchRequestor {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIREQUEST
|
||||
|
@ -35,6 +37,7 @@ class nsViewSourceChannel final : public nsIViewSourceChannel,
|
|||
NS_DECL_NSISTREAMLISTENER
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
NS_DECL_NSIHTTPCHANNEL
|
||||
NS_DECL_NSIPROCESSSWITCHREQUESTOR
|
||||
NS_FORWARD_SAFE_NSICACHEINFOCHANNEL(mCacheInfoChannel)
|
||||
NS_FORWARD_SAFE_NSICACHINGCHANNEL(mCachingChannel)
|
||||
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 mOpened;
|
||||
bool mIsSrcdocChannel;
|
||||
|
||||
private:
|
||||
bool IsNsHttpChannel() const;
|
||||
};
|
||||
|
||||
#endif /* nsViewSourceChannel_h___ */
|
||||
|
|
|
@ -40,26 +40,28 @@ ProcessChooser.prototype = {
|
|||
Services.obs.removeObserver(this, "http-on-may-change-process");
|
||||
},
|
||||
|
||||
examine(aChannel) {
|
||||
if (this.channel && this.channel != aChannel) {
|
||||
examine(aRequestor) {
|
||||
const channel = aRequestor.channel;
|
||||
|
||||
if (this.channel && this.channel != channel) {
|
||||
// Hack: this is just so we don't get redirected multiple times.
|
||||
info("same channel. give null");
|
||||
return;
|
||||
}
|
||||
|
||||
if (aChannel.URI.host != this.toDomain) {
|
||||
info("wrong host for channel " + aChannel.URI.host);
|
||||
if (channel.URI.host != this.toDomain) {
|
||||
info("wrong host for channel " + channel.URI.host);
|
||||
return;
|
||||
}
|
||||
|
||||
let redirects = aChannel.loadInfo.redirectChain;
|
||||
let redirects = channel.loadInfo.redirectChain;
|
||||
if (redirects[redirects.length - 1].principal.URI.host != this.fromDomain) {
|
||||
info("didn't find redirect");
|
||||
return;
|
||||
}
|
||||
|
||||
info("setting channel");
|
||||
this.channel = aChannel;
|
||||
this.channel = channel;
|
||||
let self = this;
|
||||
|
||||
info("unregistering");
|
||||
|
@ -79,13 +81,13 @@ ProcessChooser.prototype = {
|
|||
});
|
||||
|
||||
info("calling switchprocessto");
|
||||
aChannel.switchProcessTo(tabPromise, identifier);
|
||||
aRequestor.switchProcessTo(tabPromise, identifier);
|
||||
},
|
||||
|
||||
observe(aSubject, aTopic, aData) {
|
||||
switch (aTopic) {
|
||||
case "http-on-may-change-process":
|
||||
this.examine(aSubject.QueryInterface(Ci.nsIHttpChannel));
|
||||
this.examine(aSubject.QueryInterface(Ci.nsIProcessSwitchRequestor));
|
||||
break;
|
||||
default:
|
||||
ok(false, "Unexpected topic observed!");
|
||||
|
|
Загрузка…
Ссылка в новой задаче