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:
Jean-Yves Avenard 2019-09-18 23:49:51 +00:00
Родитель 02d8a3d841
Коммит db9dcef811
15 изменённых файлов: 186 добавлений и 124 удалений

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

@ -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!");