зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1277028 - Make external protocol handlers work with e10s redirects, r=jduell
This commit is contained in:
Родитель
8cb77ec6fc
Коммит
2342cffea3
|
@ -142,6 +142,7 @@
|
||||||
#include "nsIMutable.h"
|
#include "nsIMutable.h"
|
||||||
#include "nsINSSU2FToken.h"
|
#include "nsINSSU2FToken.h"
|
||||||
#include "nsIObserverService.h"
|
#include "nsIObserverService.h"
|
||||||
|
#include "nsIParentChannel.h"
|
||||||
#include "nsIPresShell.h"
|
#include "nsIPresShell.h"
|
||||||
#include "nsIRemoteWindowContext.h"
|
#include "nsIRemoteWindowContext.h"
|
||||||
#include "nsIScriptError.h"
|
#include "nsIScriptError.h"
|
||||||
|
@ -4419,6 +4420,32 @@ ContentParent::RecvLoadURIExternal(const URIParams& uri,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ContentParent::RecvExtProtocolChannelConnectParent(const uint32_t& registrarId)
|
||||||
|
{
|
||||||
|
nsresult rv;
|
||||||
|
|
||||||
|
// First get the real channel created before redirect on the parent.
|
||||||
|
nsCOMPtr<nsIChannel> channel;
|
||||||
|
rv = NS_LinkRedirectChannels(registrarId, nullptr, getter_AddRefs(channel));
|
||||||
|
NS_ENSURE_SUCCESS(rv, true);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIParentChannel> parent = do_QueryInterface(channel, &rv);
|
||||||
|
NS_ENSURE_SUCCESS(rv, true);
|
||||||
|
|
||||||
|
// The channel itself is its own (faked) parent, link it.
|
||||||
|
rv = NS_LinkRedirectChannels(registrarId, parent, getter_AddRefs(channel));
|
||||||
|
NS_ENSURE_SUCCESS(rv, true);
|
||||||
|
|
||||||
|
// Signal the parent channel that it's a redirect-to parent. This will
|
||||||
|
// make AsyncOpen on it do nothing (what we want).
|
||||||
|
// Yes, this is a bit of a hack, but I don't think it's necessary to invent
|
||||||
|
// a new interface just to set this flag on the channel.
|
||||||
|
parent->SetParentListener(nullptr);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ContentParent::HasNotificationPermission(const IPC::Principal& aPrincipal)
|
ContentParent::HasNotificationPermission(const IPC::Principal& aPrincipal)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1004,6 +1004,7 @@ private:
|
||||||
|
|
||||||
virtual bool RecvLoadURIExternal(const URIParams& uri,
|
virtual bool RecvLoadURIExternal(const URIParams& uri,
|
||||||
PBrowserParent* windowContext) override;
|
PBrowserParent* windowContext) override;
|
||||||
|
virtual bool RecvExtProtocolChannelConnectParent(const uint32_t& registrarId) override;
|
||||||
|
|
||||||
virtual bool RecvSyncMessage(const nsString& aMsg,
|
virtual bool RecvSyncMessage(const nsString& aMsg,
|
||||||
const ClonedMessageData& aData,
|
const ClonedMessageData& aData,
|
||||||
|
|
|
@ -833,6 +833,7 @@ parent:
|
||||||
async SetURITitle(URIParams uri, nsString title);
|
async SetURITitle(URIParams uri, nsString title);
|
||||||
|
|
||||||
async LoadURIExternal(URIParams uri, PBrowser windowContext);
|
async LoadURIExternal(URIParams uri, PBrowser windowContext);
|
||||||
|
async ExtProtocolChannelConnectParent(uint32_t registrarId);
|
||||||
|
|
||||||
// PrefService message
|
// PrefService message
|
||||||
sync ReadPrefsArray() returns (PrefSetting[] prefs) verify;
|
sync ReadPrefsArray() returns (PrefSetting[] prefs) verify;
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
// used to dispatch urls to default protocol handlers
|
// used to dispatch urls to default protocol handlers
|
||||||
#include "nsCExternalHandlerService.h"
|
#include "nsCExternalHandlerService.h"
|
||||||
#include "nsIExternalProtocolService.h"
|
#include "nsIExternalProtocolService.h"
|
||||||
|
#include "nsIChildChannel.h"
|
||||||
|
#include "nsIParentChannel.h"
|
||||||
|
|
||||||
class nsILoadInfo;
|
class nsILoadInfo;
|
||||||
|
|
||||||
|
@ -34,12 +36,18 @@ class nsILoadInfo;
|
||||||
// to calls in the OS for loading the url.
|
// to calls in the OS for loading the url.
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
class nsExtProtocolChannel : public nsIChannel
|
class nsExtProtocolChannel : public nsIChannel,
|
||||||
|
public nsIChildChannel,
|
||||||
|
public nsIParentChannel
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_THREADSAFE_ISUPPORTS
|
NS_DECL_THREADSAFE_ISUPPORTS
|
||||||
NS_DECL_NSICHANNEL
|
NS_DECL_NSICHANNEL
|
||||||
|
NS_DECL_NSIREQUESTOBSERVER
|
||||||
|
NS_DECL_NSISTREAMLISTENER
|
||||||
NS_DECL_NSIREQUEST
|
NS_DECL_NSIREQUEST
|
||||||
|
NS_DECL_NSICHILDCHANNEL
|
||||||
|
NS_DECL_NSIPARENTCHANNEL
|
||||||
|
|
||||||
nsExtProtocolChannel(nsIURI* aURI, nsILoadInfo* aLoadInfo);
|
nsExtProtocolChannel(nsIURI* aURI, nsILoadInfo* aLoadInfo);
|
||||||
|
|
||||||
|
@ -54,6 +62,11 @@ private:
|
||||||
nsresult mStatus;
|
nsresult mStatus;
|
||||||
nsLoadFlags mLoadFlags;
|
nsLoadFlags mLoadFlags;
|
||||||
bool mWasOpened;
|
bool mWasOpened;
|
||||||
|
// Set true (as a result of ConnectParent invoked from child process)
|
||||||
|
// when this channel is on the parent process and is being used as
|
||||||
|
// a redirect target channel. It turns AsyncOpen into a no-op since
|
||||||
|
// we do it on the child.
|
||||||
|
bool mConnectedParent;
|
||||||
|
|
||||||
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
|
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
|
||||||
nsCOMPtr<nsILoadGroup> mLoadGroup;
|
nsCOMPtr<nsILoadGroup> mLoadGroup;
|
||||||
|
@ -67,6 +80,10 @@ NS_INTERFACE_MAP_BEGIN(nsExtProtocolChannel)
|
||||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIChannel)
|
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIChannel)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIChannel)
|
NS_INTERFACE_MAP_ENTRY(nsIChannel)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIRequest)
|
NS_INTERFACE_MAP_ENTRY(nsIRequest)
|
||||||
|
NS_INTERFACE_MAP_ENTRY(nsIChildChannel)
|
||||||
|
NS_INTERFACE_MAP_ENTRY(nsIParentChannel)
|
||||||
|
NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
|
||||||
|
NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
|
||||||
NS_INTERFACE_MAP_END_THREADSAFE
|
NS_INTERFACE_MAP_END_THREADSAFE
|
||||||
|
|
||||||
nsExtProtocolChannel::nsExtProtocolChannel(nsIURI* aURI,
|
nsExtProtocolChannel::nsExtProtocolChannel(nsIURI* aURI,
|
||||||
|
@ -75,6 +92,7 @@ nsExtProtocolChannel::nsExtProtocolChannel(nsIURI* aURI,
|
||||||
, mOriginalURI(aURI)
|
, mOriginalURI(aURI)
|
||||||
, mStatus(NS_OK)
|
, mStatus(NS_OK)
|
||||||
, mWasOpened(false)
|
, mWasOpened(false)
|
||||||
|
, mConnectedParent(false)
|
||||||
, mLoadInfo(aLoadInfo)
|
, mLoadInfo(aLoadInfo)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -184,6 +202,10 @@ NS_IMETHODIMP nsExtProtocolChannel::Open2(nsIInputStream** aStream)
|
||||||
|
|
||||||
NS_IMETHODIMP nsExtProtocolChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *ctxt)
|
NS_IMETHODIMP nsExtProtocolChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *ctxt)
|
||||||
{
|
{
|
||||||
|
if (mConnectedParent) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
MOZ_ASSERT(!mLoadInfo ||
|
MOZ_ASSERT(!mLoadInfo ||
|
||||||
mLoadInfo->GetSecurityMode() == 0 ||
|
mLoadInfo->GetSecurityMode() == 0 ||
|
||||||
mLoadInfo->GetInitialSecurityCheckDone() ||
|
mLoadInfo->GetInitialSecurityCheckDone() ||
|
||||||
|
@ -338,6 +360,81 @@ NS_IMETHODIMP nsExtProtocolChannel::Resume()
|
||||||
return NS_ERROR_NOT_IMPLEMENTED;
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
// From nsIChildChannel
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsExtProtocolChannel::ConnectParent(uint32_t registrarId)
|
||||||
|
{
|
||||||
|
mozilla::dom::ContentChild::GetSingleton()->
|
||||||
|
SendExtProtocolChannelConnectParent(registrarId);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsExtProtocolChannel::CompleteRedirectSetup(nsIStreamListener *listener,
|
||||||
|
nsISupports *context)
|
||||||
|
{
|
||||||
|
// For redirects to external protocols we AsyncOpen on the child
|
||||||
|
// (not the parent) because child channel has the right docshell
|
||||||
|
// (which is needed for the select dialog).
|
||||||
|
return AsyncOpen(listener, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
// From nsIParentChannel (derives from nsIStreamListener)
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsExtProtocolChannel::SetParentListener(HttpChannelParentListener* aListener)
|
||||||
|
{
|
||||||
|
// This is called as part of the connect parent operation from
|
||||||
|
// ContentParent::RecvExtProtocolChannelConnectParent. Setting
|
||||||
|
// this flag tells this channel to not proceed and makes AsyncOpen
|
||||||
|
// just no-op. Actual operation will happen from the child process
|
||||||
|
// via CompleteRedirectSetup call on the child channel.
|
||||||
|
mConnectedParent = true;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsExtProtocolChannel::NotifyTrackingProtectionDisabled()
|
||||||
|
{
|
||||||
|
// nothing to do
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsExtProtocolChannel::Delete()
|
||||||
|
{
|
||||||
|
// nothing to do
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsExtProtocolChannel::OnStartRequest(nsIRequest *aRequest,
|
||||||
|
nsISupports *aContext)
|
||||||
|
{
|
||||||
|
// no data is expected
|
||||||
|
MOZ_CRASH("No data expected from external protocol channel");
|
||||||
|
return NS_ERROR_UNEXPECTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsExtProtocolChannel::OnStopRequest(nsIRequest *aRequest,
|
||||||
|
nsISupports *aContext,
|
||||||
|
nsresult aStatusCode)
|
||||||
|
{
|
||||||
|
// no data is expected
|
||||||
|
MOZ_CRASH("No data expected from external protocol channel");
|
||||||
|
return NS_ERROR_UNEXPECTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsExtProtocolChannel::OnDataAvailable(nsIRequest *aRequest,
|
||||||
|
nsISupports *aContext,
|
||||||
|
nsIInputStream *aInputStream,
|
||||||
|
uint64_t aOffset,
|
||||||
|
uint32_t aCount)
|
||||||
|
{
|
||||||
|
// no data is expected
|
||||||
|
MOZ_CRASH("No data expected from external protocol channel");
|
||||||
|
return NS_ERROR_UNEXPECTED;
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
// the default protocol handler implementation
|
// the default protocol handler implementation
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
Загрузка…
Ссылка в новой задаче