2010-08-10 22:47:00 +04:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set sw=2 ts=8 et tw=80 : */
|
|
|
|
|
2012-05-21 15:12:37 +04:00
|
|
|
/* 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/. */
|
2010-08-10 22:47:00 +04:00
|
|
|
|
|
|
|
#include "mozilla/net/NeckoChild.h"
|
2014-03-11 02:04:28 +04:00
|
|
|
#include "mozilla/net/ChannelDiverterChild.h"
|
2010-08-10 22:47:00 +04:00
|
|
|
#include "mozilla/net/FTPChannelChild.h"
|
2017-03-09 16:09:31 +03:00
|
|
|
#include "mozilla/dom/ContentChild.h"
|
2017-03-24 01:31:00 +03:00
|
|
|
#include "mozilla/dom/DocGroup.h"
|
2019-04-10 01:39:01 +03:00
|
|
|
#include "mozilla/dom/BrowserChild.h"
|
2017-03-24 01:31:00 +03:00
|
|
|
#include "nsContentUtils.h"
|
2010-08-10 22:47:00 +04:00
|
|
|
#include "nsFtpProtocolHandler.h"
|
2019-04-10 02:15:02 +03:00
|
|
|
#include "nsIBrowserChild.h"
|
2010-08-10 22:47:00 +04:00
|
|
|
#include "nsStringStream.h"
|
|
|
|
#include "nsNetUtil.h"
|
2012-04-05 11:03:14 +04:00
|
|
|
#include "base/compiler_specific.h"
|
2017-03-09 16:09:31 +03:00
|
|
|
#include "mozilla/ipc/IPCStreamUtils.h"
|
2012-08-23 23:33:46 +04:00
|
|
|
#include "mozilla/ipc/URIUtils.h"
|
2013-10-19 00:57:55 +04:00
|
|
|
#include "SerializedLoadContext.h"
|
2014-09-21 20:40:27 +04:00
|
|
|
#include "mozilla/ipc/BackgroundUtils.h"
|
2018-01-08 17:20:35 +03:00
|
|
|
#include "nsIURIMutator.h"
|
2019-02-12 19:08:25 +03:00
|
|
|
#include "nsContentSecurityManager.h"
|
2012-08-23 06:13:54 +04:00
|
|
|
|
2017-05-26 04:09:00 +03:00
|
|
|
using mozilla::dom::ContentChild;
|
2012-08-23 06:13:54 +04:00
|
|
|
using namespace mozilla::ipc;
|
2010-08-10 22:47:00 +04:00
|
|
|
|
|
|
|
#undef LOG
|
2015-06-04 01:25:57 +03:00
|
|
|
#define LOG(args) MOZ_LOG(gFTPLog, mozilla::LogLevel::Debug, args)
|
2010-08-10 22:47:00 +04:00
|
|
|
|
|
|
|
namespace mozilla {
|
|
|
|
namespace net {
|
|
|
|
|
2019-11-15 05:42:20 +03:00
|
|
|
FTPChannelChild::FTPChannelChild(nsIURI* aUri)
|
2017-07-05 01:47:00 +03:00
|
|
|
: mIPCOpen(false),
|
2019-11-15 05:42:20 +03:00
|
|
|
mEventQ(new ChannelEventQueue(static_cast<nsIFTPChannel*>(this))),
|
2015-10-11 19:13:09 +03:00
|
|
|
mUnknownDecoderInvolved(false),
|
2010-08-10 22:47:00 +04:00
|
|
|
mCanceled(false),
|
|
|
|
mSuspendCount(0),
|
2011-10-17 18:59:28 +04:00
|
|
|
mIsPending(false),
|
2010-08-10 22:47:00 +04:00
|
|
|
mLastModifiedTime(0),
|
|
|
|
mStartPos(0),
|
2014-03-11 02:04:28 +04:00
|
|
|
mDivertingToParent(false),
|
|
|
|
mFlushedForDiversion(false),
|
|
|
|
mSuspendSent(false) {
|
2016-12-16 06:16:31 +03:00
|
|
|
LOG(("Creating FTPChannelChild @%p\n", this));
|
2010-08-10 22:47:00 +04:00
|
|
|
// grab a reference to the handler to ensure that it doesn't go away.
|
|
|
|
NS_ADDREF(gFtpHandler);
|
2019-11-15 05:42:20 +03:00
|
|
|
SetURI(aUri);
|
2014-06-17 20:39:26 +04:00
|
|
|
|
|
|
|
// We could support thread retargeting, but as long as we're being driven by
|
|
|
|
// IPDL on the main thread it doesn't buy us anything.
|
|
|
|
DisallowThreadRetargeting();
|
2010-08-10 22:47:00 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
FTPChannelChild::~FTPChannelChild() {
|
2016-12-16 06:16:31 +03:00
|
|
|
LOG(("Destroying FTPChannelChild @%p\n", this));
|
2010-08-10 22:47:00 +04:00
|
|
|
gFtpHandler->Release();
|
|
|
|
}
|
|
|
|
|
|
|
|
void FTPChannelChild::AddIPDLReference() {
|
2015-02-10 01:34:50 +03:00
|
|
|
MOZ_ASSERT(!mIPCOpen, "Attempt to retain more than one IPDL reference");
|
2010-08-10 22:47:00 +04:00
|
|
|
mIPCOpen = true;
|
|
|
|
AddRef();
|
|
|
|
}
|
|
|
|
|
|
|
|
void FTPChannelChild::ReleaseIPDLReference() {
|
2015-02-10 01:34:50 +03:00
|
|
|
MOZ_ASSERT(mIPCOpen, "Attempt to release nonexistent IPDL reference");
|
2010-08-10 22:47:00 +04:00
|
|
|
mIPCOpen = false;
|
|
|
|
Release();
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// FTPChannelChild::nsISupports
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
2014-04-27 11:06:00 +04:00
|
|
|
NS_IMPL_ISUPPORTS_INHERITED(FTPChannelChild, nsBaseChannel, nsIFTPChannel,
|
|
|
|
nsIUploadChannel, nsIResumableChannel,
|
|
|
|
nsIProxiedChannel, nsIChildChannel,
|
|
|
|
nsIDivertableChannel)
|
2010-08-10 22:47:00 +04:00
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2019-11-15 05:42:20 +03:00
|
|
|
FTPChannelChild::GetLastModifiedTime(PRTime* aLastModifiedTime) {
|
|
|
|
*aLastModifiedTime = mLastModifiedTime;
|
2010-08-10 22:47:00 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2019-11-15 05:42:20 +03:00
|
|
|
FTPChannelChild::SetLastModifiedTime(PRTime aLastModifiedTime) {
|
2010-08-10 22:47:00 +04:00
|
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2012-08-22 19:56:38 +04:00
|
|
|
FTPChannelChild::ResumeAt(uint64_t aStartPos, const nsACString& aEntityID) {
|
2010-08-10 22:47:00 +04:00
|
|
|
NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS);
|
|
|
|
mStartPos = aStartPos;
|
|
|
|
mEntityID = aEntityID;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2019-11-15 05:42:20 +03:00
|
|
|
FTPChannelChild::GetEntityID(nsACString& aEntityID) {
|
|
|
|
aEntityID = mEntityID;
|
2010-08-10 22:47:00 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
FTPChannelChild::GetProxyInfo(nsIProxyInfo** aProxyInfo) { DROP_DEAD(); }
|
|
|
|
|
2019-11-21 19:02:47 +03:00
|
|
|
NS_IMETHODIMP FTPChannelChild::GetHttpProxyConnectResponseCode(
|
|
|
|
int32_t* aResponseCode) {
|
|
|
|
DROP_DEAD();
|
|
|
|
}
|
|
|
|
|
2010-08-10 22:47:00 +04:00
|
|
|
NS_IMETHODIMP
|
2019-11-15 05:42:20 +03:00
|
|
|
FTPChannelChild::SetUploadStream(nsIInputStream* aStream,
|
|
|
|
const nsACString& aContentType,
|
|
|
|
int64_t aContentLength) {
|
2010-08-10 22:47:00 +04:00
|
|
|
NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS);
|
2019-11-15 05:42:20 +03:00
|
|
|
mUploadStream = aStream;
|
2010-08-10 22:47:00 +04:00
|
|
|
// NOTE: contentLength is intentionally ignored here.
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2019-11-15 05:42:20 +03:00
|
|
|
FTPChannelChild::GetUploadStream(nsIInputStream** aStream) {
|
|
|
|
NS_ENSURE_ARG_POINTER(aStream);
|
|
|
|
*aStream = mUploadStream;
|
|
|
|
NS_IF_ADDREF(*aStream);
|
2010-08-10 22:47:00 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2019-02-12 19:08:25 +03:00
|
|
|
FTPChannelChild::AsyncOpen(nsIStreamListener* aListener) {
|
|
|
|
nsCOMPtr<nsIStreamListener> listener = aListener;
|
|
|
|
nsresult rv =
|
|
|
|
nsContentSecurityManager::doContentSecurityCheck(this, listener);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
2013-06-05 03:32:31 +04:00
|
|
|
LOG(("FTPChannelChild::AsyncOpen [this=%p]\n", this));
|
2010-08-10 22:47:00 +04:00
|
|
|
|
|
|
|
NS_ENSURE_TRUE((gNeckoChild), NS_ERROR_FAILURE);
|
2017-05-26 04:09:00 +03:00
|
|
|
NS_ENSURE_TRUE(
|
|
|
|
!static_cast<ContentChild*>(gNeckoChild->Manager())->IsShuttingDown(),
|
|
|
|
NS_ERROR_FAILURE);
|
2010-08-10 22:47:00 +04:00
|
|
|
NS_ENSURE_ARG_POINTER(listener);
|
|
|
|
NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS);
|
|
|
|
NS_ENSURE_TRUE(!mWasOpened, NS_ERROR_ALREADY_OPENED);
|
|
|
|
|
|
|
|
// Port checked in parent, but duplicate here so we can return with error
|
|
|
|
// immediately, as we've done since before e10s.
|
|
|
|
rv = NS_CheckPortSafety(nsBaseChannel::URI()); // Need to disambiguate,
|
|
|
|
// because in the child ipdl,
|
|
|
|
// a typedef URI is defined...
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
2019-04-10 01:39:01 +03:00
|
|
|
mozilla::dom::BrowserChild* browserChild = nullptr;
|
|
|
|
nsCOMPtr<nsIBrowserChild> iBrowserChild;
|
2019-04-10 02:15:02 +03:00
|
|
|
NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup,
|
|
|
|
NS_GET_IID(nsIBrowserChild),
|
2019-04-10 01:39:01 +03:00
|
|
|
getter_AddRefs(iBrowserChild));
|
|
|
|
GetCallback(iBrowserChild);
|
|
|
|
if (iBrowserChild) {
|
|
|
|
browserChild =
|
|
|
|
static_cast<mozilla::dom::BrowserChild*>(iBrowserChild.get());
|
2012-12-29 13:02:16 +04:00
|
|
|
}
|
2019-04-10 01:39:01 +03:00
|
|
|
if (MissingRequiredBrowserChild(browserChild, "ftp")) {
|
2013-01-24 23:24:00 +04:00
|
|
|
return NS_ERROR_ILLEGAL_VALUE;
|
|
|
|
}
|
2012-12-29 13:02:16 +04:00
|
|
|
|
2010-08-10 22:47:00 +04:00
|
|
|
mListener = listener;
|
|
|
|
|
2017-07-06 15:00:35 +03:00
|
|
|
// add ourselves to the load group.
|
2012-07-30 18:20:58 +04:00
|
|
|
if (mLoadGroup) mLoadGroup->AddRequest(this, nullptr);
|
2010-08-10 22:47:00 +04:00
|
|
|
|
2017-03-09 16:09:31 +03:00
|
|
|
mozilla::ipc::AutoIPCStream autoStream;
|
|
|
|
autoStream.Serialize(mUploadStream,
|
2017-05-26 04:09:00 +03:00
|
|
|
static_cast<ContentChild*>(gNeckoChild->Manager()));
|
2012-08-23 06:13:54 +04:00
|
|
|
|
2018-05-21 23:24:25 +03:00
|
|
|
uint32_t loadFlags = 0;
|
|
|
|
GetLoadFlags(&loadFlags);
|
|
|
|
|
2013-06-22 20:09:19 +04:00
|
|
|
FTPChannelOpenArgs openArgs;
|
|
|
|
SerializeURI(nsBaseChannel::URI(), openArgs.uri());
|
|
|
|
openArgs.startPos() = mStartPos;
|
|
|
|
openArgs.entityID() = mEntityID;
|
2017-03-09 16:09:31 +03:00
|
|
|
openArgs.uploadStream() = autoStream.TakeOptionalValue();
|
2018-05-21 23:24:25 +03:00
|
|
|
openArgs.loadFlags() = loadFlags;
|
2013-06-22 20:09:19 +04:00
|
|
|
|
2019-04-25 15:16:35 +03:00
|
|
|
nsCOMPtr<nsILoadInfo> loadInfo = LoadInfo();
|
2015-06-19 01:37:20 +03:00
|
|
|
rv = mozilla::ipc::LoadInfoToLoadInfoArgs(loadInfo, &openArgs.loadInfo());
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2014-09-21 20:40:27 +04:00
|
|
|
|
2017-03-24 01:31:00 +03:00
|
|
|
// This must happen before the constructor message is sent.
|
2017-07-05 01:47:00 +03:00
|
|
|
SetupNeckoTarget();
|
2017-03-24 01:31:00 +03:00
|
|
|
|
2013-06-22 20:09:19 +04:00
|
|
|
gNeckoChild->SendPFTPChannelConstructor(
|
2019-04-10 01:39:01 +03:00
|
|
|
this, browserChild, IPC::SerializedLoadContext(this), openArgs);
|
2010-08-10 22:47:00 +04:00
|
|
|
|
|
|
|
// The socket transport layer in the chrome process now has a logical ref to
|
|
|
|
// us until OnStopRequest is called.
|
|
|
|
AddIPDLReference();
|
|
|
|
|
2011-10-17 18:59:28 +04:00
|
|
|
mIsPending = true;
|
|
|
|
mWasOpened = true;
|
2010-08-10 22:47:00 +04:00
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2019-11-15 05:42:20 +03:00
|
|
|
FTPChannelChild::IsPending(bool* aResult) {
|
|
|
|
*aResult = mIsPending;
|
2010-08-10 22:47:00 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2019-11-15 05:42:20 +03:00
|
|
|
nsresult FTPChannelChild::OpenContentStream(bool aAsync,
|
|
|
|
nsIInputStream** aStream,
|
|
|
|
nsIChannel** aChannel) {
|
2016-12-03 00:46:53 +03:00
|
|
|
MOZ_CRASH("FTPChannel*Child* should never have OpenContentStream called!");
|
2010-08-10 22:47:00 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2017-07-06 15:00:35 +03:00
|
|
|
|
2010-08-10 22:47:00 +04:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// FTPChannelChild::PFTPChannelChild
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
2014-04-07 22:26:22 +04:00
|
|
|
mozilla::ipc::IPCResult FTPChannelChild::RecvOnStartRequest(
|
|
|
|
const nsresult& aChannelStatus, const int64_t& aContentLength,
|
2010-08-10 22:47:00 +04:00
|
|
|
const nsCString& aContentType, const PRTime& aLastModified,
|
2020-03-25 23:46:35 +03:00
|
|
|
const nsCString& aEntityID, const URIParams& aURI) {
|
2014-03-11 02:04:28 +04:00
|
|
|
// 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!");
|
|
|
|
|
2015-01-08 08:27:00 +03:00
|
|
|
LOG(("FTPChannelChild::RecvOnStartRequest [this=%p]\n", this));
|
|
|
|
|
2019-11-15 05:42:20 +03:00
|
|
|
mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(
|
|
|
|
this, [self = UnsafePtr<FTPChannelChild>(this), aChannelStatus,
|
|
|
|
aContentLength, aContentType, aLastModified, aEntityID, aURI]() {
|
|
|
|
self->DoOnStartRequest(aChannelStatus, aContentLength, aContentType,
|
|
|
|
aLastModified, aEntityID, aURI);
|
|
|
|
}));
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2010-08-10 22:47:00 +04:00
|
|
|
}
|
|
|
|
|
2014-04-07 22:26:22 +04:00
|
|
|
void FTPChannelChild::DoOnStartRequest(const nsresult& aChannelStatus,
|
|
|
|
const int64_t& aContentLength,
|
2010-08-10 22:47:00 +04:00
|
|
|
const nsCString& aContentType,
|
|
|
|
const PRTime& aLastModified,
|
|
|
|
const nsCString& aEntityID,
|
2020-03-25 23:46:35 +03:00
|
|
|
const URIParams& aURI) {
|
2018-06-04 21:05:56 +03:00
|
|
|
mDuringOnStart = true;
|
|
|
|
RefPtr<FTPChannelChild> self = this;
|
|
|
|
auto clearDuringFlag =
|
|
|
|
mozilla::MakeScopeExit([self] { self->mDuringOnStart = false; });
|
|
|
|
|
2015-01-08 08:27:00 +03:00
|
|
|
LOG(("FTPChannelChild::DoOnStartRequest [this=%p]\n", this));
|
2010-08-10 22:47:00 +04:00
|
|
|
|
2014-03-11 02:04:28 +04:00
|
|
|
// 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!");
|
|
|
|
|
2014-04-07 22:26:22 +04:00
|
|
|
if (!mCanceled && NS_SUCCEEDED(mStatus)) {
|
|
|
|
mStatus = aChannelStatus;
|
|
|
|
}
|
|
|
|
|
2012-10-22 21:51:07 +04:00
|
|
|
mContentLength = aContentLength;
|
2010-08-10 22:47:00 +04:00
|
|
|
SetContentType(aContentType);
|
|
|
|
mLastModifiedTime = aLastModified;
|
|
|
|
mEntityID = aEntityID;
|
|
|
|
|
|
|
|
nsCString spec;
|
2020-03-25 23:46:35 +03:00
|
|
|
nsCOMPtr<nsIURI> uri = DeserializeURI(aURI);
|
|
|
|
nsresult rv = uri->GetSpec(spec);
|
2016-08-26 09:40:57 +03:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
2018-01-08 17:20:35 +03:00
|
|
|
// Changes nsBaseChannel::URI()
|
|
|
|
rv = NS_MutateURI(mURI).SetSpec(spec).Finalize(mURI);
|
2016-08-26 09:40:57 +03:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
Cancel(rv);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
Cancel(rv);
|
|
|
|
}
|
2010-08-10 22:47:00 +04:00
|
|
|
|
2011-06-12 05:37:09 +04:00
|
|
|
AutoEventEnqueuer ensureSerialDispatch(mEventQ);
|
2019-02-28 02:41:04 +03:00
|
|
|
rv = mListener->OnStartRequest(this);
|
2010-08-10 22:47:00 +04:00
|
|
|
if (NS_FAILED(rv)) Cancel(rv);
|
2014-03-11 02:04:28 +04:00
|
|
|
|
|
|
|
if (mDivertingToParent) {
|
|
|
|
mListener = nullptr;
|
|
|
|
if (mLoadGroup) {
|
|
|
|
mLoadGroup->RemoveRequest(this, nullptr, mStatus);
|
|
|
|
}
|
|
|
|
}
|
2010-08-10 22:47:00 +04:00
|
|
|
}
|
|
|
|
|
2014-04-07 22:26:22 +04:00
|
|
|
mozilla::ipc::IPCResult FTPChannelChild::RecvOnDataAvailable(
|
2019-11-15 05:42:20 +03:00
|
|
|
const nsresult& aChannelStatus, const nsCString& aData,
|
|
|
|
const uint64_t& aOffset, const uint32_t& aCount) {
|
2014-03-11 02:04:28 +04:00
|
|
|
MOZ_RELEASE_ASSERT(!mFlushedForDiversion,
|
|
|
|
"Should not be receiving any more callbacks from parent!");
|
|
|
|
|
2015-01-08 08:27:00 +03:00
|
|
|
LOG(("FTPChannelChild::RecvOnDataAvailable [this=%p]\n", this));
|
|
|
|
|
2019-11-15 05:42:20 +03:00
|
|
|
mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(
|
|
|
|
this,
|
|
|
|
[self = UnsafePtr<FTPChannelChild>(this),
|
|
|
|
aChannelStatus, aData, aOffset, aCount]() {
|
|
|
|
self->DoOnDataAvailable(aChannelStatus, aData,
|
|
|
|
aOffset, aCount);
|
|
|
|
}),
|
|
|
|
mDivertingToParent);
|
2014-03-11 02:04:28 +04:00
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2010-08-10 22:47:00 +04:00
|
|
|
}
|
|
|
|
|
2019-11-15 05:42:20 +03:00
|
|
|
void FTPChannelChild::DoOnDataAvailable(const nsresult& aChannelStatus,
|
|
|
|
const nsCString& aData,
|
|
|
|
const uint64_t& aOffset,
|
|
|
|
const uint32_t& aCount) {
|
2015-01-08 08:27:00 +03:00
|
|
|
LOG(("FTPChannelChild::DoOnDataAvailable [this=%p]\n", this));
|
2010-08-10 22:47:00 +04:00
|
|
|
|
2014-04-07 22:26:22 +04:00
|
|
|
if (!mCanceled && NS_SUCCEEDED(mStatus)) {
|
2019-11-15 05:42:20 +03:00
|
|
|
mStatus = aChannelStatus;
|
2014-04-07 22:26:22 +04:00
|
|
|
}
|
|
|
|
|
2014-03-11 02:04:28 +04:00
|
|
|
if (mDivertingToParent) {
|
|
|
|
MOZ_RELEASE_ASSERT(
|
|
|
|
!mFlushedForDiversion,
|
|
|
|
"Should not be processing any more callbacks from parent!");
|
|
|
|
|
2019-11-15 05:42:20 +03:00
|
|
|
SendDivertOnDataAvailable(aData, aOffset, aCount);
|
2014-03-11 02:04:28 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-11-15 05:42:20 +03:00
|
|
|
if (mCanceled) {
|
|
|
|
return;
|
|
|
|
}
|
2010-08-10 22:47:00 +04:00
|
|
|
|
2015-10-11 19:13:09 +03:00
|
|
|
if (mUnknownDecoderInvolved) {
|
|
|
|
mUnknownDecoderEventQ.AppendElement(
|
2019-11-15 05:42:20 +03:00
|
|
|
MakeUnique<NeckoTargetChannelFunctionEvent>(
|
|
|
|
this, [self = UnsafePtr<FTPChannelChild>(this), aData, aOffset,
|
|
|
|
aCount]() {
|
|
|
|
if (self->mDivertingToParent) {
|
|
|
|
self->SendDivertOnDataAvailable(aData, aOffset, aCount);
|
|
|
|
}
|
|
|
|
}));
|
2015-10-11 19:13:09 +03:00
|
|
|
}
|
|
|
|
|
2010-08-10 22:47:00 +04:00
|
|
|
// 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
|
|
|
|
// support only reading part of the data, allowing later calls to read the
|
|
|
|
// rest.
|
|
|
|
nsCOMPtr<nsIInputStream> stringStream;
|
2019-02-25 22:11:20 +03:00
|
|
|
nsresult rv =
|
|
|
|
NS_NewByteInputStream(getter_AddRefs(stringStream),
|
2019-11-15 05:42:20 +03:00
|
|
|
MakeSpan(aData).To(aCount), NS_ASSIGNMENT_DEPEND);
|
2010-08-10 22:47:00 +04:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
Cancel(rv);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2011-06-12 05:37:09 +04:00
|
|
|
AutoEventEnqueuer ensureSerialDispatch(mEventQ);
|
2019-11-15 05:42:20 +03:00
|
|
|
rv = mListener->OnDataAvailable(this, stringStream, aOffset, aCount);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
Cancel(rv);
|
|
|
|
}
|
2010-08-10 22:47:00 +04:00
|
|
|
stringStream->Close();
|
|
|
|
}
|
|
|
|
|
2016-05-02 16:38:00 +03:00
|
|
|
mozilla::ipc::IPCResult FTPChannelChild::RecvOnStopRequest(
|
|
|
|
const nsresult& aChannelStatus, const nsCString& aErrorMsg,
|
|
|
|
const bool& aUseUTF8) {
|
2014-03-11 02:04:28 +04:00
|
|
|
MOZ_RELEASE_ASSERT(!mFlushedForDiversion,
|
|
|
|
"Should not be receiving any more callbacks from parent!");
|
|
|
|
|
2016-12-16 06:16:31 +03:00
|
|
|
LOG(("FTPChannelChild::RecvOnStopRequest [this=%p status=%" PRIx32 "]\n",
|
|
|
|
this, static_cast<uint32_t>(aChannelStatus)));
|
2015-01-08 08:27:00 +03:00
|
|
|
|
2019-11-15 05:42:20 +03:00
|
|
|
mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(
|
|
|
|
this, [self = UnsafePtr<FTPChannelChild>(this), aChannelStatus, aErrorMsg,
|
|
|
|
aUseUTF8]() {
|
|
|
|
self->DoOnStopRequest(aChannelStatus, aErrorMsg, aUseUTF8);
|
|
|
|
}));
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2010-08-10 22:47:00 +04:00
|
|
|
}
|
|
|
|
|
2016-05-02 16:38:00 +03:00
|
|
|
void FTPChannelChild::DoOnStopRequest(const nsresult& aChannelStatus,
|
|
|
|
const nsCString& aErrorMsg,
|
|
|
|
bool aUseUTF8) {
|
2016-12-16 06:16:31 +03:00
|
|
|
LOG(("FTPChannelChild::DoOnStopRequest [this=%p status=%" PRIx32 "]\n", this,
|
|
|
|
static_cast<uint32_t>(aChannelStatus)));
|
2010-08-10 22:47:00 +04:00
|
|
|
|
2014-03-11 02:04:28 +04:00
|
|
|
if (mDivertingToParent) {
|
|
|
|
MOZ_RELEASE_ASSERT(
|
|
|
|
!mFlushedForDiversion,
|
|
|
|
"Should not be processing any more callbacks from parent!");
|
|
|
|
|
2014-04-07 22:26:22 +04:00
|
|
|
SendDivertOnStopRequest(aChannelStatus);
|
2014-03-11 02:04:28 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-04-07 22:26:22 +04:00
|
|
|
if (!mCanceled) mStatus = aChannelStatus;
|
2010-08-10 22:47:00 +04:00
|
|
|
|
2015-10-11 19:13:09 +03:00
|
|
|
if (mUnknownDecoderInvolved) {
|
|
|
|
mUnknownDecoderEventQ.AppendElement(
|
2019-11-15 05:42:20 +03:00
|
|
|
MakeUnique<NeckoTargetChannelFunctionEvent>(
|
|
|
|
this, [self = UnsafePtr<FTPChannelChild>(this), aChannelStatus]() {
|
|
|
|
if (self->mDivertingToParent) {
|
|
|
|
self->SendDivertOnStopRequest(aChannelStatus);
|
|
|
|
}
|
|
|
|
}));
|
2015-10-11 19:13:09 +03:00
|
|
|
}
|
|
|
|
|
2010-08-10 22:47:00 +04:00
|
|
|
{ // Ensure that all queued ipdl events are dispatched before
|
|
|
|
// we initiate protocol deletion below.
|
2011-10-17 18:59:28 +04:00
|
|
|
mIsPending = false;
|
2011-06-12 05:37:09 +04:00
|
|
|
AutoEventEnqueuer ensureSerialDispatch(mEventQ);
|
2019-02-28 02:41:31 +03:00
|
|
|
(void)mListener->OnStopRequest(this, aChannelStatus);
|
2016-05-02 16:38:00 +03:00
|
|
|
|
2012-07-30 18:20:58 +04:00
|
|
|
mListener = nullptr;
|
2010-08-10 22:47:00 +04:00
|
|
|
|
2019-11-15 05:42:20 +03:00
|
|
|
if (mLoadGroup) {
|
|
|
|
mLoadGroup->RemoveRequest(this, nullptr, aChannelStatus);
|
|
|
|
}
|
2010-08-10 22:47:00 +04:00
|
|
|
}
|
|
|
|
|
2013-07-08 19:48:39 +04:00
|
|
|
// This calls NeckoChild::DeallocPFTPChannelChild(), which deletes |this| if
|
2010-08-10 22:47:00 +04:00
|
|
|
// IPDL holds the last reference. Don't rely on |this| existing after here!
|
|
|
|
Send__delete__(this);
|
|
|
|
}
|
|
|
|
|
2012-01-11 11:19:17 +04:00
|
|
|
mozilla::ipc::IPCResult FTPChannelChild::RecvFailedAsyncOpen(
|
2019-11-15 05:42:20 +03:00
|
|
|
const nsresult& aStatusCode) {
|
2016-12-16 06:16:31 +03:00
|
|
|
LOG(("FTPChannelChild::RecvFailedAsyncOpen [this=%p status=%" PRIx32 "]\n",
|
2019-11-15 05:42:20 +03:00
|
|
|
this, static_cast<uint32_t>(aStatusCode)));
|
|
|
|
mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(
|
|
|
|
this, [self = UnsafePtr<FTPChannelChild>(this), aStatusCode]() {
|
|
|
|
self->DoFailedAsyncOpen(aStatusCode);
|
|
|
|
}));
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2010-08-10 22:47:00 +04:00
|
|
|
}
|
|
|
|
|
2019-11-15 05:42:20 +03:00
|
|
|
void FTPChannelChild::DoFailedAsyncOpen(const nsresult& aStatusCode) {
|
2016-12-16 06:16:31 +03:00
|
|
|
LOG(("FTPChannelChild::DoFailedAsyncOpen [this=%p status=%" PRIx32 "]\n",
|
2019-11-15 05:42:20 +03:00
|
|
|
this, static_cast<uint32_t>(aStatusCode)));
|
|
|
|
mStatus = aStatusCode;
|
2012-01-11 11:19:17 +04:00
|
|
|
|
2019-11-15 05:42:20 +03:00
|
|
|
if (mLoadGroup) {
|
|
|
|
mLoadGroup->RemoveRequest(this, nullptr, aStatusCode);
|
|
|
|
}
|
2010-08-10 22:47:00 +04:00
|
|
|
|
|
|
|
if (mListener) {
|
2019-02-28 02:41:04 +03:00
|
|
|
mListener->OnStartRequest(this);
|
2012-01-11 11:19:17 +04:00
|
|
|
mIsPending = false;
|
2019-11-15 05:42:20 +03:00
|
|
|
mListener->OnStopRequest(this, aStatusCode);
|
2012-01-11 11:19:17 +04:00
|
|
|
} else {
|
|
|
|
mIsPending = false;
|
2010-08-10 22:47:00 +04:00
|
|
|
}
|
|
|
|
|
2012-07-30 18:20:58 +04:00
|
|
|
mListener = nullptr;
|
2010-08-10 22:47:00 +04:00
|
|
|
|
2019-11-15 05:42:20 +03:00
|
|
|
if (mIPCOpen) {
|
|
|
|
Send__delete__(this);
|
2019-11-13 10:24:22 +03:00
|
|
|
}
|
2019-11-15 05:42:20 +03:00
|
|
|
}
|
2019-11-13 10:24:22 +03:00
|
|
|
|
2014-03-11 02:04:28 +04:00
|
|
|
mozilla::ipc::IPCResult FTPChannelChild::RecvFlushedForDiversion() {
|
2015-01-08 08:27:00 +03:00
|
|
|
LOG(("FTPChannelChild::RecvFlushedForDiversion [this=%p]\n", this));
|
2014-03-11 02:04:28 +04:00
|
|
|
MOZ_ASSERT(mDivertingToParent);
|
|
|
|
|
2019-11-15 05:42:20 +03:00
|
|
|
mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(
|
|
|
|
this, [self = UnsafePtr<FTPChannelChild>(this)]() {
|
|
|
|
self->FlushedForDiversion();
|
|
|
|
}));
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2014-03-11 02:04:28 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void FTPChannelChild::FlushedForDiversion() {
|
2015-01-08 08:27:00 +03:00
|
|
|
LOG(("FTPChannelChild::FlushedForDiversion [this=%p]\n", this));
|
2014-03-11 02:04:28 +04:00
|
|
|
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() {
|
2015-01-08 08:27:00 +03:00
|
|
|
LOG(("FTPChannelChild::RecvDivertMessages [this=%p]\n", this));
|
2014-03-11 02:04:28 +04:00
|
|
|
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()))) {
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_FAIL_NO_REASON(this);
|
2014-03-11 02:04:28 +04:00
|
|
|
}
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2014-03-11 02:04:28 +04:00
|
|
|
}
|
|
|
|
|
2010-11-24 01:56:06 +03:00
|
|
|
mozilla::ipc::IPCResult FTPChannelChild::RecvDeleteSelf() {
|
2019-11-15 05:42:20 +03:00
|
|
|
mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(
|
|
|
|
this,
|
|
|
|
[self = UnsafePtr<FTPChannelChild>(this)]() { self->DoDeleteSelf(); }));
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2010-11-24 01:56:06 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void FTPChannelChild::DoDeleteSelf() {
|
2019-11-15 05:42:20 +03:00
|
|
|
if (mIPCOpen) {
|
|
|
|
Send__delete__(this);
|
|
|
|
}
|
2010-11-24 01:56:06 +03:00
|
|
|
}
|
|
|
|
|
2010-08-10 22:47:00 +04:00
|
|
|
NS_IMETHODIMP
|
2019-11-15 05:42:20 +03:00
|
|
|
FTPChannelChild::Cancel(nsresult aStatus) {
|
2015-01-08 08:27:00 +03:00
|
|
|
LOG(("FTPChannelChild::Cancel [this=%p]\n", this));
|
2019-11-15 05:42:20 +03:00
|
|
|
if (mCanceled) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2010-08-10 22:47:00 +04:00
|
|
|
|
|
|
|
mCanceled = true;
|
2019-11-15 05:42:20 +03:00
|
|
|
mStatus = aStatus;
|
|
|
|
if (mIPCOpen) {
|
|
|
|
SendCancel(aStatus);
|
|
|
|
}
|
2010-08-10 22:47:00 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
FTPChannelChild::Suspend() {
|
|
|
|
NS_ENSURE_TRUE(mIPCOpen, NS_ERROR_NOT_AVAILABLE);
|
2014-03-11 02:04:28 +04:00
|
|
|
|
2015-01-08 08:27:00 +03:00
|
|
|
LOG(("FTPChannelChild::Suspend [this=%p]\n", this));
|
|
|
|
|
2014-03-11 02:04:28 +04:00
|
|
|
// 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) {
|
2011-06-12 05:37:09 +04:00
|
|
|
SendSuspend();
|
2014-03-11 02:04:28 +04:00
|
|
|
mSuspendSent = true;
|
2012-01-11 11:19:17 +04:00
|
|
|
}
|
2013-06-05 03:10:55 +04:00
|
|
|
mEventQ->Suspend();
|
2012-01-11 11:19:17 +04:00
|
|
|
|
2013-06-05 03:10:55 +04:00
|
|
|
return NS_OK;
|
2012-01-11 11:19:17 +04:00
|
|
|
}
|
|
|
|
|
2010-08-10 22:47:00 +04:00
|
|
|
NS_IMETHODIMP
|
|
|
|
FTPChannelChild::Resume() {
|
|
|
|
NS_ENSURE_TRUE(mIPCOpen, NS_ERROR_NOT_AVAILABLE);
|
2011-06-12 05:37:09 +04:00
|
|
|
|
2015-01-08 08:27:00 +03:00
|
|
|
LOG(("FTPChannelChild::Resume [this=%p]\n", this));
|
|
|
|
|
2014-03-11 02:04:28 +04:00
|
|
|
// 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)) {
|
2011-06-12 05:37:09 +04:00
|
|
|
SendResume();
|
2010-08-10 22:47:00 +04:00
|
|
|
}
|
2013-06-05 03:10:55 +04:00
|
|
|
mEventQ->Resume();
|
|
|
|
|
2010-08-10 22:47:00 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2010-11-24 01:56:06 +03:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// FTPChannelChild::nsIChildChannel
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2019-11-15 05:42:20 +03:00
|
|
|
FTPChannelChild::ConnectParent(uint32_t aId) {
|
2017-05-26 04:09:00 +03:00
|
|
|
NS_ENSURE_TRUE((gNeckoChild), NS_ERROR_FAILURE);
|
|
|
|
NS_ENSURE_TRUE(
|
|
|
|
!static_cast<ContentChild*>(gNeckoChild->Manager())->IsShuttingDown(),
|
|
|
|
NS_ERROR_FAILURE);
|
|
|
|
|
2015-01-08 08:27:00 +03:00
|
|
|
LOG(("FTPChannelChild::ConnectParent [this=%p]\n", this));
|
|
|
|
|
2019-04-10 01:39:01 +03:00
|
|
|
mozilla::dom::BrowserChild* browserChild = nullptr;
|
|
|
|
nsCOMPtr<nsIBrowserChild> iBrowserChild;
|
2019-04-10 02:15:02 +03:00
|
|
|
NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup,
|
|
|
|
NS_GET_IID(nsIBrowserChild),
|
2019-04-10 01:39:01 +03:00
|
|
|
getter_AddRefs(iBrowserChild));
|
|
|
|
GetCallback(iBrowserChild);
|
|
|
|
if (iBrowserChild) {
|
|
|
|
browserChild =
|
|
|
|
static_cast<mozilla::dom::BrowserChild*>(iBrowserChild.get());
|
2012-12-29 13:02:16 +04:00
|
|
|
}
|
|
|
|
|
2017-03-24 01:31:00 +03:00
|
|
|
// This must happen before the constructor message is sent.
|
2017-07-05 01:47:00 +03:00
|
|
|
SetupNeckoTarget();
|
2017-03-24 01:31:00 +03:00
|
|
|
|
2010-11-24 01:56:06 +03:00
|
|
|
// The socket transport in the chrome process now holds a logical ref to us
|
|
|
|
// until OnStopRequest, or we do a redirect, or we hit an IPDL error.
|
|
|
|
AddIPDLReference();
|
|
|
|
|
2019-11-15 05:42:20 +03:00
|
|
|
FTPChannelConnectArgs connectArgs(aId);
|
2010-11-24 01:56:06 +03:00
|
|
|
|
2013-06-22 20:09:19 +04:00
|
|
|
if (!gNeckoChild->SendPFTPChannelConstructor(
|
2019-04-10 01:39:01 +03:00
|
|
|
this, browserChild, IPC::SerializedLoadContext(this), connectArgs)) {
|
2010-11-24 01:56:06 +03:00
|
|
|
return NS_ERROR_FAILURE;
|
2013-06-22 20:09:19 +04:00
|
|
|
}
|
2010-11-24 01:56:06 +03:00
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2020-03-26 14:07:10 +03:00
|
|
|
FTPChannelChild::CompleteRedirectSetup(nsIStreamListener* aListener) {
|
2013-06-05 03:32:31 +04:00
|
|
|
LOG(("FTPChannelChild::CompleteRedirectSetup [this=%p]\n", this));
|
2010-11-24 01:56:06 +03:00
|
|
|
|
|
|
|
NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS);
|
|
|
|
NS_ENSURE_TRUE(!mWasOpened, NS_ERROR_ALREADY_OPENED);
|
|
|
|
|
2011-10-17 18:59:28 +04:00
|
|
|
mIsPending = true;
|
|
|
|
mWasOpened = true;
|
2019-11-15 05:42:20 +03:00
|
|
|
mListener = aListener;
|
2010-11-24 01:56:06 +03:00
|
|
|
|
|
|
|
// add ourselves to the load group.
|
2019-11-15 05:42:20 +03:00
|
|
|
if (mLoadGroup) {
|
|
|
|
mLoadGroup->AddRequest(this, nullptr);
|
|
|
|
}
|
2010-11-24 01:56:06 +03:00
|
|
|
|
|
|
|
// We already have an open IPDL connection to the parent. If on-modify-request
|
|
|
|
// listeners or load group observers canceled us, let the parent handle it
|
|
|
|
// and send it back to us naturally.
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2014-03-11 02:04:28 +04:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// FTPChannelChild::nsIDivertableChannel
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
NS_IMETHODIMP
|
|
|
|
FTPChannelChild::DivertToParent(ChannelDiverterChild** aChild) {
|
|
|
|
MOZ_RELEASE_ASSERT(aChild);
|
|
|
|
MOZ_RELEASE_ASSERT(gNeckoChild);
|
|
|
|
MOZ_RELEASE_ASSERT(!mDivertingToParent);
|
2017-05-26 04:09:00 +03:00
|
|
|
NS_ENSURE_TRUE(
|
|
|
|
!static_cast<ContentChild*>(gNeckoChild->Manager())->IsShuttingDown(),
|
|
|
|
NS_ERROR_FAILURE);
|
2014-03-11 02:04:28 +04:00
|
|
|
|
2015-01-08 08:27:00 +03:00
|
|
|
LOG(("FTPChannelChild::DivertToParent [this=%p]\n", this));
|
|
|
|
|
2018-06-04 21:05:56 +03:00
|
|
|
// This method should only be called during OnStartRequest.
|
|
|
|
if (!mDuringOnStart) {
|
|
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
}
|
|
|
|
|
2014-03-11 02:04:28 +04:00
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
|
2019-09-24 20:26:57 +03:00
|
|
|
// Once this is set, it should not be unset before the child is taken down.
|
|
|
|
mDivertingToParent = true;
|
|
|
|
|
2014-03-11 02:04:28 +04:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2015-10-11 19:13:09 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
FTPChannelChild::UnknownDecoderInvolvedKeepData() {
|
|
|
|
mUnknownDecoderInvolved = true;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
FTPChannelChild::UnknownDecoderInvolvedOnStartRequestCalled() {
|
|
|
|
mUnknownDecoderInvolved = false;
|
|
|
|
|
|
|
|
if (mDivertingToParent) {
|
2019-11-15 08:35:28 +03:00
|
|
|
mEventQ->PrependEvents(mUnknownDecoderEventQ);
|
2015-10-11 19:13:09 +03:00
|
|
|
}
|
|
|
|
mUnknownDecoderEventQ.Clear();
|
|
|
|
|
2019-11-15 08:35:28 +03:00
|
|
|
return NS_OK;
|
2015-10-11 19:13:09 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
FTPChannelChild::GetDivertingToParent(bool* aDiverting) {
|
|
|
|
NS_ENSURE_ARG_POINTER(aDiverting);
|
|
|
|
*aDiverting = mDivertingToParent;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2017-07-05 01:47:00 +03:00
|
|
|
void FTPChannelChild::SetupNeckoTarget() {
|
2017-04-04 02:28:41 +03:00
|
|
|
if (mNeckoTarget) {
|
2017-03-24 01:31:00 +03:00
|
|
|
return;
|
|
|
|
}
|
2019-04-25 15:16:35 +03:00
|
|
|
nsCOMPtr<nsILoadInfo> loadInfo = LoadInfo();
|
2017-04-04 02:28:41 +03:00
|
|
|
mNeckoTarget =
|
|
|
|
nsContentUtils::GetEventTargetByLoadInfo(loadInfo, TaskCategory::Network);
|
|
|
|
if (!mNeckoTarget) {
|
2017-03-24 01:31:00 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-04-04 02:28:41 +03:00
|
|
|
gNeckoChild->SetEventTargetForActor(this, mNeckoTarget);
|
2017-03-18 06:36:08 +03:00
|
|
|
}
|
|
|
|
|
2010-08-10 22:47:00 +04:00
|
|
|
} // namespace net
|
|
|
|
} // namespace mozilla
|