зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1201174 - For FTP - in case of divertToParent, it myst be possible to delay delivering of OnDataAv./OnStopR. r=jduell
--HG-- extra : rebase_source : 5c59317dd43d5e0448b44ed3d0c26dd6262e80da
This commit is contained in:
Родитель
ab6f975996
Коммит
6243a9efb2
|
@ -55,6 +55,8 @@ FTPChannelParent::FTPChannelParent(const PBrowserOrId& aIframeEmbedding,
|
||||||
}
|
}
|
||||||
|
|
||||||
mObserver = new OfflineObserver(this);
|
mObserver = new OfflineObserver(this);
|
||||||
|
|
||||||
|
mEventQ = new ChannelEventQueue(static_cast<nsIParentChannel*>(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
FTPChannelParent::~FTPChannelParent()
|
FTPChannelParent::~FTPChannelParent()
|
||||||
|
@ -243,6 +245,32 @@ FTPChannelParent::RecvResume()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class FTPDivertDataAvailableEvent : public ChannelEvent
|
||||||
|
{
|
||||||
|
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()
|
||||||
|
{
|
||||||
|
mParent->DivertOnDataAvailable(mData, mOffset, mCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
FTPChannelParent* mParent;
|
||||||
|
nsCString mData;
|
||||||
|
uint64_t mOffset;
|
||||||
|
uint32_t mCount;
|
||||||
|
};
|
||||||
|
|
||||||
bool
|
bool
|
||||||
FTPChannelParent::RecvDivertOnDataAvailable(const nsCString& data,
|
FTPChannelParent::RecvDivertOnDataAvailable(const nsCString& data,
|
||||||
const uint64_t& offset,
|
const uint64_t& offset,
|
||||||
|
@ -260,6 +288,35 @@ FTPChannelParent::RecvDivertOnDataAvailable(const nsCString& data,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mEventQ->ShouldEnqueue()) {
|
||||||
|
mEventQ->Enqueue(new FTPDivertDataAvailableEvent(this, data, offset,
|
||||||
|
count));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
DivertOnDataAvailable(data, offset, count);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
nsCOMPtr<nsIInputStream> stringStream;
|
||||||
nsresult rv = NS_NewByteInputStream(getter_AddRefs(stringStream), data.get(),
|
nsresult rv = NS_NewByteInputStream(getter_AddRefs(stringStream), data.get(),
|
||||||
count, NS_ASSIGNMENT_DEPEND);
|
count, NS_ASSIGNMENT_DEPEND);
|
||||||
|
@ -268,9 +325,11 @@ FTPChannelParent::RecvDivertOnDataAvailable(const nsCString& data,
|
||||||
mChannel->Cancel(rv);
|
mChannel->Cancel(rv);
|
||||||
}
|
}
|
||||||
mStatus = rv;
|
mStatus = rv;
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AutoEventEnqueuer ensureSerialDispatch(mEventQ);
|
||||||
|
|
||||||
rv = OnDataAvailable(mChannel, nullptr, stringStream, offset, count);
|
rv = OnDataAvailable(mChannel, nullptr, stringStream, offset, count);
|
||||||
|
|
||||||
stringStream->Close();
|
stringStream->Close();
|
||||||
|
@ -280,9 +339,27 @@ FTPChannelParent::RecvDivertOnDataAvailable(const nsCString& data,
|
||||||
}
|
}
|
||||||
mStatus = rv;
|
mStatus = rv;
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class FTPDivertStopRequestEvent : public ChannelEvent
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FTPDivertStopRequestEvent(FTPChannelParent* aParent,
|
||||||
|
const nsresult& statusCode)
|
||||||
|
: mParent(aParent)
|
||||||
|
, mStatusCode(statusCode)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Run() {
|
||||||
|
mParent->DivertOnStopRequest(mStatusCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
FTPChannelParent* mParent;
|
||||||
|
nsresult mStatusCode;
|
||||||
|
};
|
||||||
|
|
||||||
bool
|
bool
|
||||||
FTPChannelParent::RecvDivertOnStopRequest(const nsresult& statusCode)
|
FTPChannelParent::RecvDivertOnStopRequest(const nsresult& statusCode)
|
||||||
{
|
{
|
||||||
|
@ -293,6 +370,27 @@ FTPChannelParent::RecvDivertOnStopRequest(const nsresult& statusCode)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mEventQ->ShouldEnqueue()) {
|
||||||
|
mEventQ->Enqueue(new FTPDivertStopRequestEvent(this, statusCode));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
DivertOnStopRequest(statusCode);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
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.
|
// Honor the channel's status even if the underlying transaction completed.
|
||||||
nsresult status = NS_FAILED(mStatus) ? mStatus : statusCode;
|
nsresult status = NS_FAILED(mStatus) ? mStatus : statusCode;
|
||||||
|
|
||||||
|
@ -304,10 +402,26 @@ FTPChannelParent::RecvDivertOnStopRequest(const nsresult& statusCode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AutoEventEnqueuer ensureSerialDispatch(mEventQ);
|
||||||
OnStopRequest(mChannel, nullptr, status);
|
OnStopRequest(mChannel, nullptr, status);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class FTPDivertCompleteEvent : public ChannelEvent
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit FTPDivertCompleteEvent(FTPChannelParent* aParent)
|
||||||
|
: mParent(aParent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Run() {
|
||||||
|
mParent->DivertComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
FTPChannelParent* mParent;
|
||||||
|
};
|
||||||
|
|
||||||
bool
|
bool
|
||||||
FTPChannelParent::RecvDivertComplete()
|
FTPChannelParent::RecvDivertComplete()
|
||||||
{
|
{
|
||||||
|
@ -318,13 +432,31 @@ FTPChannelParent::RecvDivertComplete()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mEventQ->ShouldEnqueue()) {
|
||||||
|
mEventQ->Enqueue(new FTPDivertCompleteEvent(this));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
DivertComplete();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
nsresult rv = ResumeForDiversion();
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
FailDiversion(NS_ERROR_UNEXPECTED);
|
FailDiversion(NS_ERROR_UNEXPECTED);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -588,6 +720,8 @@ FTPChannelParent::StartDiversion()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
AutoEventEnqueuer ensureSerialDispatch(mEventQ);
|
||||||
// Call OnStartRequest for the "DivertTo" listener.
|
// Call OnStartRequest for the "DivertTo" listener.
|
||||||
nsresult rv = OnStartRequest(mChannel, nullptr);
|
nsresult rv = OnStartRequest(mChannel, nullptr);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
|
@ -597,6 +731,7 @@ FTPChannelParent::StartDiversion()
|
||||||
mStatus = rv;
|
mStatus = rv;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// After OnStartRequest has been called, tell FTPChannelChild to divert the
|
// After OnStartRequest has been called, tell FTPChannelChild to divert the
|
||||||
// OnDataAvailables and OnStopRequest to this FTPChannelParent.
|
// OnDataAvailables and OnStopRequest to this FTPChannelParent.
|
||||||
|
|
|
@ -79,6 +79,16 @@ protected:
|
||||||
// ChildChannel. Used during HTTP->FTP redirects.
|
// ChildChannel. Used during HTTP->FTP redirects.
|
||||||
bool ConnectChannel(const uint32_t& channelId);
|
bool ConnectChannel(const uint32_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 bool RecvCancel(const nsresult& status) override;
|
virtual bool RecvCancel(const nsresult& status) override;
|
||||||
virtual bool RecvSuspend() override;
|
virtual bool RecvSuspend() override;
|
||||||
virtual bool RecvResume() override;
|
virtual bool RecvResume() override;
|
||||||
|
@ -119,6 +129,8 @@ protected:
|
||||||
bool mSuspendedForDiversion;
|
bool mSuspendedForDiversion;
|
||||||
nsRefPtr<OfflineObserver> mObserver;
|
nsRefPtr<OfflineObserver> mObserver;
|
||||||
nsRefPtr<mozilla::dom::TabParent> mTabParent;
|
nsRefPtr<mozilla::dom::TabParent> mTabParent;
|
||||||
|
|
||||||
|
nsRefPtr<ChannelEventQueue> mEventQ;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace net
|
} // namespace net
|
||||||
|
|
Загрузка…
Ссылка в новой задаче