Bug 1604447 - Remove channel diversion code. r=dragana,necko-reviewers

Differential Revision: https://phabricator.services.mozilla.com/D90193
This commit is contained in:
Matt Woodrow 2020-09-18 20:56:54 +00:00
Родитель 00089ecfb4
Коммит 9638778ace
46 изменённых файлов: 184 добавлений и 2580 удалений

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

@ -1,59 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 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 _adivertablechannelparent_h_
#define _adivertablechannelparent_h_
#include "nsISupports.h"
class nsIStreamListener;
namespace mozilla {
namespace net {
// To be implemented by a channel's parent actors, e.g. HttpChannelParent
// and FTPChannelParent. Used by ChannelDiverterParent to divert
// nsIStreamListener callbacks from the child process to a new
// listener in the parent process.
class ADivertableParentChannel : public nsISupports {
public:
// Called by ChannelDiverterParent::DivertTo(nsIStreamListener*).
// The listener should now be used to received nsIStreamListener callbacks,
// i.e. OnStartRequest, OnDataAvailable and OnStopRequest, as if it had been
// passed to AsyncOpen for the channel. A reference to the listener will be
// added and kept until OnStopRequest has completed.
virtual void DivertTo(nsIStreamListener* aListener) = 0;
// Called to suspend parent channel in ChannelDiverterParent constructor.
virtual nsresult SuspendForDiversion() = 0;
// While messages are diverted back from the child to the parent calls to
// suspend/resume the channel must also suspend/resume the message diversion.
// These two functions will be called by nsHttpChannel and nsFtpChannel
// Suspend()/Resume() functions.
virtual nsresult SuspendMessageDiversion() = 0;
virtual nsresult ResumeMessageDiversion() = 0;
// Cancel an ongoing diversion by using IPC to invoke Cancel() in the child.
// This is necessary because most of the channel's state machine is suspended
// during diversion, so an explicit action must be taken to interrupt the
// diversion process so cancellation can be fully processed.
//
// Historically, diversions were assumed to be shortlived, where it was merely
// a question of diverting some small amount of network traffic back to the
// parent. However, Service Worker child interception made it possible for
// the data to entirely be sourced from the child, which makes diversion
// potentially long-lived. Especially when large files are involved.
//
// This mechanism is expected to be removed when ServiceWorkers move from
// child intercept to parent intercept (in the short to medium term).
virtual nsresult CancelDiversion() = 0;
};
} // namespace net
} // namespace mozilla
#endif

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

@ -1,16 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 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 "mozilla/net/ChannelDiverterChild.h"
#include "mozilla/net/NeckoChannelParams.h"
#include "mozilla/net/HttpChannelChild.h"
#include "mozilla/net/FTPChannelChild.h"
#include "mozilla/net/PHttpChannelChild.h"
#include "mozilla/net/PFTPChannelChild.h"
namespace mozilla {
namespace net {} // namespace net
} // namespace mozilla

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

@ -1,24 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 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 _channeldiverterchild_h_
#define _channeldiverterchild_h_
#include "mozilla/net/PChannelDiverterChild.h"
namespace mozilla {
namespace net {
class ChannelDiverterChild : public PChannelDiverterChild {
public:
ChannelDiverterChild() = default;
virtual ~ChannelDiverterChild() = default;
};
} // namespace net
} // namespace mozilla
#endif /* _channeldiverterchild_h_ */

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

@ -1,60 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 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 "mozilla/net/ChannelDiverterParent.h"
#include "mozilla/net/NeckoChannelParams.h"
#include "mozilla/net/HttpChannelParent.h"
#include "mozilla/net/FTPChannelParent.h"
#include "mozilla/net/PHttpChannelParent.h"
#include "mozilla/net/PFTPChannelParent.h"
#include "ADivertableParentChannel.h"
namespace mozilla {
namespace net {
bool ChannelDiverterParent::Init(const ChannelDiverterArgs& aArgs) {
switch (aArgs.type()) {
case ChannelDiverterArgs::THttpChannelDiverterArgs: {
auto httpParent = static_cast<HttpChannelParent*>(
aArgs.get_HttpChannelDiverterArgs().mChannelParent());
httpParent->SetApplyConversion(
aArgs.get_HttpChannelDiverterArgs().mApplyConversion());
mDivertableChannelParent =
static_cast<ADivertableParentChannel*>(httpParent);
break;
}
case ChannelDiverterArgs::TPFTPChannelParent: {
mDivertableChannelParent = static_cast<ADivertableParentChannel*>(
static_cast<FTPChannelParent*>(aArgs.get_PFTPChannelParent()));
break;
}
default:
MOZ_ASSERT_UNREACHABLE("unknown ChannelDiverterArgs type");
return false;
}
MOZ_ASSERT(mDivertableChannelParent);
nsresult rv = mDivertableChannelParent->SuspendForDiversion();
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
return true;
}
void ChannelDiverterParent::DivertTo(nsIStreamListener* newListener) {
MOZ_ASSERT(newListener);
MOZ_ASSERT(mDivertableChannelParent);
mDivertableChannelParent->DivertTo(newListener);
}
void ChannelDiverterParent::ActorDestroy(ActorDestroyReason aWhy) {
// Implement me! Bug 1005179
}
} // namespace net
} // namespace mozilla

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

@ -1,38 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 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 _channeldiverterparent_h_
#define _channeldiverterparent_h_
#include "mozilla/net/PChannelDiverterParent.h"
class nsIStreamListener;
namespace mozilla {
namespace net {
class ChannelDiverterArgs;
class ADivertableParentChannel;
class ChannelDiverterParent : public PChannelDiverterParent {
public:
ChannelDiverterParent() = default;
virtual ~ChannelDiverterParent() = default;
bool Init(const ChannelDiverterArgs& aArgs);
void DivertTo(nsIStreamListener* newListener);
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
private:
RefPtr<ADivertableParentChannel> mDivertableChannelParent;
};
} // namespace net
} // namespace mozilla
#endif /* _channeldiverterparent_h_ */

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

@ -10,6 +10,7 @@
#include "mozilla/net/SocketProcessParent.h"
#include "nsHttp.h"
#include "nsICancelable.h"
#include "nsIDNSListener.h"
#include "nsIDNSService.h"
#include "nsIDNSRecord.h"
#include "nsIInputStream.h"

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

@ -7,6 +7,7 @@
#include "mozilla/Services.h"
#include "xpcpublic.h"
#include "nsSocketTransport2.h"
#include "nsIHttpChannelInternal.h"
#include "nsINetworkLinkService.h"
static LazyLogModule gNCSLog("NetworkConnectivityService");

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

