mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 15:23:51 +00:00
Bug 1380186 implement SimpleChannel Parent/Child IPC, r=kmag,mayhemer
MozReview-Commit-ID: 8zgF2MLwdu2 --HG-- extra : rebase_source : a5adcddb0119b8308a7beef74df998263dc8b620
This commit is contained in:
parent
02063c6559
commit
824d3d0d57
@ -3,10 +3,20 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "SimpleChannel.h"
|
||||
|
||||
#include "nsBaseChannel.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsIChildChannel.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIRequest.h"
|
||||
#include "SimpleChannel.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
#include "mozilla/Unused.h"
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/net/NeckoChild.h"
|
||||
#include "mozilla/net/PSimpleChannelChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
@ -22,7 +32,8 @@ namespace net {
|
||||
(target) = result.unwrap(); \
|
||||
} while (0)
|
||||
|
||||
class SimpleChannel final : public nsBaseChannel
|
||||
|
||||
class SimpleChannel : public nsBaseChannel
|
||||
{
|
||||
public:
|
||||
explicit SimpleChannel(UniquePtr<SimpleChannelCallbacks>&& aCallbacks);
|
||||
@ -78,10 +89,96 @@ SimpleChannel::BeginAsyncRead(nsIStreamListener* listener, nsIRequest** request)
|
||||
|
||||
#undef TRY_VAR
|
||||
|
||||
class SimpleChannelChild final : public SimpleChannel
|
||||
, public nsIChildChannel
|
||||
, public PSimpleChannelChild
|
||||
{
|
||||
public:
|
||||
explicit SimpleChannelChild(UniquePtr<SimpleChannelCallbacks>&& aCallbacks);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSICHILDCHANNEL
|
||||
|
||||
protected:
|
||||
virtual void ActorDestroy(ActorDestroyReason why) override;
|
||||
|
||||
private:
|
||||
virtual ~SimpleChannelChild() = default;
|
||||
|
||||
void AddIPDLReference();
|
||||
|
||||
RefPtr<SimpleChannelChild> mIPDLRef;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED(SimpleChannelChild, SimpleChannel, nsIChildChannel)
|
||||
|
||||
SimpleChannelChild::SimpleChannelChild(UniquePtr<SimpleChannelCallbacks>&& aCallbacks)
|
||||
: SimpleChannel(Move(aCallbacks))
|
||||
, mIPDLRef(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
SimpleChannelChild::ConnectParent(uint32_t aId)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mozilla::dom::ContentChild* cc =
|
||||
static_cast<mozilla::dom::ContentChild*>(gNeckoChild->Manager());
|
||||
if (cc->IsShuttingDown()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (!gNeckoChild->SendPSimpleChannelConstructor(this, aId)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// IPC now has a ref to us.
|
||||
mIPDLRef = this;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
SimpleChannelChild::CompleteRedirectSetup(nsIStreamListener* aListener,
|
||||
nsISupports* aContext)
|
||||
{
|
||||
if (mIPDLRef) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
if (mLoadInfo && mLoadInfo->GetEnforceSecurity()) {
|
||||
MOZ_ASSERT(!aContext, "aContext should be null!");
|
||||
rv = AsyncOpen2(aListener);
|
||||
} else {
|
||||
rv = AsyncOpen(aListener, aContext);
|
||||
}
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (mIPDLRef) {
|
||||
Unused << Send__delete__(this);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
SimpleChannelChild::ActorDestroy(ActorDestroyReason why)
|
||||
{
|
||||
MOZ_ASSERT(mIPDLRef);
|
||||
mIPDLRef = nullptr;
|
||||
}
|
||||
|
||||
|
||||
already_AddRefed<nsIChannel>
|
||||
NS_NewSimpleChannelInternal(nsIURI* aURI, nsILoadInfo* aLoadInfo, UniquePtr<SimpleChannelCallbacks>&& aCallbacks)
|
||||
{
|
||||
RefPtr<SimpleChannel> chan = new SimpleChannel(Move(aCallbacks));
|
||||
RefPtr<SimpleChannel> chan;
|
||||
if (IsNeckoChild()) {
|
||||
chan = new SimpleChannelChild(Move(aCallbacks));
|
||||
} else {
|
||||
chan = new SimpleChannel(Move(aCallbacks));
|
||||
}
|
||||
|
||||
chan->SetURI(aURI);
|
||||
|
||||
|
101
netwerk/base/SimpleChannelParent.cpp
Normal file
101
netwerk/base/SimpleChannelParent.cpp
Normal file
@ -0,0 +1,101 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim: set ts=4 sw=4 sts=4 et tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "SimpleChannelParent.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsIChannel.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
NS_IMPL_ISUPPORTS(SimpleChannelParent, nsIParentChannel, nsIStreamListener)
|
||||
|
||||
bool
|
||||
SimpleChannelParent::Init(const uint32_t &channelId)
|
||||
{
|
||||
nsCOMPtr<nsIChannel> channel;
|
||||
MOZ_ALWAYS_SUCCEEDS(
|
||||
NS_LinkRedirectChannels(channelId, this, getter_AddRefs(channel)));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
SimpleChannelParent::SetParentListener(HttpChannelParentListener* aListener)
|
||||
{
|
||||
// Nothing to do.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
SimpleChannelParent::NotifyTrackingProtectionDisabled()
|
||||
{
|
||||
// Nothing to do.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
SimpleChannelParent::NotifyTrackingResource()
|
||||
{
|
||||
// Nothing to do.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
SimpleChannelParent::SetClassifierMatchedInfo(const nsACString& aList,
|
||||
const nsACString& aProvider,
|
||||
const nsACString& aPrefix)
|
||||
{
|
||||
// nothing to do
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
SimpleChannelParent::Delete()
|
||||
{
|
||||
// Nothing to do.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
SimpleChannelParent::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
SimpleChannelParent::OnStartRequest(nsIRequest* aRequest,
|
||||
nsISupports* aContext)
|
||||
{
|
||||
// We don't have a way to prevent nsBaseChannel from calling AsyncOpen on
|
||||
// the created nsSimpleChannel. We don't have anywhere to send the data in the
|
||||
// parent, so abort the binding.
|
||||
return NS_BINDING_ABORTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
SimpleChannelParent::OnStopRequest(nsIRequest* aRequest,
|
||||
nsISupports* aContext,
|
||||
nsresult aStatusCode)
|
||||
{
|
||||
// See above.
|
||||
MOZ_ASSERT(NS_FAILED(aStatusCode));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
SimpleChannelParent::OnDataAvailable(nsIRequest* aRequest,
|
||||
nsISupports* aContext,
|
||||
nsIInputStream* aInputStream,
|
||||
uint64_t aOffset,
|
||||
uint32_t aCount)
|
||||
{
|
||||
// See above.
|
||||
MOZ_CRASH("Should never be called");
|
||||
}
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
41
netwerk/base/SimpleChannelParent.h
Normal file
41
netwerk/base/SimpleChannelParent.h
Normal file
@ -0,0 +1,41 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim: set ts=4 sw=4 sts=4 et tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef NS_SIMPLECHANNELPARENT_H
|
||||
#define NS_SIMPLECHANNELPARENT_H
|
||||
|
||||
#include "nsIParentChannel.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
|
||||
#include "mozilla/net/PSimpleChannelParent.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
// In order to support HTTP redirects, we need to implement the HTTP
|
||||
// redirection API, which requires a class that implements nsIParentChannel
|
||||
// and which calls NS_LinkRedirectChannels.
|
||||
class SimpleChannelParent : public nsIParentChannel
|
||||
, public PSimpleChannelParent
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIPARENTCHANNEL
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
NS_DECL_NSISTREAMLISTENER
|
||||
|
||||
MOZ_MUST_USE bool Init(const uint32_t& aArgs);
|
||||
|
||||
private:
|
||||
~SimpleChannelParent() = default;
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason why) override;
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
||||
#endif /* NS_SIMPLECHANNELPARENT_H */
|
@ -179,6 +179,7 @@ EXPORTS.mozilla.net += [
|
||||
'MemoryDownloader.h',
|
||||
'Predictor.h',
|
||||
'ReferrerPolicy.h',
|
||||
'SimpleChannelParent.h',
|
||||
'TCPFastOpen.h',
|
||||
]
|
||||
|
||||
@ -249,6 +250,7 @@ UNIFIED_SOURCES += [
|
||||
'RequestContextService.cpp',
|
||||
'SimpleBuffer.cpp',
|
||||
'SimpleChannel.cpp',
|
||||
'SimpleChannelParent.cpp',
|
||||
'StreamingProtocolService.cpp',
|
||||
'TCPFastOpenLayer.cpp',
|
||||
'ThrottleQueue.cpp',
|
||||
|
@ -261,6 +261,20 @@ NeckoChild::DeallocPFileChannelChild(PFileChannelChild* child)
|
||||
return true;
|
||||
}
|
||||
|
||||
PSimpleChannelChild*
|
||||
NeckoChild::AllocPSimpleChannelChild(const uint32_t& channelId)
|
||||
{
|
||||
MOZ_ASSERT_UNREACHABLE("Should never get here");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
NeckoChild::DeallocPSimpleChannelChild(PSimpleChannelChild* child)
|
||||
{
|
||||
// NB: See SimpleChannelChild::ActorDestroy.
|
||||
return true;
|
||||
}
|
||||
|
||||
PRtspControllerChild*
|
||||
NeckoChild::AllocPRtspControllerChild()
|
||||
{
|
||||
|
@ -71,6 +71,8 @@ protected:
|
||||
virtual bool DeallocPDataChannelChild(PDataChannelChild* child) override;
|
||||
virtual PFileChannelChild* AllocPFileChannelChild(const uint32_t& channelId) override;
|
||||
virtual bool DeallocPFileChannelChild(PFileChannelChild* child) override;
|
||||
virtual PSimpleChannelChild* AllocPSimpleChannelChild(const uint32_t& channelId) override;
|
||||
virtual bool DeallocPSimpleChannelChild(PSimpleChannelChild* child) override;
|
||||
virtual PRtspControllerChild* AllocPRtspControllerChild() override;
|
||||
virtual bool DeallocPRtspControllerChild(PRtspControllerChild*) override;
|
||||
virtual PRtspChannelChild*
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "mozilla/net/WebSocketChannelParent.h"
|
||||
#include "mozilla/net/WebSocketEventListenerParent.h"
|
||||
#include "mozilla/net/DataChannelParent.h"
|
||||
#include "mozilla/net/SimpleChannelParent.h"
|
||||
#include "mozilla/net/AltDataOutputStreamParent.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "mozilla/net/FileChannelParent.h"
|
||||
@ -530,6 +531,29 @@ NeckoParent::RecvPDataChannelConstructor(PDataChannelParent* actor,
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
PSimpleChannelParent*
|
||||
NeckoParent::AllocPSimpleChannelParent(const uint32_t &channelId)
|
||||
{
|
||||
RefPtr<SimpleChannelParent> p = new SimpleChannelParent();
|
||||
return p.forget().take();
|
||||
}
|
||||
|
||||
bool
|
||||
NeckoParent::DeallocPSimpleChannelParent(PSimpleChannelParent* actor)
|
||||
{
|
||||
RefPtr<SimpleChannelParent> p = dont_AddRef(actor).downcast<SimpleChannelParent>();
|
||||
return true;
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
NeckoParent::RecvPSimpleChannelConstructor(PSimpleChannelParent* actor,
|
||||
const uint32_t& channelId)
|
||||
{
|
||||
SimpleChannelParent* p = static_cast<SimpleChannelParent*>(actor);
|
||||
MOZ_ALWAYS_TRUE(p->Init(channelId));
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
PFileChannelParent*
|
||||
NeckoParent::AllocPFileChannelParent(const uint32_t &channelId)
|
||||
{
|
||||
|
@ -182,6 +182,13 @@ protected:
|
||||
virtual mozilla::ipc::IPCResult RecvPDataChannelConstructor(PDataChannelParent* aActor,
|
||||
const uint32_t& channelId) override;
|
||||
|
||||
virtual PSimpleChannelParent*
|
||||
AllocPSimpleChannelParent(const uint32_t& channelId) override;
|
||||
virtual bool DeallocPSimpleChannelParent(PSimpleChannelParent* parent) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvPSimpleChannelConstructor(PSimpleChannelParent* aActor,
|
||||
const uint32_t& channelId) override;
|
||||
|
||||
virtual PFileChannelParent*
|
||||
AllocPFileChannelParent(const uint32_t& channelId) override;
|
||||
virtual bool DeallocPFileChannelParent(PFileChannelParent* parent) override;
|
||||
|
@ -20,6 +20,7 @@ include protocol PDNSRequest;
|
||||
include protocol PChannelDiverter;
|
||||
include protocol PFileDescriptorSet;
|
||||
include protocol PDataChannel;
|
||||
include protocol PSimpleChannel;
|
||||
include protocol PTransportProvider;
|
||||
include protocol PChildToParentStream; //FIXME: bug #792908
|
||||
include protocol PParentToChildStream; //FIXME: bug #792908
|
||||
@ -56,6 +57,7 @@ nested(upto inside_cpow) sync protocol PNecko
|
||||
manages PUDPSocket;
|
||||
manages PDNSRequest;
|
||||
manages PDataChannel;
|
||||
manages PSimpleChannel;
|
||||
manages PFileChannel;
|
||||
manages PRtspController;
|
||||
manages PRtspChannel;
|
||||
@ -104,7 +106,7 @@ parent:
|
||||
* the parent and the child when we're redirecting to a data: URI.
|
||||
*/
|
||||
async PDataChannel(uint32_t channelId);
|
||||
|
||||
async PSimpleChannel(uint32_t channelId);
|
||||
async PFileChannel(uint32_t channelId);
|
||||
|
||||
async PRtspController();
|
||||
|
25
netwerk/ipc/PSimpleChannel.ipdl
Normal file
25
netwerk/ipc/PSimpleChannel.ipdl
Normal file
@ -0,0 +1,25 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set sw=2 ts=8 et tw=80 ft=cpp : */
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
include protocol PNecko;
|
||||
include URIParams;
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
async protocol PSimpleChannel
|
||||
{
|
||||
manager PNecko;
|
||||
|
||||
parent:
|
||||
// Note: channels are opened during construction, so no open method here:
|
||||
// see PNecko.ipdl
|
||||
async __delete__();
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
@ -29,6 +29,7 @@ IPDL_SOURCES = [
|
||||
'PNecko.ipdl',
|
||||
'PRtspChannel.ipdl',
|
||||
'PRtspController.ipdl',
|
||||
'PSimpleChannel.ipdl',
|
||||
]
|
||||
|
||||
# needed so --disable-webrtc builds work (yes, a bit messy)
|
||||
|
@ -55,6 +55,12 @@ function getData(channel) {
|
||||
return extractFromChannel(channel, key) || attachToChannel(channel, key, {});
|
||||
}
|
||||
|
||||
function getFinalChannelURI(channel) {
|
||||
let {loadInfo} = channel;
|
||||
// resultPrincipalURI may be null, but originalURI never will be.
|
||||
return (loadInfo && loadInfo.resultPrincipalURI) || channel.originalURI;
|
||||
}
|
||||
|
||||
var RequestId = {
|
||||
count: 1,
|
||||
create(channel = null) {
|
||||
@ -753,9 +759,10 @@ HttpObserverManager = {
|
||||
getRequestData(channel, loadContext, policyType, extraData) {
|
||||
let {loadInfo} = channel;
|
||||
|
||||
let URI = getFinalChannelURI(channel);
|
||||
let data = {
|
||||
requestId: RequestId.get(channel),
|
||||
url: channel.URI.spec,
|
||||
url: URI.spec,
|
||||
method: channel.requestMethod,
|
||||
browser: loadContext && loadContext.topFrameElement,
|
||||
type: WebRequestCommon.typeForPolicyType(policyType),
|
||||
@ -831,7 +838,10 @@ HttpObserverManager = {
|
||||
canModify(channel) {
|
||||
let {isHostPermitted} = AddonManagerPermissions;
|
||||
|
||||
if (isHostPermitted(channel.URI.host)) {
|
||||
// Bug 1334550 introduced the possibility of having a JAR uri here,
|
||||
// use the result uri if possible in that case.
|
||||
let URI = getFinalChannelURI(channel);
|
||||
if (URI && isHostPermitted(URI.host)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -872,7 +882,7 @@ HttpObserverManager = {
|
||||
|
||||
let canModify = this.canModify(channel);
|
||||
let commonData = null;
|
||||
let uri = channel.URI;
|
||||
let uri = getFinalChannelURI(channel);
|
||||
let requestBody;
|
||||
for (let [callback, opts] of this.listeners[kind].entries()) {
|
||||
if (!this.shouldRunListener(policyType, uri, opts.filter)) {
|
||||
@ -1055,8 +1065,10 @@ HttpObserverManager = {
|
||||
},
|
||||
|
||||
onChannelReplaced(oldChannel, newChannel) {
|
||||
// We want originalURI, this will provide a moz-ext rather than jar or file
|
||||
// uri on redirects.
|
||||
this.runChannelListener(oldChannel, this.getLoadContext(oldChannel),
|
||||
"onRedirect", {redirectUrl: newChannel.URI.spec});
|
||||
"onRedirect", {redirectUrl: newChannel.originalURI.spec});
|
||||
},
|
||||
|
||||
onStartRequest(channel, loadContext) {
|
||||
|
Loading…
Reference in New Issue
Block a user