@ -30,7 +30,6 @@ XPIDL_SOURCES += [
'nsICaptivePortalService.idl',
'nsIChannel.idl',
'nsIChannelEventSink.idl',
'nsIChannelWithDivertableParentListener.idl',
'nsIChildChannel.idl',
'nsIClassifiedChannel.idl',
'nsIClassOfService.idl',
@ -39,7 +38,6 @@ XPIDL_SOURCES += [
'nsIDashboardEventNotifier.idl',
'nsIDeprecationWarner.idl',
'nsIDHCPClient.idl',
'nsIDivertableChannel.idl',
'nsIDownloader.idl',
'nsIEncodedChannel.idl',
'nsIExternalProtocolHandler.idl',
@ -161,8 +159,6 @@ EXPORTS.mozilla += [
EXPORTS.mozilla.net += [
'CaptivePortalService.h',
'ChannelDiverterChild.h',
'ChannelDiverterParent.h',
'Dashboard.h',
'DashboardTypes.h',
'DefaultURI.h',
@ -184,8 +180,6 @@ UNIFIED_SOURCES += [
'ArrayBufferInputStream.cpp',
'BackgroundFileSaver.cpp',
'CaptivePortalService.cpp',
'ChannelDiverterChild.cpp',
'ChannelDiverterParent.cpp',
'Dashboard.cpp',
'DefaultURI.cpp',
'EventTokenBucket.cpp',

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

@ -1,46 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 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 "nsISupports.idl"
%{C++
namespace mozilla {
namespace net {
class ADivertableParentChannel;
}
}
%}
[ptr] native ADivertableParentChannelPtr(mozilla::net::ADivertableParentChannel);
/** When we are diverting messages from the child to the parent. The
* nsHttpChannel and nsFtpChannel must know that there is a ChannelParent to
* be able to suspend message delivery if the channel is suspended.
*/
[uuid(c073d79f-2503-4dff-ba87-d3071f8b433b)]
interface nsIChannelWithDivertableParentListener : nsISupports
{
/**
* Informs nsHttpChannel or nsFtpChannel that a ParentChannel starts
* diverting messages. During this time all suspend/resume calls to the
* channel must also suspend the ParentChannel by calling
* SuspendMessageDiversion/ResumeMessageDiversion.
*/
void MessageDiversionStarted(in ADivertableParentChannelPtr aParentChannel);
/**
* The message diversion has finished the calls to
* SuspendMessageDiversion/ResumeMessageDiversion are not necessary anymore.
*/
void MessageDiversionStop();
/**
* Internal versions of Suspend/Resume that suspend (or resume) the channel
* but do not suspend the ParentChannel's IPDL message queue.
*/
void SuspendInternal();
void ResumeInternal();
};

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

@ -1,78 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 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 "nsISupports.idl"
%{C++
namespace mozilla {
namespace net {
class ChannelDiverterChild;
}
}
%}
[ptr] native ChannelDiverterChild(mozilla::net::ChannelDiverterChild);
interface nsIStreamListener;
/**
* A channel implementing this interface allows diverting from an
* nsIStreamListener in the child process to one in the parent.
*/
[uuid(7a9bf52d-f828-4b31-b8df-b40fdd37d007)]
interface nsIDivertableChannel : nsISupports
{
/**
* CHILD ONLY.
* Called by Necko client in child process during OnStartRequest to divert
* nsIStreamListener and nsIRequest callbacks to the parent process.
*
* The process should look like the following:
*
* 1) divertToParent is called in the child process. It can only be called
* during OnStartRequest().
*
* 2) The ChannelDiverterChild that is returned is an IPDL object. It should
* be passed via some other IPDL method of the client's choosing to the
* parent. On the parent the ChannelDiverterParent's divertTo() function
* should be called with an nsIStreamListener that will then receive the
* OnStartRequest/OnDataAvailable/OnStopRequest for the channel. The
* ChannelDiverterParent can then be deleted (which will also destroy the
* ChannelDiverterChild in the child).
*
* After divertToParent() has been called, NO further function calls
* should be made on the channel. It is a dead object for all purposes.
* The reference that the channel holds to the listener in the child is
* released is once OnStartRequest completes, and no other
* nsIStreamListener calls (OnDataAvailable, OnStopRequest) will be made
* to it.
*
* @return ChannelDiverterChild IPDL actor to be passed to parent process by
* client IPDL message, e.g. PClient.DivertUsing(PDiverterChild).
*
* @throws exception if the channel was canceled early. Throws status code of
* canceled channel.
*/
ChannelDiverterChild divertToParent();
/**
* nsUnknownDecoder delays calling OnStartRequest until it gets enough data
* to decide about the content type (until OnDataAvaiable is called). In a
* OnStartRequest DivertToParent can be called but some OnDataAvailables are
* already called and therefore can not be diverted to parent.
*
* nsUnknownDecoder will call UnknownDecoderInvolvedKeepData in its
* OnStartRequest function and when it calls OnStartRequest of the next
* listener it will call UnknownDecoderInvolvedOnStartRequestCalled. In this
* function Child process will decide to discarge data if it is not diverting
* to parent or keep them if it is diverting to parent.
*/
void unknownDecoderInvolvedKeepData();
void unknownDecoderInvolvedOnStartRequestCalled();
readonly attribute bool divertingToParent;
};

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

@ -405,18 +405,6 @@ union FTPChannelCreationArgs
FTPChannelConnectArgs; // Used for redirected-to channels
};
struct HttpChannelDiverterArgs
{
PHttpChannel mChannel;
bool mApplyConversion;
};
union ChannelDiverterArgs
{
HttpChannelDiverterArgs;
PFTPChannel;
};
struct CookieStruct
{
nsCString name;

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

@ -17,7 +17,6 @@
#include "mozilla/net/WebSocketChannelChild.h"
#include "mozilla/net/WebSocketEventListenerChild.h"
#include "mozilla/net/DNSRequestChild.h"
#include "mozilla/net/ChannelDiverterChild.h"
#include "mozilla/net/IPCTransportProvider.h"
#include "mozilla/dom/network/TCPSocketChild.h"
#include "mozilla/dom/network/TCPServerSocketChild.h"
@ -246,17 +245,6 @@ bool NeckoChild::DeallocPUDPSocketChild(PUDPSocketChild* child) {
return true;
}
PChannelDiverterChild* NeckoChild::AllocPChannelDiverterChild(
const ChannelDiverterArgs& channel) {
return new ChannelDiverterChild();
;
}
bool NeckoChild::DeallocPChannelDiverterChild(PChannelDiverterChild* child) {
delete static_cast<ChannelDiverterChild*>(child);
return true;
}
PTransportProviderChild* NeckoChild::AllocPTransportProviderChild() {
// This refcount is transferred to the receiver of the message that
// includes the PTransportProviderChild actor.

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

@ -58,9 +58,6 @@ class NeckoChild : public PNeckoChild {
bool DeallocPUDPSocketChild(PUDPSocketChild*);
PSimpleChannelChild* AllocPSimpleChannelChild(const uint32_t& channelId);
bool DeallocPSimpleChannelChild(PSimpleChannelChild* child);
PChannelDiverterChild* AllocPChannelDiverterChild(
const ChannelDiverterArgs& channel);
bool DeallocPChannelDiverterChild(PChannelDiverterChild* actor);
PTransportProviderChild* AllocPTransportProviderChild();
bool DeallocPTransportProviderChild(PTransportProviderChild* aActor);
mozilla::ipc::IPCResult RecvAsyncAuthPromptForNestedFrame(

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

@ -24,7 +24,6 @@
#include "mozilla/Unused.h"
#include "mozilla/net/FileChannelParent.h"
#include "mozilla/net/DNSRequestParent.h"
#include "mozilla/net/ChannelDiverterParent.h"
#include "mozilla/net/ClassifierDummyChannelParent.h"
#include "mozilla/net/IPCTransportProvider.h"
#include "mozilla/net/RequestContextService.h"
@ -554,24 +553,6 @@ mozilla::ipc::IPCResult NeckoParent::RecvCancelHTMLDNSPrefetch(
return IPC_OK();
}
PChannelDiverterParent* NeckoParent::AllocPChannelDiverterParent(
const ChannelDiverterArgs& channel) {
return new ChannelDiverterParent();
}
mozilla::ipc::IPCResult NeckoParent::RecvPChannelDiverterConstructor(
PChannelDiverterParent* actor, const ChannelDiverterArgs& channel) {
auto parent = static_cast<ChannelDiverterParent*>(actor);
parent->Init(channel);
return IPC_OK();
}
bool NeckoParent::DeallocPChannelDiverterParent(
PChannelDiverterParent* parent) {
delete static_cast<ChannelDiverterParent*>(parent);
return true;
}
PTransportProviderParent* NeckoParent::AllocPTransportProviderParent() {
RefPtr<TransportProviderParent> res = new TransportProviderParent();
return res.forget().take();

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

@ -189,12 +189,6 @@ class NeckoParent : public PNeckoParent {
virtual mozilla::ipc::IPCResult RecvPFileChannelConstructor(
PFileChannelParent* aActor, const uint32_t& channelId) override;
PChannelDiverterParent* AllocPChannelDiverterParent(
const ChannelDiverterArgs& channel);
virtual mozilla::ipc::IPCResult RecvPChannelDiverterConstructor(
PChannelDiverterParent* actor,
const ChannelDiverterArgs& channel) override;
bool DeallocPChannelDiverterParent(PChannelDiverterParent* actor);
PTransportProviderParent* AllocPTransportProviderParent();
bool DeallocPTransportProviderParent(PTransportProviderParent* aActor);

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

@ -1,25 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 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 PFTPChannel;
include protocol PHttpChannel;
include protocol PNecko;
namespace mozilla {
namespace net {
// Used when diverting necko channels from child back to the parent.
// See nsIDivertableChannel.
async protocol PChannelDiverter
{
manager PNecko;
child:
async __delete__();
};
}// namespace net
}// namespace mozilla

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

@ -16,7 +16,6 @@ include protocol PTCPSocket;
include protocol PTCPServerSocket;
include protocol PUDPSocket;
include protocol PDNSRequest;
include protocol PChannelDiverter;
include protocol PFileDescriptorSet;
include protocol PDataChannel;
include protocol PSimpleChannel;
@ -61,7 +60,6 @@ nested(upto inside_cpow) sync protocol PNecko
manages PDataChannel;
manages PSimpleChannel;
manages PFileChannel;
manages PChannelDiverter;
manages PTransportProvider;
manages PAltDataOutputStream;
manages PStunAddrsRequest;
@ -115,8 +113,6 @@ parent:
async PSimpleChannel(uint32_t channelId);
async PFileChannel(uint32_t channelId);
async PChannelDiverter(ChannelDiverterArgs channel);
async PClassifierDummyChannel(nsIURI uri, nsIURI aTopWindowURI,
nsresult aTopWindowURIResult,
LoadInfoArgs? loadInfo);

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

@ -56,7 +56,6 @@ UNIFIED_SOURCES += [
IPDL_SOURCES = [
'NeckoChannelParams.ipdlh',
'PChannelDiverter.ipdl',
'PDataChannel.ipdl',
'PDocumentChannel.ipdl',
'PFileChannel.ipdl',

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

@ -6,7 +6,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/net/NeckoChild.h"
#include "mozilla/net/ChannelDiverterChild.h"
#include "mozilla/net/FTPChannelChild.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/DocGroup.h"
@ -36,14 +35,11 @@ namespace net {
FTPChannelChild::FTPChannelChild(nsIURI* aUri)
: mIPCOpen(false),
mEventQ(new ChannelEventQueue(static_cast<nsIFTPChannel*>(this))),
mUnknownDecoderInvolved(false),
mCanceled(false),
mSuspendCount(0),
mIsPending(false),
mLastModifiedTime(0),
mStartPos(0),
mDivertingToParent(false),
mFlushedForDiversion(false),
mSuspendSent(false) {
LOG(("Creating FTPChannelChild @%p\n", this));
// grab a reference to the handler to ensure that it doesn't go away.
@ -78,8 +74,7 @@ void FTPChannelChild::ReleaseIPDLReference() {
NS_IMPL_ISUPPORTS_INHERITED(FTPChannelChild, nsBaseChannel, nsIFTPChannel,
nsIUploadChannel, nsIResumableChannel,
nsIProxiedChannel, nsIChildChannel,
nsIDivertableChannel)
nsIProxiedChannel, nsIChildChannel)
//-----------------------------------------------------------------------------
@ -229,15 +224,6 @@ mozilla::ipc::IPCResult FTPChannelChild::RecvOnStartRequest(
const nsresult& aChannelStatus, const int64_t& aContentLength,
const nsCString& aContentType, const PRTime& aLastModified,
const nsCString& aEntityID, const URIParams& aURI) {
// mFlushedForDiversion and mDivertingToParent should NEVER be set at this
// stage, as they are set in the listener's OnStartRequest.
MOZ_RELEASE_ASSERT(
!mFlushedForDiversion,
"mFlushedForDiversion should be unset before OnStartRequest!");
MOZ_RELEASE_ASSERT(
!mDivertingToParent,
"mDivertingToParent should be unset before OnStartRequest!");
LOG(("FTPChannelChild::RecvOnStartRequest [this=%p]\n", this));
mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(
@ -262,15 +248,6 @@ void FTPChannelChild::DoOnStartRequest(const nsresult& aChannelStatus,
LOG(("FTPChannelChild::DoOnStartRequest [this=%p]\n", this));
// mFlushedForDiversion and mDivertingToParent should NEVER be set at this
// stage, as they are set in the listener's OnStartRequest.
MOZ_RELEASE_ASSERT(
!mFlushedForDiversion,
"mFlushedForDiversion should be unset before OnStartRequest!");
MOZ_RELEASE_ASSERT(
!mDivertingToParent,
"mDivertingToParent should be unset before OnStartRequest!");
if (!mCanceled && NS_SUCCEEDED(mStatus)) {
mStatus = aChannelStatus;
}
@ -296,31 +273,18 @@ void FTPChannelChild::DoOnStartRequest(const nsresult& aChannelStatus,
AutoEventEnqueuer ensureSerialDispatch(mEventQ);
rv = mListener->OnStartRequest(this);
if (NS_FAILED(rv)) Cancel(rv);
if (mDivertingToParent) {
mListener = nullptr;
if (mLoadGroup) {
mLoadGroup->RemoveRequest(this, nullptr, mStatus);
}
}
}
mozilla::ipc::IPCResult FTPChannelChild::RecvOnDataAvailable(
const nsresult& aChannelStatus, const nsCString& aData,
const uint64_t& aOffset, const uint32_t& aCount) {
MOZ_RELEASE_ASSERT(!mFlushedForDiversion,
"Should not be receiving any more callbacks from parent!");
LOG(("FTPChannelChild::RecvOnDataAvailable [this=%p]\n", this));
mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(
this,
[self = UnsafePtr<FTPChannelChild>(this),
aChannelStatus, aData, aOffset, aCount]() {
self->DoOnDataAvailable(aChannelStatus, aData,
aOffset, aCount);
}),
mDivertingToParent);
this, [self = UnsafePtr<FTPChannelChild>(this), aChannelStatus, aData,
aOffset, aCount]() {
self->DoOnDataAvailable(aChannelStatus, aData, aOffset, aCount);
}));
return IPC_OK();
}
@ -335,30 +299,10 @@ void FTPChannelChild::DoOnDataAvailable(const nsresult& aChannelStatus,
mStatus = aChannelStatus;
}
if (mDivertingToParent) {
MOZ_RELEASE_ASSERT(
!mFlushedForDiversion,
"Should not be processing any more callbacks from parent!");
SendDivertOnDataAvailable(aData, aOffset, aCount);
return;
}
if (mCanceled) {
return;
}
if (mUnknownDecoderInvolved) {
mUnknownDecoderEventQ.AppendElement(
MakeUnique<NeckoTargetChannelFunctionEvent>(
this, [self = UnsafePtr<FTPChannelChild>(this), aData, aOffset,
aCount]() {
if (self->mDivertingToParent) {
self->SendDivertOnDataAvailable(aData, aOffset, aCount);
}
}));
}
// NOTE: the OnDataAvailable contract requires the client to read all the data
// in the inputstream. This code relies on that ('data' will go away after
// this function). Apparently the previous, non-e10s behavior was to actually
@ -384,9 +328,6 @@ void FTPChannelChild::DoOnDataAvailable(const nsresult& aChannelStatus,
mozilla::ipc::IPCResult FTPChannelChild::RecvOnStopRequest(
const nsresult& aChannelStatus, const nsCString& aErrorMsg,
const bool& aUseUTF8) {
MOZ_RELEASE_ASSERT(!mFlushedForDiversion,
"Should not be receiving any more callbacks from parent!");
LOG(("FTPChannelChild::RecvOnStopRequest [this=%p status=%" PRIx32 "]\n",
this, static_cast<uint32_t>(aChannelStatus)));
@ -404,27 +345,8 @@ void FTPChannelChild::DoOnStopRequest(const nsresult& aChannelStatus,
LOG(("FTPChannelChild::DoOnStopRequest [this=%p status=%" PRIx32 "]\n", this,
static_cast<uint32_t>(aChannelStatus)));
if (mDivertingToParent) {
MOZ_RELEASE_ASSERT(
!mFlushedForDiversion,
"Should not be processing any more callbacks from parent!");
SendDivertOnStopRequest(aChannelStatus);
return;
}
if (!mCanceled) mStatus = aChannelStatus;
if (mUnknownDecoderInvolved) {
mUnknownDecoderEventQ.AppendElement(
MakeUnique<NeckoTargetChannelFunctionEvent>(
this, [self = UnsafePtr<FTPChannelChild>(this), aChannelStatus]() {
if (self->mDivertingToParent) {
self->SendDivertOnStopRequest(aChannelStatus);
}
}));
}
{ // Ensure that all queued ipdl events are dispatched before
// we initiate protocol deletion below.
mIsPending = false;
@ -478,42 +400,6 @@ void FTPChannelChild::DoFailedAsyncOpen(const nsresult& aStatusCode) {
}
}
mozilla::ipc::IPCResult FTPChannelChild::RecvFlushedForDiversion() {
LOG(("FTPChannelChild::RecvFlushedForDiversion [this=%p]\n", this));
MOZ_ASSERT(mDivertingToParent);
mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(
this, [self = UnsafePtr<FTPChannelChild>(this)]() {
self->FlushedForDiversion();
}));
return IPC_OK();
}
void FTPChannelChild::FlushedForDiversion() {
LOG(("FTPChannelChild::FlushedForDiversion [this=%p]\n", this));
MOZ_RELEASE_ASSERT(mDivertingToParent);
// Once this is set, it should not be unset before FTPChannelChild is taken
// down. After it is set, no OnStart/OnData/OnStop callbacks should be
// received from the parent channel, nor dequeued from the ChannelEventQueue.
mFlushedForDiversion = true;
SendDivertComplete();
}
mozilla::ipc::IPCResult FTPChannelChild::RecvDivertMessages() {
LOG(("FTPChannelChild::RecvDivertMessages [this=%p]\n", this));
MOZ_RELEASE_ASSERT(mDivertingToParent);
MOZ_RELEASE_ASSERT(mSuspendCount > 0);
// DivertTo() has been called on parent, so we can now start sending queued
// IPDL messages back to parent listener.
if (NS_WARN_IF(NS_FAILED(Resume()))) {
return IPC_FAIL_NO_REASON(this);
}
return IPC_OK();
}
mozilla::ipc::IPCResult FTPChannelChild::RecvDeleteSelf() {
mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(
this,
@ -549,9 +435,7 @@ FTPChannelChild::Suspend() {
LOG(("FTPChannelChild::Suspend [this=%p]\n", this));
// SendSuspend only once, when suspend goes from 0 to 1.
// Don't SendSuspend at all if we're diverting callbacks to the parent;
// suspend will be called at the correct time in the parent itself.
if (!mSuspendCount++ && !mDivertingToParent) {
if (!mSuspendCount++) {
SendSuspend();
mSuspendSent = true;
}
@ -567,10 +451,7 @@ FTPChannelChild::Resume() {
LOG(("FTPChannelChild::Resume [this=%p]\n", this));
// SendResume only once, when suspend count drops to 0.
// Don't SendResume at all if we're diverting callbacks to the parent (unless
// suspend was sent earlier); otherwise, resume will be called at the correct
// time in the parent itself.
if (!--mSuspendCount && (!mDivertingToParent || mSuspendSent)) {
if (!--mSuspendCount && mSuspendSent) {
SendResume();
}
mEventQ->Resume();
@ -641,73 +522,6 @@ FTPChannelChild::CompleteRedirectSetup(nsIStreamListener* aListener) {
return NS_OK;
}
//-----------------------------------------------------------------------------
// FTPChannelChild::nsIDivertableChannel
//-----------------------------------------------------------------------------
NS_IMETHODIMP
FTPChannelChild::DivertToParent(ChannelDiverterChild** aChild) {
MOZ_RELEASE_ASSERT(aChild);
MOZ_RELEASE_ASSERT(gNeckoChild);
MOZ_RELEASE_ASSERT(!mDivertingToParent);
NS_ENSURE_TRUE(
!static_cast<ContentChild*>(gNeckoChild->Manager())->IsShuttingDown(),
NS_ERROR_FAILURE);
LOG(("FTPChannelChild::DivertToParent [this=%p]\n", this));
// This method should only be called during OnStartRequest.
if (!mDuringOnStart) {
return NS_ERROR_NOT_AVAILABLE;
}
// We must fail DivertToParent() if there's no parent end of the channel (and
// won't be!) due to early failure.
if (NS_FAILED(mStatus) && !mIPCOpen) {
return mStatus;
}
// Once this is set, it should not be unset before the child is taken down.
mDivertingToParent = true;
nsresult rv = Suspend();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
PChannelDiverterChild* diverter =
gNeckoChild->SendPChannelDiverterConstructor(this);
MOZ_RELEASE_ASSERT(diverter);
*aChild = static_cast<ChannelDiverterChild*>(diverter);
return NS_OK;
}
NS_IMETHODIMP
FTPChannelChild::UnknownDecoderInvolvedKeepData() {
mUnknownDecoderInvolved = true;
return NS_OK;
}
NS_IMETHODIMP
FTPChannelChild::UnknownDecoderInvolvedOnStartRequestCalled() {
mUnknownDecoderInvolved = false;
if (mDivertingToParent) {
mEventQ->PrependEvents(mUnknownDecoderEventQ);
}
mUnknownDecoderEventQ.Clear();
return NS_OK;
}
NS_IMETHODIMP
FTPChannelChild::GetDivertingToParent(bool* aDiverting) {
NS_ENSURE_ARG_POINTER(aDiverting);
*aDiverting = mDivertingToParent;
return NS_OK;
}
void FTPChannelChild::SetupNeckoTarget() {
if (mNeckoTarget) {
return;

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

@ -17,7 +17,6 @@
#include "nsIProxiedChannel.h"
#include "nsIResumableChannel.h"
#include "nsIChildChannel.h"
#include "nsIDivertableChannel.h"
#include "nsIEventTarget.h"
#include "nsIStreamListener.h"
@ -40,8 +39,7 @@ class FTPChannelChild final : public PFTPChannelChild,
public nsIUploadChannel,
public nsIResumableChannel,
public nsIProxiedChannel,
public nsIChildChannel,
public nsIDivertableChannel {
public nsIChildChannel {
public:
typedef ::nsIStreamListener nsIStreamListener;
@ -51,7 +49,6 @@ class FTPChannelChild final : public PFTPChannelChild,
NS_DECL_NSIRESUMABLECHANNEL
NS_DECL_NSIPROXIEDCHANNEL
NS_DECL_NSICHILDCHANNEL
NS_DECL_NSIDIVERTABLECHANNEL
NS_IMETHOD Cancel(nsresult aStatus) override;
NS_IMETHOD Suspend() override;
@ -73,8 +70,6 @@ class FTPChannelChild final : public PFTPChannelChild,
bool IsSuspended() const;
void FlushedForDiversion();
protected:
virtual ~FTPChannelChild();
@ -93,8 +88,6 @@ class FTPChannelChild final : public PFTPChannelChild,
const bool& aUseUTF8) override;
mozilla::ipc::IPCResult RecvFailedAsyncOpen(
const nsresult& aStatusCode) override;
mozilla::ipc::IPCResult RecvFlushedForDiversion() override;
mozilla::ipc::IPCResult RecvDivertMessages() override;
mozilla::ipc::IPCResult RecvDeleteSelf() override;
void DoOnStartRequest(const nsresult& aChannelStatus,
@ -119,12 +112,6 @@ class FTPChannelChild final : public PFTPChannelChild,
bool mIPCOpen;
const RefPtr<ChannelEventQueue> mEventQ;
// If nsUnknownDecoder is involved we queue onDataAvailable (and possibly
// OnStopRequest) so that we can divert them if needed when the listener's
// OnStartRequest is finally called
nsTArray<UniquePtr<ChannelEvent>> mUnknownDecoderEventQ;
bool mUnknownDecoderInvolved;
bool mCanceled;
uint32_t mSuspendCount;
bool mIsPending;
@ -137,11 +124,6 @@ class FTPChannelChild final : public PFTPChannelChild,
uint64_t mStartPos;
nsCString mEntityID;
// Once set, OnData and possibly OnStop will be diverted to the parent.
bool mDivertingToParent;
// Once set, no OnStart/OnData/OnStop callbacks should be received from the
// parent channel, nor dequeued from the ChannelEventQueue.
bool mFlushedForDiversion;
// Set if SendSuspend is called. Determines if SendResume is needed when
// diverting callbacks to parent.
bool mSuspendSent;

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

@ -43,9 +43,6 @@ FTPChannelParent::FTPChannelParent(dom::BrowserParent* aIframeEmbedding,
mLoadContext(aLoadContext),
mPBOverride(aOverrideStatus),
mStatus(NS_OK),
mDivertingFromChild(false),
mDivertedOnStartRequest(false),
mSuspendedForDiversion(false),
mBrowserParent(aIframeEmbedding),
mUseUTF8(false) {
nsIProtocolHandler* handler;
@ -201,174 +198,6 @@ mozilla::ipc::IPCResult FTPChannelParent::RecvResume() {
return IPC_OK();
}
class FTPDivertDataAvailableEvent : public MainThreadChannelEvent {
public:
FTPDivertDataAvailableEvent(FTPChannelParent* aParent, const nsCString& data,
const uint64_t& offset, const uint32_t& count)
: mParent(aParent), mData(data), mOffset(offset), mCount(count) {}
void Run() override {
mParent->DivertOnDataAvailable(mData, mOffset, mCount);
}
private:
FTPChannelParent* mParent;
nsCString mData;
uint64_t mOffset;
uint32_t mCount;
};
mozilla::ipc::IPCResult FTPChannelParent::RecvDivertOnDataAvailable(
const nsCString& data, const uint64_t& offset, const uint32_t& count) {
if (NS_WARN_IF(!mDivertingFromChild)) {
MOZ_ASSERT(mDivertingFromChild,
"Cannot RecvDivertOnDataAvailable if diverting is not set!");
FailDiversion(NS_ERROR_UNEXPECTED);
return IPC_FAIL_NO_REASON(this);
}
// Drop OnDataAvailables if the parent was canceled already.
if (NS_FAILED(mStatus)) {
return IPC_OK();
}
mEventQ->RunOrEnqueue(
new FTPDivertDataAvailableEvent(this, data, offset, count));
return IPC_OK();
}
void FTPChannelParent::DivertOnDataAvailable(const nsCString& data,
const uint64_t& offset,
const uint32_t& count) {
LOG(("FTPChannelParent::DivertOnDataAvailable [this=%p]\n", this));
if (NS_WARN_IF(!mDivertingFromChild)) {
MOZ_ASSERT(mDivertingFromChild,
"Cannot DivertOnDataAvailable if diverting is not set!");
FailDiversion(NS_ERROR_UNEXPECTED);
return;
}
// Drop OnDataAvailables if the parent was canceled already.
if (NS_FAILED(mStatus)) {
return;
}
nsCOMPtr<nsIInputStream> stringStream;
nsresult rv = NS_NewByteInputStream(
getter_AddRefs(stringStream), Span(data).To(count), NS_ASSIGNMENT_DEPEND);
if (NS_FAILED(rv)) {
if (mChannel) {
mChannel->Cancel(rv);
}
mStatus = rv;
return;
}
AutoEventEnqueuer ensureSerialDispatch(mEventQ);
rv = OnDataAvailable(mChannel, stringStream, offset, count);
stringStream->Close();
if (NS_FAILED(rv)) {
if (mChannel) {
mChannel->Cancel(rv);
}
mStatus = rv;
}
}
class FTPDivertStopRequestEvent : public MainThreadChannelEvent {
public:
FTPDivertStopRequestEvent(FTPChannelParent* aParent,
const nsresult& statusCode)
: mParent(aParent), mStatusCode(statusCode) {}
void Run() override { mParent->DivertOnStopRequest(mStatusCode); }
private:
FTPChannelParent* mParent;
nsresult mStatusCode;
};
mozilla::ipc::IPCResult FTPChannelParent::RecvDivertOnStopRequest(
const nsresult& statusCode) {
if (NS_WARN_IF(!mDivertingFromChild)) {
MOZ_ASSERT(mDivertingFromChild,
"Cannot RecvDivertOnStopRequest if diverting is not set!");
FailDiversion(NS_ERROR_UNEXPECTED);
return IPC_FAIL_NO_REASON(this);
}
mEventQ->RunOrEnqueue(new FTPDivertStopRequestEvent(this, statusCode));
return IPC_OK();
}
void FTPChannelParent::DivertOnStopRequest(const nsresult& statusCode) {
LOG(("FTPChannelParent::DivertOnStopRequest [this=%p]\n", this));
if (NS_WARN_IF(!mDivertingFromChild)) {
MOZ_ASSERT(mDivertingFromChild,
"Cannot DivertOnStopRequest if diverting is not set!");
FailDiversion(NS_ERROR_UNEXPECTED);
return;
}
// Honor the channel's status even if the underlying transaction completed.
nsresult status = NS_FAILED(mStatus) ? mStatus : statusCode;
// Reset fake pending status in case OnStopRequest has already been called.
if (mChannel) {
nsCOMPtr<nsIForcePendingChannel> forcePendingIChan =
do_QueryInterface(mChannel);
if (forcePendingIChan) {
forcePendingIChan->ForcePending(false);
}
}
AutoEventEnqueuer ensureSerialDispatch(mEventQ);
OnStopRequest(mChannel, status);
}
class FTPDivertCompleteEvent : public MainThreadChannelEvent {
public:
explicit FTPDivertCompleteEvent(FTPChannelParent* aParent)
: mParent(aParent) {}
void Run() override { mParent->DivertComplete(); }
private:
FTPChannelParent* mParent;
};
mozilla::ipc::IPCResult FTPChannelParent::RecvDivertComplete() {
if (NS_WARN_IF(!mDivertingFromChild)) {
MOZ_ASSERT(mDivertingFromChild,
"Cannot RecvDivertComplete if diverting is not set!");
FailDiversion(NS_ERROR_UNEXPECTED);
return IPC_FAIL_NO_REASON(this);
}
mEventQ->RunOrEnqueue(new FTPDivertCompleteEvent(this));
return IPC_OK();
}
void FTPChannelParent::DivertComplete() {
LOG(("FTPChannelParent::DivertComplete [this=%p]\n", this));
if (NS_WARN_IF(!mDivertingFromChild)) {
MOZ_ASSERT(mDivertingFromChild,
"Cannot DivertComplete if diverting is not set!");
FailDiversion(NS_ERROR_UNEXPECTED);
return;
}
nsresult rv = ResumeForDiversion();
if (NS_WARN_IF(NS_FAILED(rv))) {
FailDiversion(NS_ERROR_UNEXPECTED);
}
}
//-----------------------------------------------------------------------------
// FTPChannelParent::nsIRequestObserver
//-----------------------------------------------------------------------------
@ -377,12 +206,6 @@ NS_IMETHODIMP
FTPChannelParent::OnStartRequest(nsIRequest* aRequest) {
LOG(("FTPChannelParent::OnStartRequest [this=%p]\n", this));
if (mDivertingFromChild) {
MOZ_RELEASE_ASSERT(mDivertToListener,
"Cannot divert if listener is unset!");
return mDivertToListener->OnStartRequest(aRequest);
}
nsCOMPtr<nsIChannel> chan = do_QueryInterface(aRequest);
MOZ_ASSERT(chan);
NS_ENSURE_TRUE(chan, NS_ERROR_UNEXPECTED);
@ -442,12 +265,6 @@ FTPChannelParent::OnStopRequest(nsIRequest* aRequest, nsresult aStatusCode) {
LOG(("FTPChannelParent::OnStopRequest: [this=%p status=%" PRIu32 "]\n", this,
static_cast<uint32_t>(aStatusCode)));
if (mDivertingFromChild) {
MOZ_RELEASE_ASSERT(mDivertToListener,
"Cannot divert if listener is unset!");
return mDivertToListener->OnStopRequest(aRequest, aStatusCode);
}
if (mIPCClosed || !SendOnStopRequest(aStatusCode, mErrorMsg, mUseUTF8)) {
return NS_ERROR_UNEXPECTED;
}
@ -465,13 +282,6 @@ FTPChannelParent::OnDataAvailable(nsIRequest* aRequest,
uint64_t aOffset, uint32_t aCount) {
LOG(("FTPChannelParent::OnDataAvailable [this=%p]\n", this));
if (mDivertingFromChild) {
MOZ_RELEASE_ASSERT(mDivertToListener,
"Cannot divert if listener is unset!");
return mDivertToListener->OnDataAvailable(aRequest, aInputStream, aOffset,
aCount);
}
nsCString data;
nsresult rv = NS_ReadInputStreamToString(aInputStream, data, aCount);
if (NS_FAILED(rv)) return rv;
@ -576,245 +386,6 @@ FTPChannelParent::GetInterface(const nsIID& uuid, void** result) {
return QueryInterface(uuid, result);
}
nsresult FTPChannelParent::ResumeChannelInternalIfPossible() {
nsCOMPtr<nsIChannelWithDivertableParentListener> chan =
do_QueryInterface(mChannel);
if (chan) {
return chan->ResumeInternal();
}
return mChannel->Resume();
}
//-----------------------------------------------------------------------------
// FTPChannelParent::ADivertableParentChannel
//-----------------------------------------------------------------------------
nsresult FTPChannelParent::SuspendForDiversion() {
MOZ_ASSERT(mChannel);
if (NS_WARN_IF(mDivertingFromChild)) {
MOZ_ASSERT(!mDivertingFromChild, "Already suspended for diversion!");
return NS_ERROR_UNEXPECTED;
}
// MessageDiversionStarted call will suspend mEventQ as many times as the
// channel has been suspended, so that channel and this queue are in sync.
nsCOMPtr<nsIChannelWithDivertableParentListener> chan =
do_QueryInterface(mChannel);
if (chan) {
chan->MessageDiversionStarted(this);
}
// We need to suspend only nsHttp/FTPChannel (i.e. we should not suspend
// mEventQ). Therefore we call mChannel->SuspendInternal() and not
// mChannel->Suspend().
// We are suspending only nsHttp/FTPChannel here because we want to stop
// OnDataAvailable until diversion is over. At the same time we should
// send the diverted OnDataAvailable-s to the listeners and not queue them
// in mEventQ.
// Try suspending the channel. Allow it to fail, since OnStopRequest may have
// been called and thus the channel may not be pending.
nsresult rv;
if (chan) {
rv = chan->SuspendInternal();
} else {
rv = mChannel->Suspend();
}
MOZ_ASSERT(NS_SUCCEEDED(rv) || rv == NS_ERROR_NOT_AVAILABLE);
mSuspendedForDiversion = NS_SUCCEEDED(rv);
// Once this is set, no more OnStart/OnData/OnStop callbacks should be sent
// to the child.
mDivertingFromChild = true;
return NS_OK;
}
/* private, supporting function for ADivertableParentChannel */
nsresult FTPChannelParent::ResumeForDiversion() {
MOZ_ASSERT(mChannel);
MOZ_ASSERT(mDivertToListener);
if (NS_WARN_IF(!mDivertingFromChild)) {
MOZ_ASSERT(mDivertingFromChild,
"Cannot ResumeForDiversion if not diverting!");
return NS_ERROR_UNEXPECTED;
}
nsCOMPtr<nsIChannelWithDivertableParentListener> chan =
do_QueryInterface(mChannel);
if (chan) {
chan->MessageDiversionStop();
}
if (mSuspendedForDiversion) {
nsresult rv = ResumeChannelInternalIfPossible();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
mSuspendedForDiversion = false;
}
// Delete() will tear down IPDL, but ref from underlying nsFTPChannel will
// keep us alive if there's more data to be delivered to listener.
if (NS_WARN_IF(NS_FAILED(Delete()))) {
return NS_ERROR_UNEXPECTED;
}
return NS_OK;
}
nsresult FTPChannelParent::SuspendMessageDiversion() {
// This only need to suspend message queue.
mEventQ->Suspend();
return NS_OK;
}
nsresult FTPChannelParent::ResumeMessageDiversion() {
// This only need to resumes message queue.
mEventQ->Resume();
return NS_OK;
}
nsresult FTPChannelParent::CancelDiversion() {
// Only HTTP channels can have child-process-sourced-data that's long-lived
// so this isn't currently relevant for FTP channels and there is nothing to
// do.
return NS_OK;
}
void FTPChannelParent::DivertTo(nsIStreamListener* aListener) {
MOZ_ASSERT(aListener);
if (NS_WARN_IF(!mDivertingFromChild)) {
MOZ_ASSERT(mDivertingFromChild,
"Cannot DivertTo new listener if diverting is not set!");
return;
}
if (NS_WARN_IF(mIPCClosed || !SendFlushedForDiversion())) {
FailDiversion(NS_ERROR_UNEXPECTED);
return;
}
mDivertToListener = aListener;
// Call OnStartRequest and SendDivertMessages asynchronously to avoid
// reentering client context.
NS_DispatchToCurrentThread(
NewRunnableMethod("net::FTPChannelParent::StartDiversion", this,
&FTPChannelParent::StartDiversion));
}
void FTPChannelParent::StartDiversion() {
if (NS_WARN_IF(!mDivertingFromChild)) {
MOZ_ASSERT(mDivertingFromChild,
"Cannot StartDiversion if diverting is not set!");
return;
}
// Fake pending status in case OnStopRequest has already been called.
if (mChannel) {
nsCOMPtr<nsIForcePendingChannel> forcePendingIChan =
do_QueryInterface(mChannel);
if (forcePendingIChan) {
forcePendingIChan->ForcePending(true);
}
}
{
AutoEventEnqueuer ensureSerialDispatch(mEventQ);
// Call OnStartRequest for the "DivertTo" listener.
nsresult rv = OnStartRequest(mChannel);
if (NS_FAILED(rv)) {
if (mChannel) {
mChannel->Cancel(rv);
}
mStatus = rv;
return;
}
}
// After OnStartRequest has been called, tell FTPChannelChild to divert the
// OnDataAvailables and OnStopRequest to this FTPChannelParent.
if (NS_WARN_IF(mIPCClosed || !SendDivertMessages())) {
FailDiversion(NS_ERROR_UNEXPECTED);
return;
}
}
class FTPFailDiversionEvent : public Runnable {
public:
FTPFailDiversionEvent(FTPChannelParent* aChannelParent, nsresult aErrorCode)
: Runnable("net::FTPFailDiversionEvent"),
mChannelParent(aChannelParent),
mErrorCode(aErrorCode) {
MOZ_RELEASE_ASSERT(aChannelParent);
MOZ_RELEASE_ASSERT(NS_FAILED(aErrorCode));
}
NS_IMETHOD Run() override {
mChannelParent->NotifyDiversionFailed(mErrorCode);
return NS_OK;
}
private:
RefPtr<FTPChannelParent> mChannelParent;
nsresult mErrorCode;
};
void FTPChannelParent::FailDiversion(nsresult aErrorCode) {
MOZ_RELEASE_ASSERT(NS_FAILED(aErrorCode));
MOZ_RELEASE_ASSERT(mDivertingFromChild);
MOZ_RELEASE_ASSERT(mDivertToListener);
MOZ_RELEASE_ASSERT(mChannel);
NS_DispatchToCurrentThread(new FTPFailDiversionEvent(this, aErrorCode));
}
void FTPChannelParent::NotifyDiversionFailed(nsresult aErrorCode) {
MOZ_RELEASE_ASSERT(NS_FAILED(aErrorCode));
MOZ_RELEASE_ASSERT(mDivertingFromChild);
MOZ_RELEASE_ASSERT(mDivertToListener);
MOZ_RELEASE_ASSERT(mChannel);
mChannel->Cancel(aErrorCode);
nsCOMPtr<nsIForcePendingChannel> forcePendingIChan =
do_QueryInterface(mChannel);
if (forcePendingIChan) {
forcePendingIChan->ForcePending(false);
}
bool isPending = false;
nsresult rv = mChannel->IsPending(&isPending);
MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
// Resume only we suspended earlier.
if (mSuspendedForDiversion) {
ResumeChannelInternalIfPossible();
}
// Channel has already sent OnStartRequest to the child, so ensure that we
// call it here if it hasn't already been called.
if (!mDivertedOnStartRequest) {
nsCOMPtr<nsIForcePendingChannel> forcePendingIChan =
do_QueryInterface(mChannel);
if (forcePendingIChan) {
forcePendingIChan->ForcePending(true);
}
mDivertToListener->OnStartRequest(mChannel);
if (forcePendingIChan) {
forcePendingIChan->ForcePending(false);
}
}
// If the channel is pending, it will call OnStopRequest itself; otherwise, do
// it here.
if (!isPending) {
mDivertToListener->OnStopRequest(mChannel, aErrorCode);
}
mDivertToListener = nullptr;
mChannel = nullptr;
if (!mIPCClosed) {
Unused << SendDeleteSelf();
}
}
//-----------------------------------------------------------------------------
// FTPChannelParent::nsIChannelEventSink
//-----------------------------------------------------------------------------

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

@ -8,7 +8,6 @@
#ifndef mozilla_net_FTPChannelParent_h
#define mozilla_net_FTPChannelParent_h
#include "ADivertableParentChannel.h"
#include "mozilla/net/PFTPChannelParent.h"
#include "mozilla/net/NeckoParent.h"
#include "nsIParentChannel.h"
@ -30,7 +29,6 @@ class ChannelEventQueue;
class FTPChannelParent final : public PFTPChannelParent,
public nsIParentChannel,
public nsIInterfaceRequestor,
public ADivertableParentChannel,
public nsIChannelEventSink,
public nsIFTPChannelParentInternal {
public:
@ -47,33 +45,11 @@ class FTPChannelParent final : public PFTPChannelParent,
bool Init(const FTPChannelCreationArgs& aOpenArgs);
// ADivertableParentChannel functions.
void DivertTo(nsIStreamListener* aListener) override;
nsresult SuspendForDiversion() override;
nsresult SuspendMessageDiversion() override;
nsresult ResumeMessageDiversion() override;
nsresult CancelDiversion() override;
// Calls OnStartRequest for "DivertTo" listener, then notifies child channel
// that it should divert OnDataAvailable and OnStopRequest calls to this
// parent channel.
void StartDiversion();
// Handles calling OnStart/Stop if there are errors during diversion.
// Called asynchronously from FailDiversion.
void NotifyDiversionFailed(nsresult aErrorCode);
NS_IMETHOD SetErrorMsg(const char* aMsg, bool aUseUTF8) override;
protected:
virtual ~FTPChannelParent();
// private, supporting function for ADivertableParentChannel.
nsresult ResumeForDiversion();
// Asynchronously calls NotifyDiversionFailed.
void FailDiversion(nsresult aErrorCode);
bool DoAsyncOpen(const URIParams& aURI, const uint64_t& aStartPos,
const nsCString& aEntityID,
const Maybe<IPCStream>& aUploadStream,
@ -84,26 +60,9 @@ class FTPChannelParent final : public PFTPChannelParent,
// ChildChannel. Used during HTTP->FTP redirects.
bool ConnectChannel(const uint64_t& channelId);
void DivertOnDataAvailable(const nsCString& data, const uint64_t& offset,
const uint32_t& count);
void DivertOnStopRequest(const nsresult& statusCode);
void DivertComplete();
friend class FTPDivertDataAvailableEvent;
friend class FTPDivertStopRequestEvent;
friend class FTPDivertCompleteEvent;
virtual mozilla::ipc::IPCResult RecvCancel(const nsresult& status) override;
virtual mozilla::ipc::IPCResult RecvSuspend() override;
virtual mozilla::ipc::IPCResult RecvResume() override;
virtual mozilla::ipc::IPCResult RecvDivertOnDataAvailable(
const nsCString& data, const uint64_t& offset,
const uint32_t& count) override;
virtual mozilla::ipc::IPCResult RecvDivertOnStopRequest(
const nsresult& statusCode) override;
virtual mozilla::ipc::IPCResult RecvDivertComplete() override;
nsresult ResumeChannelInternalIfPossible();
virtual void ActorDestroy(ActorDestroyReason why) override;
@ -116,21 +75,9 @@ class FTPChannelParent final : public PFTPChannelParent,
PBOverrideStatus mPBOverride;
// If OnStart/OnData/OnStop have been diverted from the child, forward them to
// this listener.
nsCOMPtr<nsIStreamListener> mDivertToListener;
// Set to the canceled status value if the main channel was canceled.
nsresult mStatus;
// Once set, no OnStart/OnData/OnStop calls should be accepted; conversely, it
// must be set when RecvDivertOnData/~DivertOnStop/~DivertComplete are
// received from the child channel.
bool mDivertingFromChild;
// Set if OnStart|StopRequest was called during a diversion from the child.
bool mDivertedOnStartRequest;
// Set if we successfully suspended the nsHttpChannel for diversion. Unset
// when we call ResumeForDiversion.
bool mSuspendedForDiversion;
RefPtr<mozilla::dom::BrowserParent> mBrowserParent;
RefPtr<ChannelEventQueue> mEventQ;

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

@ -30,17 +30,6 @@ parent:
async Suspend();
async Resume();
// Divert OnDataAvailable to the parent.
async DivertOnDataAvailable(nsCString data,
uint64_t offset,
uint32_t count);
// Divert OnStopRequest to the parent.
async DivertOnStopRequest(nsresult statusCode);
// Child has no more events/messages to divert to the parent.
async DivertComplete();
child:
async OnStartRequest(nsresult aChannelStatus,
int64_t aContentLength,
@ -57,13 +46,6 @@ child:
bool aUseUTF8);
async FailedAsyncOpen(nsresult statusCode);
// Parent has been suspended for diversion; no more events to be enqueued.
async FlushedForDiversion();
// Child should resume processing the ChannelEventQueue, i.e. diverting any
// OnDataAvailable and OnStopRequest messages in the queue back to the parent.
async DivertMessages();
async DeleteSelf();
};

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

@ -27,8 +27,7 @@ extern LazyLogModule gFTPLog;
NS_IMPL_ISUPPORTS_INHERITED(nsFtpChannel, nsBaseChannel, nsIUploadChannel,
nsIResumableChannel, nsIFTPChannel,
nsIProxiedChannel, nsIForcePendingChannel,
nsISupportsWeakReference,
nsIChannelWithDivertableParentListener)
nsISupportsWeakReference)
//-----------------------------------------------------------------------------
@ -199,59 +198,6 @@ bool nsFtpChannel::Pending() const {
NS_IMETHODIMP
nsFtpChannel::Suspend() {
LOG(("nsFtpChannel::Suspend [this=%p]\n", this));
nsresult rv = SuspendInternal();
nsresult rvParentChannel = NS_OK;
if (mParentChannel) {
rvParentChannel = mParentChannel->SuspendMessageDiversion();
}
return NS_FAILED(rv) ? rv : rvParentChannel;
}
NS_IMETHODIMP
nsFtpChannel::Resume() {
LOG(("nsFtpChannel::Resume [this=%p]\n", this));
nsresult rv = ResumeInternal();
nsresult rvParentChannel = NS_OK;
if (mParentChannel) {
rvParentChannel = mParentChannel->ResumeMessageDiversion();
}
return NS_FAILED(rv) ? rv : rvParentChannel;
}
//-----------------------------------------------------------------------------
// AChannelHasDivertableParentChannelAsListener internal functions
//-----------------------------------------------------------------------------
NS_IMETHODIMP
nsFtpChannel::MessageDiversionStarted(
ADivertableParentChannel* aParentChannel) {
MOZ_ASSERT(!mParentChannel);
mParentChannel = aParentChannel;
// If the channel is suspended, propagate that info to the parent's mEventQ.
uint32_t suspendCount = mSuspendCount;
while (suspendCount--) {
mParentChannel->SuspendMessageDiversion();
}
return NS_OK;
}
NS_IMETHODIMP
nsFtpChannel::MessageDiversionStop() {
LOG(("nsFtpChannel::MessageDiversionStop [this=%p]", this));
MOZ_ASSERT(mParentChannel);
mParentChannel = nullptr;
return NS_OK;
}
NS_IMETHODIMP
nsFtpChannel::SuspendInternal() {
LOG(("nsFtpChannel::SuspendInternal [this=%p]\n", this));
NS_ENSURE_TRUE(Pending(), NS_ERROR_NOT_AVAILABLE);
++mSuspendCount;
@ -259,8 +205,8 @@ nsFtpChannel::SuspendInternal() {
}
NS_IMETHODIMP
nsFtpChannel::ResumeInternal() {
LOG(("nsFtpChannel::ResumeInternal [this=%p]\n", this));
nsFtpChannel::Resume() {
LOG(("nsFtpChannel::Resume [this=%p]\n", this));
NS_ENSURE_TRUE(mSuspendCount > 0, NS_ERROR_UNEXPECTED);
--mSuspendCount;
return nsBaseChannel::Resume();

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

@ -11,7 +11,6 @@
#include "nsString.h"
#include "nsCOMPtr.h"
#include "nsIChannelWithDivertableParentListener.h"
#include "nsIFTPChannel.h"
#include "nsIForcePendingChannel.h"
#include "nsIUploadChannel.h"
@ -21,7 +20,6 @@
#include "nsWeakReference.h"
class nsIURI;
using mozilla::net::ADivertableParentChannel;
class nsFtpChannel final : public nsBaseChannel,
public nsIFTPChannel,
@ -29,14 +27,12 @@ class nsFtpChannel final : public nsBaseChannel,
public nsIResumableChannel,
public nsIProxiedChannel,
public nsIForcePendingChannel,
public nsSupportsWeakReference,
public nsIChannelWithDivertableParentListener {
public nsSupportsWeakReference {
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIUPLOADCHANNEL
NS_DECL_NSIRESUMABLECHANNEL
NS_DECL_NSIPROXIEDCHANNEL
NS_DECL_NSICHANNELWITHDIVERTABLEPARENTLISTENER
nsFtpChannel(nsIURI* uri, nsIProxyInfo* pi)
: mProxyInfo(pi),
@ -111,7 +107,6 @@ class nsFtpChannel final : public nsBaseChannel,
bool mResumeRequested;
PRTime mLastModifiedTime;
bool mForcePending;
RefPtr<ADivertableParentChannel> mParentChannel;
// Current suspension depth for this channel object
uint32_t mSuspendCount;

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

@ -373,53 +373,6 @@ IPCResult HttpBackgroundChannelChild::RecvOnConsoleReport(
return IPC_OK();
}
IPCResult HttpBackgroundChannelChild::RecvFlushedForDiversion() {
LOG(("HttpBackgroundChannelChild::RecvFlushedForDiversion [this=%p]\n",
this));
MOZ_ASSERT(OnSocketThread());
if (NS_WARN_IF(!mChannelChild)) {
return IPC_OK();
}
if (IsWaitingOnStartRequest()) {
LOG((" > pending until OnStartRequest\n"));
mQueuedRunnables.AppendElement(NewRunnableMethod(
"HttpBackgroundChannelChild::RecvFlushedForDiversion", this,
&HttpBackgroundChannelChild::RecvFlushedForDiversion));
return IPC_OK();
}
mChannelChild->ProcessFlushedForDiversion();
return IPC_OK();
}
IPCResult HttpBackgroundChannelChild::RecvDivertMessages() {
LOG(("HttpBackgroundChannelChild::RecvDivertMessages [this=%p]\n", this));
MOZ_ASSERT(OnSocketThread());
if (NS_WARN_IF(!mChannelChild)) {
return IPC_OK();
}
if (IsWaitingOnStartRequest()) {
LOG((" > pending until OnStartRequest\n"));
mQueuedRunnables.AppendElement(NewRunnableMethod(
"HttpBackgroundChannelChild::RecvDivertMessages", this,
&HttpBackgroundChannelChild::RecvDivertMessages));
return IPC_OK();
}
mChannelChild->ProcessDivertMessages();
return IPC_OK();
}
IPCResult HttpBackgroundChannelChild::RecvNotifyClassificationFlags(
const uint32_t& aClassificationFlags, const bool& aIsThirdParty) {
LOG(

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

@ -80,10 +80,6 @@ class HttpBackgroundChannelChild final : public PHttpBackgroundChannelChild {
IPCResult RecvOnStatus(const nsresult& aStatus);
IPCResult RecvFlushedForDiversion();
IPCResult RecvDivertMessages();
IPCResult RecvNotifyClassificationFlags(const uint32_t& aClassificationFlags,
const bool& aIsThirdParty);

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

@ -344,39 +344,6 @@ bool HttpBackgroundChannelParent::OnStatus(const nsresult aStatus) {
return SendOnStatus(aStatus);
}
bool HttpBackgroundChannelParent::OnDiversion() {
LOG(("HttpBackgroundChannelParent::OnDiversion [this=%p]\n", this));
AssertIsInMainProcess();
if (NS_WARN_IF(!mIPCOpened)) {
return false;
}
if (!IsOnBackgroundThread()) {
MutexAutoLock lock(mBgThreadMutex);
nsresult rv = mBackgroundThread->Dispatch(
NewRunnableMethod("net::HttpBackgroundChannelParent::OnDiversion", this,
&HttpBackgroundChannelParent::OnDiversion),
NS_DISPATCH_NORMAL);
MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
return NS_SUCCEEDED(rv);
}
if (!SendFlushedForDiversion()) {
return false;
}
// The listener chain should now be setup; tell HttpChannelChild to divert
// the OnDataAvailables and OnStopRequest to associated HttpChannelParent.
if (!SendDivertMessages()) {
return false;
}
return true;
}
bool HttpBackgroundChannelParent::OnNotifyClassificationFlags(
uint32_t aClassificationFlags, bool aIsThirdParty) {
LOG(

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

@ -41,7 +41,6 @@
#include "mozilla/ipc/InputStreamUtils.h"
#include "mozilla/ipc/URIUtils.h"
#include "mozilla/ipc/BackgroundUtils.h"
#include "mozilla/net/ChannelDiverterChild.h"
#include "mozilla/net/DNS.h"
#include "mozilla/net/SocketProcessBridgeChild.h"
#include "mozilla/StaticPrefs_network.h"
@ -94,9 +93,6 @@ HttpChannelChild::HttpChannelChild()
mCacheFetchCount(0),
mCacheExpirationTime(nsICacheEntry::NO_EXPIRATION_TIME),
mDeletingChannelSent(false),
mUnknownDecoderInvolved(false),
mDivertingToParent(false),
mFlushedForDiversion(false),
mIsFromCache(false),
mIsRacing(false),
mCacheNeedToReportBytesReadInitialized(false),
@ -265,8 +261,6 @@ NS_INTERFACE_MAP_BEGIN(HttpChannelChild)
NS_INTERFACE_MAP_ENTRY(nsIAsyncVerifyRedirectCallback)
NS_INTERFACE_MAP_ENTRY(nsIChildChannel)
NS_INTERFACE_MAP_ENTRY(nsIHttpChannelChild)
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIDivertableChannel,
!mMultiPartID.isSome())
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIMultiPartChannel, mMultiPartID.isSome())
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIThreadRetargetableRequest,
!mMultiPartID.isSome())
@ -358,8 +352,6 @@ void HttpChannelChild::ProcessOnStartRequest(
const HttpChannelOnStartRequestArgs& aArgs) {
LOG(("HttpChannelChild::ProcessOnStartRequest [this=%p]\n", this));
MOZ_ASSERT(OnSocketThread());
MOZ_RELEASE_ASSERT(!mFlushedForDiversion,
"Should not be receiving any more callbacks from parent!");
mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(
this, [self = UnsafePtr<HttpChannelChild>(this), aResponseHead,
@ -388,15 +380,6 @@ void HttpChannelChild::OnStartRequest(
const HttpChannelOnStartRequestArgs& aArgs) {
LOG(("HttpChannelChild::OnStartRequest [this=%p]\n", this));
// mFlushedForDiversion and mDivertingToParent should NEVER be set at this
// stage, as they are set in the listener's OnStartRequest.
MOZ_RELEASE_ASSERT(
!mFlushedForDiversion,
"mFlushedForDiversion should be unset before OnStartRequest!");
MOZ_RELEASE_ASSERT(
!mDivertingToParent,
"mDivertingToParent should be unset before OnStartRequest!");
// If this channel was aborted by ActorDestroy, then there may be other
// OnStartRequest/OnStopRequest/OnDataAvailable IPC messages that need to
// be handled. In that case we just ignore them to avoid calling the listener
@ -550,57 +533,6 @@ void HttpChannelChild::OnAfterLastPart(const nsresult& aStatus) {
}
}
class SyntheticDiversionListener final : public nsIStreamListener {
RefPtr<HttpChannelChild> mChannel;
~SyntheticDiversionListener() = default;
public:
explicit SyntheticDiversionListener(HttpChannelChild* aChannel)
: mChannel(aChannel) {
MOZ_ASSERT(mChannel);
}
NS_IMETHOD
OnStartRequest(nsIRequest* aRequest) override {
MOZ_ASSERT_UNREACHABLE(
"SyntheticDiversionListener should never see OnStartRequest");
return NS_OK;
}
NS_IMETHOD
OnStopRequest(nsIRequest* aRequest, nsresult aStatus) override {
if (mChannel->CanSend()) {
mChannel->SendDivertOnStopRequest(aStatus);
mChannel->SendDivertComplete();
}
return NS_OK;
}
NS_IMETHOD
OnDataAvailable(nsIRequest* aRequest, nsIInputStream* aInputStream,
uint64_t aOffset, uint32_t aCount) override {
if (!mChannel->CanSend()) {
aRequest->Cancel(NS_ERROR_ABORT);
return NS_ERROR_ABORT;
}
nsAutoCString data;
nsresult rv = NS_ConsumeStream(aInputStream, aCount, data);
if (NS_WARN_IF(NS_FAILED(rv))) {
aRequest->Cancel(rv);
return rv;
}
mChannel->SendDivertOnDataAvailable(data, aOffset, aCount);
return NS_OK;
}
NS_DECL_ISUPPORTS
};
NS_IMPL_ISUPPORTS(SyntheticDiversionListener, nsIStreamListener);
void HttpChannelChild::DoOnStartRequest(nsIRequest* aRequest,
nsISupports* aContext) {
nsresult rv;
@ -633,15 +565,6 @@ void HttpChannelChild::DoOnStartRequest(nsIRequest* aRequest,
return;
}
if (mDivertingToParent) {
mListener = nullptr;
mCompressListener = nullptr;
if (mLoadGroup) {
mLoadGroup->RemoveRequest(this, nullptr, mStatus);
}
return;
}
nsCOMPtr<nsIStreamListener> listener;
rv = DoApplyContentConversions(mListener, getter_AddRefs(listener), nullptr);
if (NS_FAILED(rv)) {
@ -657,10 +580,7 @@ void HttpChannelChild::ProcessOnTransportAndData(
const uint64_t& aOffset, const uint32_t& aCount, const nsCString& aData) {
LOG(("HttpChannelChild::ProcessOnTransportAndData [this=%p]\n", this));
MOZ_ASSERT(OnSocketThread());
MOZ_RELEASE_ASSERT(!mFlushedForDiversion,
"Should not be receiving any more callbacks from parent!");
mEventQ->RunOrEnqueue(
new ChannelFunctionEvent(
mEventQ->RunOrEnqueue(new ChannelFunctionEvent(
[self = UnsafePtr<HttpChannelChild>(this)]() {
return self->GetODATarget();
},
@ -668,18 +588,7 @@ void HttpChannelChild::ProcessOnTransportAndData(
aTransportStatus, aOffset, aCount, aData]() {
self->OnTransportAndData(aChannelStatus, aTransportStatus, aOffset,
aCount, aData);
}),
mDivertingToParent);
}
void HttpChannelChild::MaybeDivertOnData(const nsCString& aData,
const uint64_t& aOffset,
const uint32_t& aCount) {
LOG(("HttpChannelChild::MaybeDivertOnData [this=%p]", this));
if (mDivertingToParent) {
SendDivertOnDataAvailable(aData, aOffset, aCount);
}
}));
}
void HttpChannelChild::OnTransportAndData(const nsresult& aChannelStatus,
@ -693,32 +602,10 @@ void HttpChannelChild::OnTransportAndData(const nsresult& aChannelStatus,
mStatus = aChannelStatus;
}
// For diversion to parent, just SendDivertOnDataAvailable.
if (mDivertingToParent) {
MOZ_ASSERT(NS_IsMainThread());
MOZ_RELEASE_ASSERT(
!mFlushedForDiversion,
"Should not be processing any more callbacks from parent!");
SendDivertOnDataAvailable(aData, aOffset, aCount);
return;
}
if (mCanceled || NS_FAILED(mStatus)) {
return;
}
if (mUnknownDecoderInvolved) {
LOG(("UnknownDecoder is involved queue OnDataAvailable call. [this=%p]",
this));
MOZ_ASSERT(NS_IsMainThread());
mUnknownDecoderEventQ.AppendElement(
MakeUnique<NeckoTargetChannelFunctionEvent>(
this,
[self = UnsafePtr<HttpChannelChild>(this), aData, aOffset,
aCount]() { self->MaybeDivertOnData(aData, aOffset, aCount); }));
}
// Hold queue lock throughout all three calls, else we might process a later
// necko msg in between them.
AutoEventEnqueuer ensureSerialDispatch(mEventQ);
@ -801,11 +688,7 @@ void HttpChannelChild::OnTransportAndData(const nsresult& aChannelStatus,
bool HttpChannelChild::NeedToReportBytesRead() {
if (mCacheNeedToReportBytesReadInitialized) {
// No need to send SendRecvBytes when diversion starts since the parent
// process will suspend for diversion triggered in during OnStrartRequest at
// child side, which is earlier. Parent will take over the flow control
// after the diverting starts. Sending |SendBytesRead| is redundant.
return mNeedToReportBytesRead && !mDivertingToParent;
return mNeedToReportBytesRead;
}
// Might notify parent for partial cache, and the IPC message is ignored by
@ -889,13 +772,9 @@ void HttpChannelChild::ProcessOnStopRequest(
"aFromSocketProcess=%d]\n",
this, aFromSocketProcess));
MOZ_ASSERT(OnSocketThread());
MOZ_RELEASE_ASSERT(!mFlushedForDiversion,
"Should not be receiving any more callbacks from parent!");
mEventQ->RunOrEnqueue(
new NeckoTargetChannelFunctionEvent(
this,
[self = UnsafePtr<HttpChannelChild>(this), aChannelStatus, aTiming,
mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(
this, [self = UnsafePtr<HttpChannelChild>(this), aChannelStatus, aTiming,
aResponseTrailers,
consoleReports = CopyableTArray{aConsoleReports.Clone()},
aFromSocketProcess]() mutable {
@ -904,37 +783,21 @@ void HttpChannelChild::ProcessOnStopRequest(
self->DoOnConsoleReport(std::move(consoleReports));
self->ContinueOnStopRequest();
}
}),
mDivertingToParent);
}));
}
void HttpChannelChild::ProcessOnConsoleReport(
nsTArray<ConsoleReportCollected>&& aConsoleReports) {
LOG(("HttpChannelChild::ProcessOnConsoleReport [this=%p]\n", this));
MOZ_ASSERT(OnSocketThread());
MOZ_RELEASE_ASSERT(!mFlushedForDiversion,
"Should not be receiving any more callbacks from parent!");
mEventQ->RunOrEnqueue(
new NeckoTargetChannelFunctionEvent(
mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(
this,
[self = UnsafePtr<HttpChannelChild>(this),
consoleReports = CopyableTArray{aConsoleReports.Clone()}]() mutable {
self->DoOnConsoleReport(std::move(consoleReports));
self->ContinueOnStopRequest();
}),
mDivertingToParent);
}
void HttpChannelChild::MaybeDivertOnStop(const nsresult& aChannelStatus) {
LOG(
("HttpChannelChild::MaybeDivertOnStop [this=%p, "
"mDivertingToParent=%d status=%" PRIx32 "]",
this, static_cast<bool>(mDivertingToParent),
static_cast<uint32_t>(aChannelStatus)));
if (mDivertingToParent) {
SendDivertOnStopRequest(aChannelStatus);
}
}));
}
void HttpChannelChild::DoOnConsoleReport(
@ -971,26 +834,6 @@ void HttpChannelChild::OnStopRequest(
return;
}
if (mDivertingToParent) {
MOZ_RELEASE_ASSERT(
!mFlushedForDiversion,
"Should not be processing any more callbacks from parent!");
SendDivertOnStopRequest(aChannelStatus);
return;
}
if (mUnknownDecoderInvolved) {
LOG(("UnknownDecoder is involved queue OnStopRequest call. [this=%p]",
this));
MOZ_ASSERT(NS_IsMainThread());
mUnknownDecoderEventQ.AppendElement(
MakeUnique<NeckoTargetChannelFunctionEvent>(
this, [self = UnsafePtr<HttpChannelChild>(this), aChannelStatus]() {
self->MaybeDivertOnStop(aChannelStatus);
}));
}
nsCOMPtr<nsICompressConvStats> conv = do_QueryInterface(mCompressListener);
if (conv) {
conv->GetDecodedDataLength(&mDecodedBodySize);
@ -1047,20 +890,6 @@ void HttpChannelChild::OnStopRequest(
}
void HttpChannelChild::ContinueOnStopRequest() {
// If unknownDecoder is involved and the received content is short we will
// know whether we need to divert to parent only after OnStopRequest of the
// listeners chain is called in DoOnStopRequest. At that moment
// unknownDecoder will call OnStartRequest of the real listeners of the
// channel including the OnStopRequest of UrlLoader which decides whether we
// need to divert to parent.
// If we are diverting to parent we should not do a cleanup.
if (mDivertingToParent) {
LOG(
("HttpChannelChild::OnStopRequest - We are diverting to parent, "
"postpone cleaning up."));
return;
}
// If we're a multi-part stream, then don't cleanup yet, and we'll do so
// in OnAfterLastPart.
if (mMultiPartID) {
@ -1594,19 +1423,6 @@ mozilla::ipc::IPCResult HttpChannelChild::RecvRedirect3Complete() {
return IPC_OK();
}
void HttpChannelChild::ProcessFlushedForDiversion() {
LOG(("HttpChannelChild::ProcessFlushedForDiversion [this=%p]\n", this));
MOZ_ASSERT(OnSocketThread());
MOZ_RELEASE_ASSERT(mDivertingToParent);
mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(
this,
[self = UnsafePtr<HttpChannelChild>(this)]() {
self->FlushedForDiversion();
}),
true);
}
void HttpChannelChild::ProcessNotifyClassificationFlags(
uint32_t aClassificationFlags, bool aIsThirdParty) {
LOG(
@ -1634,20 +1450,6 @@ void HttpChannelChild::ProcessNotifyFlashPluginStateChanged(
}));
}
void HttpChannelChild::FlushedForDiversion() {
LOG(("HttpChannelChild::FlushedForDiversion [this=%p]\n", this));
MOZ_RELEASE_ASSERT(mDivertingToParent);
// Once this is set, it should not be unset before HttpChannelChild is taken
// down. After it is set, no OnStart/OnData/OnStop callbacks should be
// received from the parent channel, nor dequeued from the ChannelEventQueue.
mFlushedForDiversion = true;
// If we're synthesized, it's up to the SyntheticDiversionListener to invoke
// SendDivertComplete after it has sent the DivertOnStopRequestMessage.
SendDivertComplete();
}
void HttpChannelChild::ProcessSetClassifierMatchedInfo(
const nsCString& aList, const nsCString& aProvider,
const nsCString& aFullHash) {
@ -1682,23 +1484,6 @@ void HttpChannelChild::ProcessSetClassifierMatchedTrackingInfo(
}));
}
void HttpChannelChild::ProcessDivertMessages() {
LOG(("HttpChannelChild::ProcessDivertMessages [this=%p]\n", this));
MOZ_ASSERT(OnSocketThread());
MOZ_RELEASE_ASSERT(mDivertingToParent);
// DivertTo() has been called on parent, so we can now start sending queued
// IPDL messages back to parent listener.
nsCOMPtr<nsISerialEventTarget> neckoTarget = GetNeckoTarget();
MOZ_ASSERT(neckoTarget);
nsresult rv =
neckoTarget->Dispatch(NewRunnableMethod("HttpChannelChild::Resume", this,
&HttpChannelChild::Resume),
NS_DISPATCH_NORMAL);
MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
}
// Completes the redirect and cleans up the old channel.
void HttpChannelChild::Redirect3Complete() {
LOG(("HttpChannelChild::Redirect3Complete [this=%p]\n", this));
@ -2020,9 +1805,8 @@ HttpChannelChild::Cancel(nsresult aStatus) {
NS_IMETHODIMP
HttpChannelChild::Suspend() {
LOG(("HttpChannelChild::Suspend [this=%p, mSuspendCount=%" PRIu32 ", "
"mDivertingToParent=%d]\n",
this, mSuspendCount + 1, static_cast<bool>(mDivertingToParent)));
LOG(("HttpChannelChild::Suspend [this=%p, mSuspendCount=%" PRIu32 "\n", this,
mSuspendCount + 1));
MOZ_ASSERT(NS_IsMainThread());
NS_ENSURE_TRUE(RemoteChannelExists(), NS_ERROR_NOT_AVAILABLE);
@ -2031,7 +1815,7 @@ HttpChannelChild::Suspend() {
// SendSuspend only once, when suspend goes from 0 to 1.
// Don't SendSuspend at all if we're diverting callbacks to the parent;
// suspend will be called at the correct time in the parent itself.
if (!mSuspendCount++ && !mDivertingToParent) {
if (!mSuspendCount++) {
if (RemoteChannelExists()) {
SendSuspend();
mSuspendSent = true;
@ -2044,9 +1828,8 @@ HttpChannelChild::Suspend() {
NS_IMETHODIMP
HttpChannelChild::Resume() {
LOG(("HttpChannelChild::Resume [this=%p, mSuspendCount=%" PRIu32 ", "
"mDivertingToParent=%d]\n",
this, mSuspendCount - 1, static_cast<bool>(mDivertingToParent)));
LOG(("HttpChannelChild::Resume [this=%p, mSuspendCount=%" PRIu32 "\n", this,
mSuspendCount - 1));
MOZ_ASSERT(NS_IsMainThread());
NS_ENSURE_TRUE(RemoteChannelExists(), NS_ERROR_NOT_AVAILABLE);
NS_ENSURE_TRUE(mSuspendCount > 0, NS_ERROR_UNEXPECTED);
@ -2059,7 +1842,7 @@ HttpChannelChild::Resume() {
// Don't SendResume at all if we're diverting callbacks to the parent (unless
// suspend was sent earlier); otherwise, resume will be called at the correct
// time in the parent itself.
if (!--mSuspendCount && (!mDivertingToParent || mSuspendSent)) {
if (!--mSuspendCount && mSuspendSent) {
if (RemoteChannelExists()) {
SendResume();
}
@ -2993,87 +2776,6 @@ HttpChannelChild::RemoveCorsPreflightCacheEntry(nsIURI* aURI,
return result ? NS_OK : NS_ERROR_FAILURE;
}
//-----------------------------------------------------------------------------
// HttpChannelChild::nsIDivertableChannel
//-----------------------------------------------------------------------------
NS_IMETHODIMP
HttpChannelChild::DivertToParent(ChannelDiverterChild** aChild) {
LOG(("HttpChannelChild::DivertToParent [this=%p]\n", this));
MOZ_RELEASE_ASSERT(aChild);
MOZ_RELEASE_ASSERT(gNeckoChild);
MOZ_RELEASE_ASSERT(!mDivertingToParent);
MOZ_ASSERT(NS_IsMainThread());
if (mMultiPartID) {
return NS_ERROR_NOT_IMPLEMENTED;
}
nsresult rv = NS_OK;
// We must fail DivertToParent() if there's no parent end of the channel (and
// won't be!) due to early failure.
if (NS_FAILED(mStatus) && !RemoteChannelExists()) {
return mStatus;
}
// Once this is set, it should not be unset before the child is taken down.
mDivertingToParent = true;
rv = Suspend();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (static_cast<ContentChild*>(gNeckoChild->Manager())->IsShuttingDown()) {
return NS_ERROR_FAILURE;
}
HttpChannelDiverterArgs args;
args.mChannelChild() = this;
args.mApplyConversion() = mApplyConversion;
PChannelDiverterChild* diverter =
gNeckoChild->SendPChannelDiverterConstructor(args);
MOZ_RELEASE_ASSERT(diverter);
*aChild = static_cast<ChannelDiverterChild*>(diverter);
return NS_OK;
}
NS_IMETHODIMP
HttpChannelChild::UnknownDecoderInvolvedKeepData() {
LOG(("HttpChannelChild::UnknownDecoderInvolvedKeepData [this=%p]", this));
MOZ_ASSERT(NS_IsMainThread());
mUnknownDecoderInvolved = true;
return NS_OK;
}
NS_IMETHODIMP
HttpChannelChild::UnknownDecoderInvolvedOnStartRequestCalled() {
LOG(
("HttpChannelChild::UnknownDecoderInvolvedOnStartRequestCalled "
"[this=%p, mDivertingToParent=%d]",
this, static_cast<bool>(mDivertingToParent)));
MOZ_ASSERT(NS_IsMainThread());
mUnknownDecoderInvolved = false;
if (mDivertingToParent) {
mEventQ->PrependEvents(mUnknownDecoderEventQ);
}
mUnknownDecoderEventQ.Clear();
return NS_OK;
}
NS_IMETHODIMP
HttpChannelChild::GetDivertingToParent(bool* aDiverting) {
NS_ENSURE_ARG_POINTER(aDiverting);
*aDiverting = mDivertingToParent;
return NS_OK;
}
//-----------------------------------------------------------------------------
// HttpChannelChild::nsIMuliPartChannel
//-----------------------------------------------------------------------------
@ -3318,19 +3020,6 @@ void HttpChannelChild::ProcessAttachStreamFilter(
std::move(aEndpoint)));
}
mozilla::ipc::IPCResult HttpChannelChild::RecvCancelDiversion() {
MOZ_ASSERT(NS_IsMainThread());
// This method is a very special case for cancellation of a diverted
// intercepted channel. Normally we would go through the mEventQ in order to
// serialize event execution in the face of sync XHR and now background
// channels. However, similar to how CancelOnMainThread describes, Cancel()
// pre-empts everything. (And frankly, we want this stack frame on the stack
// if a crash happens.)
Cancel(NS_ERROR_ABORT);
return IPC_OK();
}
void HttpChannelChild::ActorDestroy(ActorDestroyReason aWhy) {
MOZ_ASSERT(NS_IsMainThread());

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

@ -29,7 +29,6 @@
#include "nsIAsyncVerifyRedirectCallback.h"
#include "nsIChildChannel.h"
#include "nsIHttpChannelChild.h"
#include "nsIDivertableChannel.h"
#include "nsIMultiPartChannel.h"
#include "nsIThreadRetargetableRequest.h"
#include "mozilla/net/DNS.h"
@ -52,7 +51,6 @@ namespace mozilla {
namespace net {
class HttpBackgroundChannelChild;
class SyntheticDiversionListener;
class HttpChannelChild final : public PHttpChannelChild,
public HttpBaseChannel,
@ -63,7 +61,6 @@ class HttpChannelChild final : public PHttpChannelChild,
public nsIAsyncVerifyRedirectCallback,
public nsIChildChannel,
public nsIHttpChannelChild,
public nsIDivertableChannel,
public nsIMultiPartChannel,
public nsIThreadRetargetableRequest,
public NeckoTargetHolder {
@ -78,7 +75,6 @@ class HttpChannelChild final : public PHttpChannelChild,
NS_DECL_NSIASYNCVERIFYREDIRECTCALLBACK
NS_DECL_NSICHILDCHANNEL
NS_DECL_NSIHTTPCHANNELCHILD
NS_DECL_NSIDIVERTABLECHANNEL
NS_DECL_NSIMULTIPARTCHANNEL
NS_DECL_NSITHREADRETARGETABLEREQUEST
NS_DECLARE_STATIC_IID_ACCESSOR(HTTP_CHANNEL_CHILD_IID)
@ -119,8 +115,6 @@ class HttpChannelChild final : public PHttpChannelChild,
[[nodiscard]] bool IsSuspended();
void FlushedForDiversion();
void OnCopyComplete(nsresult aStatus) override;
// Callback while background channel is ready.
@ -152,8 +146,6 @@ class HttpChannelChild final : public PHttpChannelChild,
mozilla::ipc::IPCResult RecvSetPriority(const int16_t& aPriority) override;
mozilla::ipc::IPCResult RecvCancelDiversion() override;
mozilla::ipc::IPCResult RecvOriginalCacheInputStreamAvailable(
const Maybe<IPCStream>& aStream) override;
@ -229,8 +221,6 @@ class HttpChannelChild final : public PHttpChannelChild,
void ProcessOnConsoleReport(
nsTArray<ConsoleReportCollected>&& aConsoleReports);
void ProcessFlushedForDiversion();
void ProcessDivertMessages();
void ProcessNotifyClassificationFlags(uint32_t aClassificationFlags,
bool aIsThirdParty);
void ProcessNotifyFlashPluginStateChanged(
@ -310,11 +300,6 @@ class HttpChannelChild final : public PHttpChannelChild,
// Used to ensure atomicity of mNeckoTarget / mODATarget;
Mutex mEventTargetMutex;
// If nsUnknownDecoder is involved OnStartRequest call will be delayed and
// this queue keeps OnDataAvailable data until OnStartRequest is finally
// called.
nsTArray<UniquePtr<ChannelEvent>> mUnknownDecoderEventQ;
TimeStamp mLastStatusReported;
uint64_t mCacheEntryId;
@ -335,14 +320,6 @@ class HttpChannelChild final : public PHttpChannelChild,
// To ensure only one SendDeletingChannel is triggered.
Atomic<bool> mDeletingChannelSent;
Atomic<bool, ReleaseAcquire> mUnknownDecoderInvolved;
// Once set, OnData and possibly OnStop will be diverted to the parent.
Atomic<bool, ReleaseAcquire> mDivertingToParent;
// Once set, no OnStart/OnData/OnStop callbacks should be received from the
// parent channel, nor dequeued from the ChannelEventQueue.
Atomic<bool, ReleaseAcquire> mFlushedForDiversion;
Atomic<bool, SequentiallyConsistent> mIsFromCache;
Atomic<bool, SequentiallyConsistent> mIsRacing;
// Set if we get the result and cache |mNeedToReportBytesRead|
@ -420,15 +397,12 @@ class HttpChannelChild final : public PHttpChannelChild,
const bool& aUseResponseHead,
const nsHttpHeaderArray& aRequestHeaders,
const HttpChannelOnStartRequestArgs& aArgs);
void MaybeDivertOnData(const nsCString& data, const uint64_t& offset,
const uint32_t& count);
void OnTransportAndData(const nsresult& channelStatus, const nsresult& status,
const uint64_t& offset, const uint32_t& count,
const nsCString& data);
void OnStopRequest(const nsresult& channelStatus,
const ResourceTimingStructArgs& timing,
const nsHttpHeaderArray& aResponseTrailers);
void MaybeDivertOnStop(const nsresult& aChannelStatus);
void FailedAsyncOpen(const nsresult& status);
void HandleAsyncAbort();
void Redirect1Begin(const uint32_t& registrarId, const URIParams& newUri,

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

@ -74,10 +74,6 @@ HttpChannelParent::HttpChannelParent(dom::BrowserParent* iframeEmbedding,
mSentRedirect1BeginFailed(false),
mReceivedRedirect2Verify(false),
mHasSuspendedByBackPressure(false),
mPendingDiversion(false),
mDivertingFromChild(false),
mDivertedOnStartRequest(false),
mSuspendedForDiversion(false),
mCacheNeedFlowControlInitialized(false),
mNeedFlowControl(true),
mSuspendedForFlowControl(false),
@ -1047,199 +1043,6 @@ HttpChannelParent::RecvMarkOfflineCacheEntryAsForeign() {
return IPC_OK();
}
class DivertDataAvailableEvent : public MainThreadChannelEvent {
public:
DivertDataAvailableEvent(HttpChannelParent* aParent, const nsCString& data,
const uint64_t& offset, const uint32_t& count)
: mParent(aParent), mData(data), mOffset(offset), mCount(count) {}
void Run() override {
mParent->DivertOnDataAvailable(mData, mOffset, mCount);
}
private:
HttpChannelParent* mParent;
nsCString mData;
uint64_t mOffset;
uint32_t mCount;
};
mozilla::ipc::IPCResult HttpChannelParent::RecvDivertOnDataAvailable(
const nsCString& data, const uint64_t& offset, const uint32_t& count) {
LOG(("HttpChannelParent::RecvDivertOnDataAvailable [this=%p]\n", this));
MOZ_ASSERT(mParentListener);
if (NS_WARN_IF(!mDivertingFromChild)) {
MOZ_ASSERT(mDivertingFromChild,
"Cannot RecvDivertOnDataAvailable if diverting is not set!");
FailDiversion(NS_ERROR_UNEXPECTED);
return IPC_FAIL_NO_REASON(this);
}
// Drop OnDataAvailables if the parent was canceled already.
if (NS_FAILED(mStatus)) {
return IPC_OK();
}
mEventQ->RunOrEnqueue(
new DivertDataAvailableEvent(this, data, offset, count));
return IPC_OK();
}
void HttpChannelParent::DivertOnDataAvailable(const nsCString& data,
const uint64_t& offset,
const uint32_t& count) {
LOG(("HttpChannelParent::DivertOnDataAvailable [this=%p]\n", this));
MOZ_ASSERT(mParentListener);
if (NS_WARN_IF(!mDivertingFromChild)) {
MOZ_ASSERT(mDivertingFromChild,
"Cannot DivertOnDataAvailable if diverting is not set!");
FailDiversion(NS_ERROR_UNEXPECTED);
return;
}
// Drop OnDataAvailables if the parent was canceled already.
if (NS_FAILED(mStatus)) {
return;
}
nsCOMPtr<nsIInputStream> stringStream;
nsresult rv = NS_NewByteInputStream(
getter_AddRefs(stringStream), Span(data).To(count), NS_ASSIGNMENT_DEPEND);
if (NS_FAILED(rv)) {
if (mChannel) {
mChannel->Cancel(rv);
}
mStatus = rv;
return;
}
AutoEventEnqueuer ensureSerialDispatch(mEventQ);
rv = mParentListener->OnDataAvailable(mChannel, stringStream, offset, count);
stringStream->Close();
if (NS_FAILED(rv)) {
if (mChannel) {
mChannel->Cancel(rv);
}
mStatus = rv;
}
}
class DivertStopRequestEvent : public MainThreadChannelEvent {
public:
DivertStopRequestEvent(HttpChannelParent* aParent, const nsresult& statusCode)
: mParent(aParent), mStatusCode(statusCode) {}
void Run() override { mParent->DivertOnStopRequest(mStatusCode); }
private:
HttpChannelParent* mParent;
nsresult mStatusCode;
};
mozilla::ipc::IPCResult HttpChannelParent::RecvDivertOnStopRequest(
const nsresult& statusCode) {
LOG(("HttpChannelParent::RecvDivertOnStopRequest [this=%p]\n", this));
MOZ_ASSERT(mParentListener);
if (NS_WARN_IF(!mDivertingFromChild)) {
MOZ_ASSERT(mDivertingFromChild,
"Cannot RecvDivertOnStopRequest if diverting is not set!");
FailDiversion(NS_ERROR_UNEXPECTED);
return IPC_FAIL_NO_REASON(this);
}
mEventQ->RunOrEnqueue(new DivertStopRequestEvent(this, statusCode));
return IPC_OK();
}
void HttpChannelParent::DivertOnStopRequest(const nsresult& statusCode) {
LOG(("HttpChannelParent::DivertOnStopRequest [this=%p]\n", this));
MOZ_ASSERT(mParentListener);
if (NS_WARN_IF(!mDivertingFromChild)) {
MOZ_ASSERT(mDivertingFromChild,
"Cannot DivertOnStopRequest if diverting is not set!");
FailDiversion(NS_ERROR_UNEXPECTED);
return;
}
// Honor the channel's status even if the underlying transaction completed.
nsresult status = NS_FAILED(mStatus) ? mStatus : statusCode;
// Reset fake pending status in case OnStopRequest has already been called.
if (mChannel) {
mChannel->ForcePending(false);
}
AutoEventEnqueuer ensureSerialDispatch(mEventQ);
mParentListener->OnStopRequest(mChannel, status);
}
class DivertCompleteEvent : public MainThreadChannelEvent {
public:
explicit DivertCompleteEvent(HttpChannelParent* aParent) : mParent(aParent) {}
void Run() override { mParent->DivertComplete(); }
private:
HttpChannelParent* mParent;
};
mozilla::ipc::IPCResult HttpChannelParent::RecvDivertComplete() {
LOG(("HttpChannelParent::RecvDivertComplete [this=%p]\n", this));
MOZ_ASSERT(mParentListener);
if (NS_WARN_IF(!mDivertingFromChild)) {
MOZ_ASSERT(mDivertingFromChild,
"Cannot RecvDivertComplete if diverting is not set!");
FailDiversion(NS_ERROR_UNEXPECTED);
return IPC_FAIL_NO_REASON(this);
}
mEventQ->RunOrEnqueue(new DivertCompleteEvent(this));
return IPC_OK();
}
void HttpChannelParent::DivertComplete() {
LOG(("HttpChannelParent::DivertComplete [this=%p]\n", this));
MOZ_ASSERT(mParentListener);
if (NS_WARN_IF(!mDivertingFromChild)) {
MOZ_ASSERT(mDivertingFromChild,
"Cannot DivertComplete if diverting is not set!");
FailDiversion(NS_ERROR_UNEXPECTED);
return;
}
nsresult rv = ResumeForDiversion();
if (NS_WARN_IF(NS_FAILED(rv))) {
FailDiversion(NS_ERROR_UNEXPECTED);
return;
}
mParentListener = nullptr;
}
void HttpChannelParent::MaybeFlushPendingDiversion() {
if (!mPendingDiversion) {
return;
}
mPendingDiversion = false;
nsresult rv = SuspendForDiversion();
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
if (mDivertListener) {
DivertTo(mDivertListener);
}
}
mozilla::ipc::IPCResult HttpChannelParent::RecvRemoveCorsPreflightCacheEntry(
const URIParams& uri,
const mozilla::ipc::PrincipalInfo& requestingPrincipal) {
@ -1316,8 +1119,6 @@ HttpChannelParent::OnStartRequest(nsIRequest* aRequest) {
LOG(("HttpChannelParent::OnStartRequest [this=%p, aRequest=%p]\n", this,
aRequest));
MOZ_ASSERT(NS_IsMainThread());
MOZ_RELEASE_ASSERT(!mDivertingFromChild,
"Cannot call OnStartRequest if diverting is set!");
Maybe<uint32_t> multiPartID;
bool isLastPartOfMultiPart = false;
@ -1525,9 +1326,6 @@ HttpChannelParent::OnStopRequest(nsIRequest* aRequest, nsresult aStatusCode) {
this, aRequest, static_cast<uint32_t>(aStatusCode)));
MOZ_ASSERT(NS_IsMainThread());
MOZ_RELEASE_ASSERT(!mDivertingFromChild,
"Cannot call OnStopRequest if diverting is set!");
RefPtr<nsHttpChannel> httpChannelImpl = do_QueryObject(mChannel);
if (httpChannelImpl) {
httpChannelImpl->SetWarningReporter(nullptr);
@ -1644,9 +1442,6 @@ HttpChannelParent::OnDataAvailable(nsIRequest* aRequest,
this, aRequest, aOffset, aCount));
MOZ_ASSERT(NS_IsMainThread());
MOZ_RELEASE_ASSERT(!mDivertingFromChild,
"Cannot call OnDataAvailable if diverting is set!");
if (mDataSentToChildProcess) {
uint32_t n;
return aInputStream->ReadSegments(NS_DiscardSegment, nullptr, aCount, &n);
@ -1731,8 +1526,7 @@ bool HttpChannelParent::NeedFlowControl() {
mozilla::ipc::IPCResult HttpChannelParent::RecvBytesRead(
const int32_t& aCount) {
// no more flow control after diviersion starts
if (!NeedFlowControl() || mDivertingFromChild) {
if (!NeedFlowControl()) {
return IPC_OK();
}
@ -2117,259 +1911,6 @@ HttpChannelParent::CompleteRedirect(bool succeeded) {
return NS_OK;
}
//-----------------------------------------------------------------------------
// HttpChannelParent::ADivertableParentChannel
//-----------------------------------------------------------------------------
nsresult HttpChannelParent::SuspendForDiversion() {
LOG(("HttpChannelParent::SuspendForDiversion [this=%p]\n", this));
MOZ_ASSERT(mChannel);
MOZ_ASSERT(mParentListener);
if (NS_WARN_IF(mDivertingFromChild)) {
MOZ_ASSERT(!mDivertingFromChild, "Already suspended for diversion!");
return NS_ERROR_UNEXPECTED;
}
// MessageDiversionStarted call will suspend mEventQ as many times as the
// channel has been suspended, so that channel and this queue are in sync.
nsCOMPtr<nsIChannelWithDivertableParentListener> divertChannel =
do_QueryInterface(static_cast<nsIChannel*>(mChannel.get()));
divertChannel->MessageDiversionStarted(this);
nsresult rv = NS_OK;
// Try suspending the channel. Allow it to fail, since OnStopRequest may have
// been called and thus the channel may not be pending. If we've already
// automatically suspended after synthesizing the response, then we don't
// need to suspend again here.
// We need to suspend only nsHttpChannel (i.e. we should not suspend
// mEventQ). Therefore we call mChannel->SuspendInternal() and not
// mChannel->Suspend().
// We are suspending only nsHttpChannel here because we want to stop
// OnDataAvailable until diversion is over. At the same time we should
// send the diverted OnDataAvailable-s to the listeners and not queue them
// in mEventQ.
rv = divertChannel->SuspendInternal();
MOZ_ASSERT(NS_SUCCEEDED(rv) || rv == NS_ERROR_NOT_AVAILABLE);
mSuspendedForDiversion = NS_SUCCEEDED(rv);
rv = mParentListener->SuspendForDiversion();
MOZ_ASSERT(NS_SUCCEEDED(rv));
// After we suspend for diversion, we don't need the flow control since the
// channel is suspended until all the data is consumed and no more e10s later.
// No point to have another redundant suspension.
if (mSuspendedForFlowControl) {
LOG((" resume the channel due to e10s backpressure relief by diversion"));
Unused << mChannel->Resume();
mSuspendedForFlowControl = false;
}
// Once this is set, no more OnStart/OnData/OnStop callbacks should be sent
// to the child.
mDivertingFromChild = true;
return NS_OK;
}
nsresult HttpChannelParent::SuspendMessageDiversion() {
LOG(("HttpChannelParent::SuspendMessageDiversion [this=%p]", this));
// This only needs to suspend message queue.
mEventQ->Suspend();
return NS_OK;
}
nsresult HttpChannelParent::ResumeMessageDiversion() {
LOG(("HttpChannelParent::SuspendMessageDiversion [this=%p]", this));
// This only needs to resumes message queue.
mEventQ->Resume();
return NS_OK;
}
nsresult HttpChannelParent::CancelDiversion() {
LOG(("HttpChannelParent::CancelDiversion [this=%p]", this));
if (!mIPCClosed) {
Unused << SendCancelDiversion();
}
return NS_OK;
}
/* private, supporting function for ADivertableParentChannel */
nsresult HttpChannelParent::ResumeForDiversion() {
LOG(("HttpChannelParent::ResumeForDiversion [this=%p]\n", this));
MOZ_ASSERT(mChannel);
if (NS_WARN_IF(!mDivertingFromChild)) {
MOZ_ASSERT(mDivertingFromChild,
"Cannot ResumeForDiversion if not diverting!");
return NS_ERROR_UNEXPECTED;
}
nsCOMPtr<nsIChannelWithDivertableParentListener> divertChannel =
do_QueryInterface(static_cast<nsIChannel*>(mChannel.get()));
divertChannel->MessageDiversionStop();
if (mSuspendedForDiversion) {
// The nsHttpChannel will deliver remaining OnData/OnStop for the transfer.
nsresult rv = divertChannel->ResumeInternal();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
mSuspendedForDiversion = false;
}
if (NS_WARN_IF(mIPCClosed || !DoSendDeleteSelf())) {
return NS_ERROR_UNEXPECTED;
}
return NS_OK;
}
void HttpChannelParent::DivertTo(nsIStreamListener* aListener) {
LOG(("HttpChannelParent::DivertTo [this=%p aListener=%p]\n", this,
aListener));
MOZ_ASSERT(mParentListener);
if (NS_WARN_IF(!mDivertingFromChild)) {
MOZ_ASSERT(mDivertingFromChild,
"Cannot DivertTo new listener if diverting is not set!");
return;
}
mDivertListener = aListener;
// Call OnStartRequest and SendDivertMessages asynchronously to avoid
// reentering client context.
NS_DispatchToCurrentThread(
NewRunnableMethod("net::HttpChannelParent::StartDiversion", this,
&HttpChannelParent::StartDiversion));
}
void HttpChannelParent::StartDiversion() {
LOG(("HttpChannelParent::StartDiversion [this=%p]\n", this));
if (NS_WARN_IF(!mDivertingFromChild)) {
MOZ_ASSERT(mDivertingFromChild,
"Cannot StartDiversion if diverting is not set!");
return;
}
// Fake pending status in case OnStopRequest has already been called.
if (mChannel) {
mChannel->ForcePending(true);
}
{
AutoEventEnqueuer ensureSerialDispatch(mEventQ);
// Call OnStartRequest for the "DivertTo" listener.
nsresult rv = mDivertListener->OnStartRequest(mChannel);
if (NS_FAILED(rv)) {
if (mChannel) {
mChannel->Cancel(rv);
}
mStatus = rv;
}
}
mDivertedOnStartRequest = true;
// After OnStartRequest has been called, setup content decoders if needed.
//
// Create a content conversion chain based on mDivertListener and update
// mDivertListener.
nsCOMPtr<nsIStreamListener> converterListener;
Unused << mChannel->DoApplyContentConversions(
mDivertListener, getter_AddRefs(converterListener));
if (converterListener) {
mDivertListener = std::move(converterListener);
}
// Now mParentListener can be diverted to mDivertListener.
mParentListener->DivertTo(mDivertListener);
mDivertListener = nullptr;
// Either IPC channel is closed or background channel
// is ready to send FlushedForDiversion and DivertMessages.
MOZ_ASSERT(mIPCClosed || mBgParent);
if (NS_WARN_IF(mIPCClosed || !mBgParent || !mBgParent->OnDiversion())) {
FailDiversion(NS_ERROR_UNEXPECTED);
return;
}
}
class HTTPFailDiversionEvent : public Runnable {
public:
HTTPFailDiversionEvent(HttpChannelParent* aChannelParent, nsresult aErrorCode)
: Runnable("net::HTTPFailDiversionEvent"),
mChannelParent(aChannelParent),
mErrorCode(aErrorCode) {
MOZ_RELEASE_ASSERT(aChannelParent);
MOZ_RELEASE_ASSERT(NS_FAILED(aErrorCode));
}
NS_IMETHOD Run() override {
mChannelParent->NotifyDiversionFailed(mErrorCode);
return NS_OK;
}
private:
RefPtr<HttpChannelParent> mChannelParent;
nsresult mErrorCode;
};
void HttpChannelParent::FailDiversion(nsresult aErrorCode) {
MOZ_RELEASE_ASSERT(NS_FAILED(aErrorCode));
MOZ_RELEASE_ASSERT(mDivertingFromChild);
MOZ_RELEASE_ASSERT(mParentListener);
MOZ_RELEASE_ASSERT(mChannel);
NS_DispatchToCurrentThread(new HTTPFailDiversionEvent(this, aErrorCode));
}
void HttpChannelParent::NotifyDiversionFailed(nsresult aErrorCode) {
LOG(("HttpChannelParent::NotifyDiversionFailed [this=%p aErrorCode=%" PRIx32
"]\n",
this, static_cast<uint32_t>(aErrorCode)));
MOZ_RELEASE_ASSERT(NS_FAILED(aErrorCode));
MOZ_RELEASE_ASSERT(mDivertingFromChild);
MOZ_RELEASE_ASSERT(mParentListener);
MOZ_RELEASE_ASSERT(mChannel);
mChannel->Cancel(aErrorCode);
mChannel->ForcePending(false);
bool isPending = false;
nsresult rv = mChannel->IsPending(&isPending);
MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
// Resume only if we suspended earlier.
if (mSuspendedForDiversion) {
nsCOMPtr<nsIChannelWithDivertableParentListener> divertChannel =
do_QueryInterface(static_cast<nsIChannel*>(mChannel.get()));
divertChannel->ResumeInternal();
}
// Channel has already sent OnStartRequest to the child, so ensure that we
// call it here if it hasn't already been called.
if (!mDivertedOnStartRequest) {
mChannel->ForcePending(true);
mParentListener->OnStartRequest(mChannel);
mChannel->ForcePending(false);
}
// If the channel is pending, it will call OnStopRequest itself; otherwise, do
// it here.
if (!isPending) {
mParentListener->OnStopRequest(mChannel, aErrorCode);
}
if (!mIPCClosed) {
Unused << DoSendDeleteSelf();
}
// DoSendDeleteSelf will need channel Id to remove the strong reference in
// BackgroundChannelRegistrar if channel pairing is aborted.
// Thus we need to keep mChannel until DoSendDeleteSelf is done.
mParentListener = nullptr;
mChannel = nullptr;
}
nsresult HttpChannelParent::OpenAlternativeOutputStream(
const nsACString& type, int64_t predictedSize,
nsIAsyncOutputStream** _retval) {

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

@ -8,7 +8,6 @@
#ifndef mozilla_net_HttpChannelParent_h
#define mozilla_net_HttpChannelParent_h
#include "ADivertableParentChannel.h"
#include "nsHttp.h"
#include "mozilla/net/PHttpChannelParent.h"
#include "mozilla/net/NeckoCommon.h"
@ -53,7 +52,6 @@ class HttpChannelParent final : public nsIInterfaceRequestor,
public PHttpChannelParent,
public nsIParentRedirectingChannel,
public nsIProgressEventSink,
public ADivertableParentChannel,
public nsIAuthPromptProvider,
public nsIDeprecationWarner,
public HttpChannelSecurityWarningReporter,
@ -85,22 +83,6 @@ class HttpChannelParent final : public nsIInterfaceRequestor,
[[nodiscard]] bool Init(const HttpChannelCreationArgs& aOpenArgs);
// ADivertableParentChannel functions.
void DivertTo(nsIStreamListener* aListener) override;
[[nodiscard]] nsresult SuspendForDiversion() override;
[[nodiscard]] nsresult SuspendMessageDiversion() override;
[[nodiscard]] nsresult ResumeMessageDiversion() override;
[[nodiscard]] nsresult CancelDiversion() override;
// Calls OnStartRequest for "DivertTo" listener, then notifies child channel
// that it should divert OnDataAvailable and OnStopRequest calls to this
// parent channel.
void StartDiversion();
// Handles calling OnStart/Stop if there are errors during diversion.
// Called asynchronously from FailDiversion.
void NotifyDiversionFailed(nsresult aErrorCode);
// Forwarded to nsHttpChannel::SetApplyConversion.
void SetApplyConversion(bool aApplyConversion) {
if (mChannel) {
@ -211,12 +193,6 @@ class HttpChannelParent final : public nsIInterfaceRequestor,
virtual mozilla::ipc::IPCResult RecvDocumentChannelCleanup(
const bool& clearCacheEntry) override;
virtual mozilla::ipc::IPCResult RecvMarkOfflineCacheEntryAsForeign() override;
virtual mozilla::ipc::IPCResult RecvDivertOnDataAvailable(
const nsCString& data, const uint64_t& offset,
const uint32_t& count) override;
virtual mozilla::ipc::IPCResult RecvDivertOnStopRequest(
const nsresult& statusCode) override;
virtual mozilla::ipc::IPCResult RecvDivertComplete() override;
virtual mozilla::ipc::IPCResult RecvRemoveCorsPreflightCacheEntry(
const URIParams& uri,
const mozilla::ipc::PrincipalInfo& requestingPrincipal) override;
@ -226,12 +202,6 @@ class HttpChannelParent final : public nsIInterfaceRequestor,
const nsCString& aType) override;
virtual void ActorDestroy(ActorDestroyReason why) override;
// Supporting function for ADivertableParentChannel.
[[nodiscard]] nsresult ResumeForDiversion();
// Asynchronously calls NotifyDiversionFailed.
void FailDiversion(nsresult aErrorCode);
friend class ParentChannelListener;
RefPtr<mozilla::dom::BrowserParent> mBrowserParent;
@ -252,11 +222,6 @@ class HttpChannelParent final : public nsIInterfaceRequestor,
private:
void UpdateAndSerializeSecurityInfo(nsACString& aSerializedSecurityInfoOut);
void DivertOnDataAvailable(const nsCString& data, const uint64_t& offset,
const uint32_t& count);
void DivertOnStopRequest(const nsresult& statusCode);
void DivertComplete();
void MaybeFlushPendingDiversion();
// final step for Redirect2Verify procedure, will be invoked while both
// redirecting and redirected channel are ready or any error happened.
// OnRedirectVerifyCallback will be invoked for finishing the async
@ -283,9 +248,6 @@ class HttpChannelParent final : public nsIInterfaceRequestor,
int32_t mSendWindowSize;
friend class HttpBackgroundChannelParent;
friend class DivertDataAvailableEvent;
friend class DivertStopRequestEvent;
friend class DivertCompleteEvent;
RefPtr<HttpBaseChannel> mChannel;
nsCOMPtr<nsICacheEntry> mCacheEntry;
@ -299,9 +261,6 @@ class HttpChannelParent final : public nsIInterfaceRequestor,
RefPtr<nsHttpHandler> mHttpHandler;
RefPtr<ParentChannelListener> mParentListener;
// The listener we are diverting to or will divert to if mPendingDiversion
// is set.
nsCOMPtr<nsIStreamListener> mDivertListener;
RefPtr<ChannelEventQueue> mEventQ;
@ -341,19 +300,6 @@ class HttpChannelParent final : public nsIInterfaceRequestor,
uint8_t mReceivedRedirect2Verify : 1;
uint8_t mHasSuspendedByBackPressure : 1;
// Indicates that diversion has been requested, but we could not start it
// yet because the channel is still being opened with a synthesized response.
uint8_t mPendingDiversion : 1;
// Once set, no OnStart/OnData/OnStop calls should be accepted; conversely, it
// must be set when RecvDivertOnData/~DivertOnStop/~DivertComplete are
// received from the child channel.
uint8_t mDivertingFromChild : 1;
// Set if OnStart|StopRequest was called during a diversion from the child.
uint8_t mDivertedOnStartRequest : 1;
uint8_t mSuspendedForDiversion : 1;
// Set if we get the result of and cache |mNeedFlowControl|
uint8_t mCacheNeedFlowControlInitialized : 1;
uint8_t mNeedFlowControl : 1;

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

@ -21,9 +21,7 @@ namespace net {
NS_IMPL_ISUPPORTS_INHERITED(InterceptedHttpChannel, HttpBaseChannel,
nsIInterceptedChannel, nsICacheInfoChannel,
nsIAsyncVerifyRedirectCallback, nsIRequestObserver,
nsIStreamListener,
nsIChannelWithDivertableParentListener,
nsIThreadRetargetableRequest,
nsIStreamListener, nsIThreadRetargetableRequest,
nsIThreadRetargetableStreamListener)
InterceptedHttpChannel::InterceptedHttpChannel(
@ -35,8 +33,7 @@ InterceptedHttpChannel::InterceptedHttpChannel(
mSynthesizedStreamLength(-1),
mResumeStartPos(0),
mSynthesizedOrReset(Invalid),
mCallingStatusAndProgress(false),
mDiverting(false) {
mCallingStatusAndProgress(false) {
// Pre-set the creation and AsyncOpen times based on the original channel
// we are intercepting. We don't want our extra internal redirect to mask
// any time spent processing the channel.
@ -57,7 +54,6 @@ void InterceptedHttpChannel::ReleaseListeners() {
mProgressSink = nullptr;
mBodyCallback = nullptr;
mPump = nullptr;
mParentChannel = nullptr;
MOZ_DIAGNOSTIC_ASSERT(!mIsPending);
}
@ -480,15 +476,6 @@ InterceptedHttpChannel::Cancel(nsresult aStatus) {
mStatus = aStatus;
}
// Everything is suspended during diversion until it completes. Since the
// intercepted channel could be a long-running stream, we need to request that
// cancellation be triggered in the child, completing the diversion and
// allowing cancellation to run to completion.
if (mDiverting) {
Unused << mParentChannel->CancelDiversion();
// (We want the pump to be canceled as well, so don't directly return.)
}
if (mPump) {
return mPump->Cancel(mStatus);
}
@ -498,26 +485,20 @@ InterceptedHttpChannel::Cancel(nsresult aStatus) {
NS_IMETHODIMP
InterceptedHttpChannel::Suspend(void) {
nsresult rv = SuspendInternal();
nsresult rvParentChannel = NS_OK;
if (mParentChannel) {
rvParentChannel = mParentChannel->SuspendMessageDiversion();
++mSuspendCount;
if (mPump) {
return mPump->Suspend();
}
return NS_FAILED(rv) ? rv : rvParentChannel;
return NS_OK;
}
NS_IMETHODIMP
InterceptedHttpChannel::Resume(void) {
nsresult rv = ResumeInternal();
nsresult rvParentChannel = NS_OK;
if (mParentChannel) {
rvParentChannel = mParentChannel->ResumeMessageDiversion();
--mSuspendCount;
if (mPump) {
return mPump->Resume();
}
return NS_FAILED(rv) ? rv : rvParentChannel;
return NS_OK;
}
NS_IMETHODIMP
@ -1108,45 +1089,6 @@ InterceptedHttpChannel::OnDataAvailable(nsIRequest* aRequest,
return mListener->OnDataAvailable(this, aInputStream, aOffset, aCount);
}
NS_IMETHODIMP
InterceptedHttpChannel::MessageDiversionStarted(
ADivertableParentChannel* aParentChannel) {
MOZ_ASSERT(!mParentChannel);
mParentChannel = aParentChannel;
mDiverting = true;
uint32_t suspendCount = mSuspendCount;
while (suspendCount--) {
mParentChannel->SuspendMessageDiversion();
}
return NS_OK;
}
NS_IMETHODIMP
InterceptedHttpChannel::MessageDiversionStop() {
MOZ_ASSERT(mParentChannel);
mParentChannel = nullptr;
mDiverting = false;
return NS_OK;
}
NS_IMETHODIMP
InterceptedHttpChannel::SuspendInternal() {
++mSuspendCount;
if (mPump) {
return mPump->Suspend();
}
return NS_OK;
}
NS_IMETHODIMP
InterceptedHttpChannel::ResumeInternal() {
--mSuspendCount;
if (mPump) {
return mPump->Resume();
}
return NS_OK;
}
NS_IMETHODIMP
InterceptedHttpChannel::RetargetDeliveryTo(nsIEventTarget* aNewTarget) {
MOZ_ASSERT(NS_IsMainThread());

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

@ -12,7 +12,6 @@
#include "nsINetworkInterceptController.h"
#include "nsIInputStream.h"
#include "nsICacheInfoChannel.h"
#include "nsIChannelWithDivertableParentListener.h"
#include "nsIThreadRetargetableRequest.h"
#include "nsIThreadRetargetableStreamListener.h"
@ -57,7 +56,6 @@ class InterceptedHttpChannel final
public nsICacheInfoChannel,
public nsIAsyncVerifyRedirectCallback,
public nsIStreamListener,
public nsIChannelWithDivertableParentListener,
public nsIThreadRetargetableRequest,
public nsIThreadRetargetableStreamListener {
NS_DECL_ISUPPORTS_INHERITED
@ -66,7 +64,6 @@ class InterceptedHttpChannel final
NS_DECL_NSIASYNCVERIFYREDIRECTCALLBACK
NS_DECL_NSIREQUESTOBSERVER
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSICHANNELWITHDIVERTABLEPARENTLISTENER
NS_DECL_NSITHREADRETARGETABLEREQUEST
NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
@ -81,7 +78,6 @@ class InterceptedHttpChannel final
nsCOMPtr<nsIInterceptedBodyCallback> mBodyCallback;
nsCOMPtr<nsICacheInfoChannel> mSynthesizedCacheInfo;
RefPtr<nsInputStreamPump> mPump;
RefPtr<ADivertableParentChannel> mParentChannel;
TimeStamp mFinishResponseStart;
TimeStamp mFinishResponseEnd;
Atomic<int64_t> mProgress;
@ -92,7 +88,6 @@ class InterceptedHttpChannel final
nsString mStatusHost;
enum { Invalid = 0, Synthesized, Reset } mSynthesizedOrReset;
Atomic<bool> mCallingStatusAndProgress;
bool mDiverting;
InterceptedHttpChannel(PRTime aCreationTime,
const TimeStamp& aCreationTimestamp,

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

@ -57,13 +57,6 @@ child:
// OnStopRequest.
async OnAfterLastPart(nsresult aStatus);
// Parent has been suspended for diversion; no more events to be enqueued.
async FlushedForDiversion();
// Child should resume processing the ChannelEventQueue, i.e. diverting any
// OnDataAvailable and OnStopRequest messages in the queue back to the parent.
async DivertMessages();
// Tell the child that the resource being loaded has been classified.
async NotifyClassificationFlags(uint32_t aClassificationFlags, bool aIsThirdParty);

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

@ -66,17 +66,6 @@ parent:
// again, indefinitely.
async MarkOfflineCacheEntryAsForeign();
// Divert OnDataAvailable to the parent.
async DivertOnDataAvailable(nsCString data,
uint64_t offset,
uint32_t count);
// Divert OnStopRequest to the parent.
async DivertOnStopRequest(nsresult statusCode);
// Child has no more events/messages to divert to the parent.
async DivertComplete();
// Child has detected a CORS check failure, so needs to tell the parent
// to remove any matching entry from the CORS preflight cache.
async RemoveCorsPreflightCacheEntry(URIParams uri,
@ -147,9 +136,6 @@ child:
nsString url,
nsString contentType);
// See ADivertableParentChannel::CancelDiversion
async CancelDiversion();
async OriginalCacheInputStreamAvailable(IPCStream? stream);
async AltDataCacheInputStreamAvailable(IPCStream? stream);

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

@ -39,9 +39,7 @@ namespace net {
ParentChannelListener::ParentChannelListener(
nsIStreamListener* aListener,
dom::CanonicalBrowsingContext* aBrowsingContext, bool aUsePrivateBrowsing)
: mNextListener(aListener),
mSuspendedForDiversion(false),
mBrowsingContext(aBrowsingContext) {
: mNextListener(aListener), mBrowsingContext(aBrowsingContext) {
LOG(("ParentChannelListener::ParentChannelListener [this=%p, next=%p]", this,
aListener));
@ -78,9 +76,6 @@ NS_INTERFACE_MAP_END
NS_IMETHODIMP
ParentChannelListener::OnStartRequest(nsIRequest* aRequest) {
MOZ_RELEASE_ASSERT(!mSuspendedForDiversion,
"Cannot call OnStartRequest if suspended for diversion!");
if (!mNextListener) return NS_ERROR_UNEXPECTED;
// If we're not a multi-part channel, then we can drop mListener and break the
@ -98,9 +93,6 @@ ParentChannelListener::OnStartRequest(nsIRequest* aRequest) {
NS_IMETHODIMP
ParentChannelListener::OnStopRequest(nsIRequest* aRequest,
nsresult aStatusCode) {
MOZ_RELEASE_ASSERT(!mSuspendedForDiversion,
"Cannot call OnStopRequest if suspended for diversion!");
if (!mNextListener) return NS_ERROR_UNEXPECTED;
LOG(("ParentChannelListener::OnStopRequest: [this=%p status=%" PRIu32 "]\n",
@ -121,9 +113,6 @@ NS_IMETHODIMP
ParentChannelListener::OnDataAvailable(nsIRequest* aRequest,
nsIInputStream* aInputStream,
uint64_t aOffset, uint32_t aCount) {
MOZ_RELEASE_ASSERT(!mSuspendedForDiversion,
"Cannot call OnDataAvailable if suspended for diversion!");
if (!mNextListener) return NS_ERROR_UNEXPECTED;
LOG(("ParentChannelListener::OnDataAvailable [this=%p]\n", this));
@ -236,35 +225,6 @@ ParentChannelListener::ChannelIntercepted(nsIInterceptedChannel* aChannel) {
return NS_OK;
}
//-----------------------------------------------------------------------------
nsresult ParentChannelListener::SuspendForDiversion() {
if (NS_WARN_IF(mSuspendedForDiversion)) {
MOZ_ASSERT(!mSuspendedForDiversion, "Cannot SuspendForDiversion twice!");
return NS_ERROR_UNEXPECTED;
}
// While this is set, no OnStart/OnData/OnStop callbacks should be forwarded
// to mNextListener.
mSuspendedForDiversion = true;
return NS_OK;
}
void ParentChannelListener::ResumeForDiversion() {
MOZ_RELEASE_ASSERT(mSuspendedForDiversion, "Must already be suspended!");
// Allow OnStart/OnData/OnStop callbacks to be forwarded to mNextListener.
mSuspendedForDiversion = false;
}
void ParentChannelListener::DivertTo(nsIStreamListener* aListener) {
MOZ_ASSERT(aListener);
MOZ_RELEASE_ASSERT(mSuspendedForDiversion, "Must already be suspended!");
mNextListener = aListener;
ResumeForDiversion();
}
//-----------------------------------------------------------------------------
// ParentChannelListener::nsIAuthPromptProvider
//

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

@ -53,10 +53,6 @@ class ParentChannelListener final : public nsIInterfaceRequestor,
dom::CanonicalBrowsingContext* aBrowsingContext,
bool aUsePrivateBrowsing);
// For channel diversion from child to parent.
void DivertTo(nsIStreamListener* aListener);
[[nodiscard]] nsresult SuspendForDiversion();
// Called to set a new listener which replaces the old one after a redirect.
void SetListenerAfterRedirect(nsIStreamListener* aListener);
@ -67,16 +63,11 @@ class ParentChannelListener final : public nsIInterfaceRequestor,
private:
virtual ~ParentChannelListener();
// Private partner function to SuspendForDiversion.
void ResumeForDiversion();
// Can be the original HttpChannelParent that created this object (normal
// case), a different {HTTP|FTP}ChannelParent that we've been redirected to,
// or some other listener that we have been diverted to via
// nsIDivertableChannel.
nsCOMPtr<nsIStreamListener> mNextListener;
// When set, no OnStart/OnData/OnStop calls should be received.
bool mSuspendedForDiversion;
// This will be populated with a real network controller if parent-side
// interception is enabled.

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

@ -6372,7 +6372,6 @@ NS_INTERFACE_MAP_BEGIN(nsHttpChannel)
NS_INTERFACE_MAP_ENTRY(nsICorsPreflightCallback)
NS_INTERFACE_MAP_ENTRY(nsIRaceCacheWithNetwork)
NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
NS_INTERFACE_MAP_ENTRY(nsIChannelWithDivertableParentListener)
NS_INTERFACE_MAP_ENTRY(nsIRequestTailUnblockCallback)
NS_INTERFACE_MAP_ENTRY_CONCRETE(nsHttpChannel)
NS_INTERFACE_MAP_END_INHERITING(HttpBaseChannel)
@ -6535,26 +6534,135 @@ void nsHttpChannel::CancelNetworkRequest(nsresult aStatus) {
NS_IMETHODIMP
nsHttpChannel::Suspend() {
nsresult rv = SuspendInternal();
NS_ENSURE_TRUE(mIsPending, NS_ERROR_NOT_AVAILABLE);
nsresult rvParentChannel = NS_OK;
if (mParentChannel) {
rvParentChannel = mParentChannel->SuspendMessageDiversion();
LOG(("nsHttpChannel::SuspendInternal [this=%p]\n", this));
LogCallingScriptLocation(this);
++mSuspendCount;
if (mSuspendCount == 1) {
mSuspendTimestamp = TimeStamp::NowLoRes();
}
return NS_FAILED(rv) ? rv : rvParentChannel;
nsresult rvTransaction = NS_OK;
if (mTransactionPump) {
rvTransaction = mTransactionPump->Suspend();
}
nsresult rvCache = NS_OK;
if (mCachePump) {
rvCache = mCachePump->Suspend();
}
return NS_FAILED(rvTransaction) ? rvTransaction : rvCache;
}
NS_IMETHODIMP
nsHttpChannel::Resume() {
nsresult rv = ResumeInternal();
NS_ENSURE_TRUE(mSuspendCount > 0, NS_ERROR_UNEXPECTED);
nsresult rvParentChannel = NS_OK;
if (mParentChannel) {
rvParentChannel = mParentChannel->ResumeMessageDiversion();
LOG(("nsHttpChannel::ResumeInternal [this=%p]\n", this));
LogCallingScriptLocation(this);
if (--mSuspendCount == 0) {
mSuspendTotalTime +=
(TimeStamp::NowLoRes() - mSuspendTimestamp).ToMilliseconds();
if (mCallOnResume) {
// Resume the interrupted procedure first, then resume
// the pump to continue process the input stream.
// Any newly created pump MUST be suspended to prevent calling
// its OnStartRequest before OnStopRequest of any pre-existing
// pump. mAsyncResumePending ensures that.
MOZ_ASSERT(!mAsyncResumePending);
mAsyncResumePending = 1;
std::function<nsresult(nsHttpChannel*)> callOnResume = nullptr;
std::swap(callOnResume, mCallOnResume);
RefPtr<nsHttpChannel> self(this);
nsCOMPtr<nsIRequest> transactionPump = mTransactionPump;
RefPtr<nsInputStreamPump> cachePump = mCachePump;
nsresult rv = NS_DispatchToCurrentThread(NS_NewRunnableFunction(
"nsHttpChannel::CallOnResume",
[callOnResume{std::move(callOnResume)}, self{std::move(self)},
transactionPump{std::move(transactionPump)},
cachePump{std::move(cachePump)}]() {
MOZ_ASSERT(self->mAsyncResumePending);
nsresult rv = self->CallOrWaitForResume(callOnResume);
if (NS_FAILED(rv)) {
self->CloseCacheEntry(false);
Unused << self->AsyncAbort(rv);
}
MOZ_ASSERT(self->mAsyncResumePending);
self->mAsyncResumePending = 0;
// And now actually resume the previously existing pumps.
if (transactionPump) {
LOG(
("nsHttpChannel::CallOnResume resuming previous transaction "
"pump %p, this=%p",
transactionPump.get(), self.get()));
transactionPump->Resume();
}
if (cachePump) {
LOG(
("nsHttpChannel::CallOnResume resuming previous cache pump "
"%p, this=%p",
cachePump.get(), self.get()));
cachePump->Resume();
}
return NS_FAILED(rv) ? rv : rvParentChannel;
// Any newly created pumps were suspended once because of
// mAsyncResumePending. Problem is that the stream listener
// notification is already pending in the queue right now, because
// AsyncRead doesn't (regardless if called after Suspend) respect
// the suspend coutner and the right order would not be preserved.
// Hence, we do another dispatch round to actually Resume after
// the notification from the original pump.
if (transactionPump != self->mTransactionPump &&
self->mTransactionPump) {
LOG(
("nsHttpChannel::CallOnResume async-resuming new "
"transaction "
"pump %p, this=%p",
self->mTransactionPump.get(), self.get()));
nsCOMPtr<nsIRequest> pump = self->mTransactionPump;
NS_DispatchToCurrentThread(NS_NewRunnableFunction(
"nsHttpChannel::CallOnResume new transaction",
[pump{std::move(pump)}]() { pump->Resume(); }));
}
if (cachePump != self->mCachePump && self->mCachePump) {
LOG(
("nsHttpChannel::CallOnResume async-resuming new cache pump "
"%p, this=%p",
self->mCachePump.get(), self.get()));
RefPtr<nsInputStreamPump> pump = self->mCachePump;
NS_DispatchToCurrentThread(NS_NewRunnableFunction(
"nsHttpChannel::CallOnResume new pump",
[pump{std::move(pump)}]() { pump->Resume(); }));
}
}));
NS_ENSURE_SUCCESS(rv, rv);
return rv;
}
}
nsresult rvTransaction = NS_OK;
if (mTransactionPump) {
rvTransaction = mTransactionPump->Resume();
}
nsresult rvCache = NS_OK;
if (mCachePump) {
rvCache = mCachePump->Resume();
}
return NS_FAILED(rvTransaction) ? rvTransaction : rvCache;
}
//-----------------------------------------------------------------------------
@ -6910,13 +7018,13 @@ nsresult nsHttpChannel::BeginConnect() {
RefPtr<AltSvcMapping> mapping;
if (!mConnectionInfo && mAllowAltSvc && // per channel
(http2Allowed || http3Allowed) &&
!(mLoadFlags & LOAD_FRESH_CONNECTION) &&
(http2Allowed || http3Allowed) && !(mLoadFlags & LOAD_FRESH_CONNECTION) &&
AltSvcMapping::AcceptableProxy(proxyInfo) &&
(scheme.EqualsLiteral("http") || scheme.EqualsLiteral("https")) &&
(mapping = gHttpHandler->GetAltServiceMapping(
scheme, host, port, mPrivateBrowsing, IsIsolated(),
GetTopWindowOrigin(), originAttributes, http2Allowed, http3Allowed))) {
GetTopWindowOrigin(), originAttributes, http2Allowed,
http3Allowed))) {
LOG(("nsHttpChannel %p Alt Service Mapping Found %s://%s:%d [%s]\n", this,
scheme.get(), mapping->AlternateHost().get(), mapping->AlternatePort(),
mapping->HashKey().get()));
@ -9535,57 +9643,6 @@ nsHttpChannel::OnPreflightFailed(nsresult aError) {
return NS_OK;
}
//-----------------------------------------------------------------------------
// AChannelHasDivertableParentChannelAsListener internal functions
//-----------------------------------------------------------------------------
NS_IMETHODIMP
nsHttpChannel::MessageDiversionStarted(
ADivertableParentChannel* aParentChannel) {
LOG(("nsHttpChannel::MessageDiversionStarted [this=%p]", this));
MOZ_ASSERT(!mParentChannel);
mParentChannel = aParentChannel;
// If the channel is suspended, propagate that info to the parent's mEventQ.
uint32_t suspendCount = mSuspendCount;
while (suspendCount--) {
mParentChannel->SuspendMessageDiversion();
}
return NS_OK;
}
NS_IMETHODIMP
nsHttpChannel::MessageDiversionStop() {
LOG(("nsHttpChannel::MessageDiversionStop [this=%p]", this));
MOZ_ASSERT(mParentChannel);
mParentChannel = nullptr;
return NS_OK;
}
NS_IMETHODIMP
nsHttpChannel::SuspendInternal() {
NS_ENSURE_TRUE(mIsPending, NS_ERROR_NOT_AVAILABLE);
LOG(("nsHttpChannel::SuspendInternal [this=%p]\n", this));
LogCallingScriptLocation(this);
++mSuspendCount;
if (mSuspendCount == 1) {
mSuspendTimestamp = TimeStamp::NowLoRes();
}
nsresult rvTransaction = NS_OK;
if (mTransactionPump) {
rvTransaction = mTransactionPump->Suspend();
}
nsresult rvCache = NS_OK;
if (mCachePump) {
rvCache = mCachePump->Suspend();
}
return NS_FAILED(rvTransaction) ? rvTransaction : rvCache;
}
nsresult nsHttpChannel::CallOrWaitForResume(
const std::function<nsresult(nsHttpChannel*)>& aFunc) {
if (mCanceled) {
@ -9603,114 +9660,6 @@ nsresult nsHttpChannel::CallOrWaitForResume(
return aFunc(this);
}
NS_IMETHODIMP
nsHttpChannel::ResumeInternal() {
NS_ENSURE_TRUE(mSuspendCount > 0, NS_ERROR_UNEXPECTED);
LOG(("nsHttpChannel::ResumeInternal [this=%p]\n", this));
LogCallingScriptLocation(this);
if (--mSuspendCount == 0) {
mSuspendTotalTime +=
(TimeStamp::NowLoRes() - mSuspendTimestamp).ToMilliseconds();
if (mCallOnResume) {
// Resume the interrupted procedure first, then resume
// the pump to continue process the input stream.
// Any newly created pump MUST be suspended to prevent calling
// its OnStartRequest before OnStopRequest of any pre-existing
// pump. mAsyncResumePending ensures that.
MOZ_ASSERT(!mAsyncResumePending);
mAsyncResumePending = 1;
std::function<nsresult(nsHttpChannel*)> callOnResume = nullptr;
std::swap(callOnResume, mCallOnResume);
RefPtr<nsHttpChannel> self(this);
nsCOMPtr<nsIRequest> transactionPump = mTransactionPump;
RefPtr<nsInputStreamPump> cachePump = mCachePump;
nsresult rv = NS_DispatchToCurrentThread(NS_NewRunnableFunction(
"nsHttpChannel::CallOnResume",
[callOnResume{std::move(callOnResume)}, self{std::move(self)},
transactionPump{std::move(transactionPump)},
cachePump{std::move(cachePump)}]() {
MOZ_ASSERT(self->mAsyncResumePending);
nsresult rv = self->CallOrWaitForResume(callOnResume);
if (NS_FAILED(rv)) {
self->CloseCacheEntry(false);
Unused << self->AsyncAbort(rv);
}
MOZ_ASSERT(self->mAsyncResumePending);
self->mAsyncResumePending = 0;
// And now actually resume the previously existing pumps.
if (transactionPump) {
LOG(
("nsHttpChannel::CallOnResume resuming previous transaction "
"pump %p, this=%p",
transactionPump.get(), self.get()));
transactionPump->Resume();
}
if (cachePump) {
LOG(
("nsHttpChannel::CallOnResume resuming previous cache pump "
"%p, this=%p",
cachePump.get(), self.get()));
cachePump->Resume();
}
// Any newly created pumps were suspended once because of
// mAsyncResumePending. Problem is that the stream listener
// notification is already pending in the queue right now, because
// AsyncRead doesn't (regardless if called after Suspend) respect
// the suspend coutner and the right order would not be preserved.
// Hence, we do another dispatch round to actually Resume after
// the notification from the original pump.
if (transactionPump != self->mTransactionPump &&
self->mTransactionPump) {
LOG(
("nsHttpChannel::CallOnResume async-resuming new "
"transaction "
"pump %p, this=%p",
self->mTransactionPump.get(), self.get()));
nsCOMPtr<nsIRequest> pump = self->mTransactionPump;
NS_DispatchToCurrentThread(NS_NewRunnableFunction(
"nsHttpChannel::CallOnResume new transaction",
[pump{std::move(pump)}]() { pump->Resume(); }));
}
if (cachePump != self->mCachePump && self->mCachePump) {
LOG(
("nsHttpChannel::CallOnResume async-resuming new cache pump "
"%p, this=%p",
self->mCachePump.get(), self.get()));
RefPtr<nsInputStreamPump> pump = self->mCachePump;
NS_DispatchToCurrentThread(NS_NewRunnableFunction(
"nsHttpChannel::CallOnResume new pump",
[pump{std::move(pump)}]() { pump->Resume(); }));
}
}));
NS_ENSURE_SUCCESS(rv, rv);
return rv;
}
}
nsresult rvTransaction = NS_OK;
if (mTransactionPump) {
rvTransaction = mTransactionPump->Resume();
}
nsresult rvCache = NS_OK;
if (mCachePump) {
rvCache = mCachePump->Resume();
}
return NS_FAILED(rvTransaction) ? rvTransaction : rvCache;
}
void nsHttpChannel::MaybeWarnAboutAppCache() {
// First, accumulate a telemetry ping about appcache usage.
Telemetry::Accumulate(Telemetry::HTTP_OFFLINE_CACHE_DOCUMENT_LOAD, true);

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

@ -15,7 +15,6 @@
#include "nsICacheEntryOpenCallback.h"
#include "nsIDNSListener.h"
#include "nsIApplicationCacheChannel.h"
#include "nsIChannelWithDivertableParentListener.h"
#include "nsIProtocolProxyCallback.h"
#include "nsIHttpAuthenticableChannel.h"
#include "nsIAsyncVerifyRedirectCallback.h"
@ -23,7 +22,6 @@
#include "nsIThreadRetargetableStreamListener.h"
#include "nsWeakReference.h"
#include "TimingStruct.h"
#include "ADivertableParentChannel.h"
#include "AutoClose.h"
#include "nsIStreamListener.h"
#include "nsICorsPreflightCallback.h"
@ -77,7 +75,6 @@ class nsHttpChannel final : public HttpBaseChannel,
public nsIDNSListener,
public nsSupportsWeakReference,
public nsICorsPreflightCallback,
public nsIChannelWithDivertableParentListener,
public nsIRaceCacheWithNetwork,
public nsIRequestTailUnblockCallback,
public nsITimerCallback {
@ -97,7 +94,6 @@ class nsHttpChannel final : public HttpBaseChannel,
NS_DECL_NSIASYNCVERIFYREDIRECTCALLBACK
NS_DECL_NSITHREADRETARGETABLEREQUEST
NS_DECL_NSIDNSLISTENER
NS_DECL_NSICHANNELWITHDIVERTABLEPARENTLISTENER
NS_DECLARE_STATIC_IID_ACCESSOR(NS_HTTPCHANNEL_IID)
NS_DECL_NSIRACECACHEWITHNETWORK
NS_DECL_NSITIMERCALLBACK
@ -791,8 +787,6 @@ class nsHttpChannel final : public HttpBaseChannel,
// If non-null, warnings should be reported to this object.
RefPtr<HttpChannelSecurityWarningReporter> mWarningReporter;
RefPtr<ADivertableParentChannel> mParentChannel;
// True if the channel is reading from cache.
Atomic<bool> mIsReadingFromCache;

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

@ -14,7 +14,6 @@
#include "nsIMIMEService.h"
#include "nsIDivertableChannel.h"
#include "nsIViewSourceChannel.h"
#include "nsIHttpChannel.h"
#include "nsIForcePendingChannel.h"
@ -215,16 +214,6 @@ nsUnknownDecoder::OnDataAvailable(nsIRequest* request, nsIInputStream* aStream,
}
#endif
nsCOMPtr<nsIDivertableChannel> divertable = do_QueryInterface(request);
if (divertable) {
bool diverting;
divertable->GetDivertingToParent(&diverting);
if (diverting) {
// The channel is diverted to the parent do not send any more data here.
return rv;
}
}
nsCOMPtr<nsIStreamListener> listener;
{
MutexAutoLock lock(mMutex);
@ -260,11 +249,6 @@ nsUnknownDecoder::OnStartRequest(nsIRequest* request) {
}
}
nsCOMPtr<nsIDivertableChannel> divertable = do_QueryInterface(request);
if (divertable) {
divertable->UnknownDecoderInvolvedKeepData();
}
// Do not pass the OnStartRequest on to the next listener (yet)...
return rv;
}
@ -735,12 +719,6 @@ nsresult nsUnknownDecoder::FireListenerNotifications(nsIRequest* request,
// mNextListener looks at it.
request->Cancel(rv);
listener->OnStartRequest(request);
nsCOMPtr<nsIDivertableChannel> divertable = do_QueryInterface(request);
if (divertable) {
rv = divertable->UnknownDecoderInvolvedOnStartRequestCalled();
}
return rv;
}
}
@ -748,17 +726,6 @@ nsresult nsUnknownDecoder::FireListenerNotifications(nsIRequest* request,
// Fire the OnStartRequest(...)
rv = listener->OnStartRequest(request);
nsCOMPtr<nsIDivertableChannel> divertable = do_QueryInterface(request);
if (divertable) {
rv = divertable->UnknownDecoderInvolvedOnStartRequestCalled();
bool diverting;
divertable->GetDivertingToParent(&diverting);
if (diverting) {
// The channel is diverted to the parent do not send any more data here.
return rv;
}
}
if (NS_SUCCEEDED(rv)) {
// install stream converter if required
nsCOMPtr<nsIEncodedChannel> encodedChannel = do_QueryInterface(request);

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

@ -5,9 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ExternalHelperAppChild.h"
#include "mozilla/net/ChannelDiverterChild.h"
#include "mozilla/dom/BrowserChild.h"
#include "nsIDivertableChannel.h"
#include "nsIInputStream.h"
#include "nsIRequest.h"
#include "nsIResumableChannel.h"
@ -64,11 +62,6 @@ ExternalHelperAppChild::OnStartRequest(nsIRequest* request) {
nsresult rv = mHandler->OnStartRequest(request);
NS_ENSURE_SUCCESS(rv, NS_ERROR_UNEXPECTED);
nsCOMPtr<nsIDivertableChannel> divertable = do_QueryInterface(request);
if (divertable) {
return DivertToParent(divertable, request);
}
nsCString entityID;
nsCOMPtr<nsIResumableChannel> resumable(do_QueryInterface(request));
if (resumable) {
@ -90,28 +83,6 @@ ExternalHelperAppChild::OnStopRequest(nsIRequest* request, nsresult status) {
return NS_OK;
}
nsresult ExternalHelperAppChild::DivertToParent(
nsIDivertableChannel* divertable, nsIRequest* request) {
// nsIDivertable must know about content conversions before being diverted.
MOZ_ASSERT(mHandler);
mHandler->MaybeApplyDecodingForExtension(request);
mozilla::net::ChannelDiverterChild* diverter = nullptr;
nsresult rv = divertable->DivertToParent(&diverter);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
MOZ_ASSERT(diverter);
if (SendDivertToParentUsing(diverter)) {
mHandler->DidDivertRequest(request);
mHandler = nullptr;
return NS_OK;
}
return NS_ERROR_FAILURE;
}
mozilla::ipc::IPCResult ExternalHelperAppChild::RecvCancel(
const nsresult& aStatus) {
mStatus = aStatus;

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

@ -35,8 +35,6 @@ class ExternalHelperAppChild : public PExternalHelperAppChild,
private:
virtual ~ExternalHelperAppChild();
[[nodiscard]] nsresult DivertToParent(nsIDivertableChannel* divertable,
nsIRequest* request);
RefPtr<nsExternalAppHandler> mHandler;
nsresult mStatus;

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

@ -17,7 +17,6 @@
#include "mozilla/ipc/URIUtils.h"
#include "nsNetUtil.h"
#include "mozilla/dom/Document.h"
#include "mozilla/net/ChannelDiverterParent.h"
#include "mozilla/dom/CanonicalBrowsingContext.h"
#include "mozilla/dom/WindowGlobalParent.h"
#include "nsQueryObject.h"
@ -40,12 +39,7 @@ ExternalHelperAppParent::ExternalHelperAppParent(
const uint32_t& aContentDispositionHint,
const nsString& aContentDispositionFilename)
: mURI(uri),
mPending(false)
#ifdef DEBUG
,
mDiverted(false)
#endif
,
mPending(false),
mIPCClosed(false),
mLoadFlags(0),
mStatus(NS_OK),
@ -116,9 +110,6 @@ void ExternalHelperAppParent::Delete() {
mozilla::ipc::IPCResult ExternalHelperAppParent::RecvOnStartRequest(
const nsCString& entityID) {
MOZ_ASSERT(!mDiverted,
"child forwarding callbacks after request was diverted");
mEntityID = entityID;
mPending = true;
mStatus = mListener->OnStartRequest(this);
@ -131,8 +122,6 @@ mozilla::ipc::IPCResult ExternalHelperAppParent::RecvOnDataAvailable(
return IPC_OK();
}
MOZ_ASSERT(!mDiverted,
"child forwarding callbacks after request was diverted");
MOZ_ASSERT(mPending, "must be pending!");
nsCOMPtr<nsIInputStream> stringStream;
@ -146,9 +135,6 @@ mozilla::ipc::IPCResult ExternalHelperAppParent::RecvOnDataAvailable(
mozilla::ipc::IPCResult ExternalHelperAppParent::RecvOnStopRequest(
const nsresult& code) {
MOZ_ASSERT(!mDiverted,
"child forwarding callbacks after request was diverted");
mPending = false;
mListener->OnStopRequest(
this, (NS_SUCCEEDED(code) && NS_FAILED(mStatus)) ? mStatus : code);
@ -156,18 +142,6 @@ mozilla::ipc::IPCResult ExternalHelperAppParent::RecvOnStopRequest(
return IPC_OK();
}
mozilla::ipc::IPCResult ExternalHelperAppParent::RecvDivertToParentUsing(
PChannelDiverterParent* diverter) {
MOZ_ASSERT(diverter);
auto p = static_cast<mozilla::net::ChannelDiverterParent*>(diverter);
p->DivertTo(this);
#ifdef DEBUG
mDiverted = true;
#endif
Unused << mozilla::net::ChannelDiverterParent::Send__delete__(p);
return IPC_OK();
}
//
// nsIStreamListener
//
@ -176,19 +150,16 @@ NS_IMETHODIMP
ExternalHelperAppParent::OnDataAvailable(nsIRequest* request,
nsIInputStream* input, uint64_t offset,
uint32_t count) {
MOZ_ASSERT(mDiverted);
return mListener->OnDataAvailable(request, input, offset, count);
}
NS_IMETHODIMP
ExternalHelperAppParent::OnStartRequest(nsIRequest* request) {
MOZ_ASSERT(mDiverted);
return mListener->OnStartRequest(request);
}
NS_IMETHODIMP
ExternalHelperAppParent::OnStopRequest(nsIRequest* request, nsresult status) {
MOZ_ASSERT(mDiverted);
nsresult rv = mListener->OnStopRequest(request, status);
Delete();
return rv;

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

@ -75,9 +75,6 @@ class ExternalHelperAppParent
const uint32_t& count) override;
mozilla::ipc::IPCResult RecvOnStopRequest(const nsresult& code) override;
mozilla::ipc::IPCResult RecvDivertToParentUsing(
PChannelDiverterParent* diverter) override;
bool WasFileChannel() override { return mWasFileChannel; }
ExternalHelperAppParent(nsIURI* uri, const int64_t& contentLength,
@ -101,9 +98,6 @@ class ExternalHelperAppParent
nsCOMPtr<nsIURI> mURI;
nsCOMPtr<nsILoadInfo> mLoadInfo;
bool mPending;
#ifdef DEBUG
bool mDiverted;
#endif
bool mIPCClosed;
nsLoadFlags mLoadFlags;
nsresult mStatus;

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

@ -5,7 +5,6 @@
include protocol PBrowser;
include protocol PContent;
include protocol PChannelDiverter;
namespace mozilla {
namespace dom {
@ -19,8 +18,6 @@ parent:
async OnDataAvailable(nsCString data, uint64_t offset, uint32_t count);
async OnStopRequest(nsresult code);
async DivertToParentUsing(PChannelDiverter diverter);
child:
async Cancel(nsresult aStatus);
async __delete__();