зеркало из 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);
|
||||
|
||||
mEventQ = new ChannelEventQueue(static_cast<nsIParentChannel*>(this));
|
||||
}
|
||||
|
||||
FTPChannelParent::~FTPChannelParent()
|
||||
|
@ -243,6 +245,32 @@ FTPChannelParent::RecvResume()
|
|||
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
|
||||
FTPChannelParent::RecvDivertOnDataAvailable(const nsCString& data,
|
||||
const uint64_t& offset,
|
||||
|
@ -260,6 +288,35 @@ FTPChannelParent::RecvDivertOnDataAvailable(const nsCString& data,
|
|||
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;
|
||||
nsresult rv = NS_NewByteInputStream(getter_AddRefs(stringStream), data.get(),
|
||||
count, NS_ASSIGNMENT_DEPEND);
|
||||
|
@ -268,9 +325,11 @@ FTPChannelParent::RecvDivertOnDataAvailable(const nsCString& data,
|
|||
mChannel->Cancel(rv);
|
||||
}
|
||||
mStatus = rv;
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
|
||||
AutoEventEnqueuer ensureSerialDispatch(mEventQ);
|
||||
|
||||
rv = OnDataAvailable(mChannel, nullptr, stringStream, offset, count);
|
||||
|
||||
stringStream->Close();
|
||||
|
@ -280,9 +339,27 @@ FTPChannelParent::RecvDivertOnDataAvailable(const nsCString& data,
|
|||
}
|
||||
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
|
||||
FTPChannelParent::RecvDivertOnStopRequest(const nsresult& statusCode)
|
||||
{
|
||||
|
@ -293,6 +370,27 @@ FTPChannelParent::RecvDivertOnStopRequest(const nsresult& statusCode)
|
|||
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.
|
||||
nsresult status = NS_FAILED(mStatus) ? mStatus : statusCode;
|
||||
|
||||
|
@ -304,10 +402,26 @@ FTPChannelParent::RecvDivertOnStopRequest(const nsresult& statusCode)
|
|||
}
|
||||
}
|
||||
|
||||
AutoEventEnqueuer ensureSerialDispatch(mEventQ);
|
||||
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
|
||||
FTPChannelParent::RecvDivertComplete()
|
||||
{
|
||||
|
@ -318,13 +432,31 @@ FTPChannelParent::RecvDivertComplete()
|
|||
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();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
FailDiversion(NS_ERROR_UNEXPECTED);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -588,14 +720,17 @@ FTPChannelParent::StartDiversion()
|
|||
}
|
||||
}
|
||||
|
||||
// Call OnStartRequest for the "DivertTo" listener.
|
||||
nsresult rv = OnStartRequest(mChannel, nullptr);
|
||||
if (NS_FAILED(rv)) {
|
||||
if (mChannel) {
|
||||
mChannel->Cancel(rv);
|
||||
{
|
||||
AutoEventEnqueuer ensureSerialDispatch(mEventQ);
|
||||
// Call OnStartRequest for the "DivertTo" listener.
|
||||
nsresult rv = OnStartRequest(mChannel, nullptr);
|
||||
if (NS_FAILED(rv)) {
|
||||
if (mChannel) {
|
||||
mChannel->Cancel(rv);
|
||||
}
|
||||
mStatus = rv;
|
||||
return;
|
||||
}
|
||||
mStatus = rv;
|
||||
return;
|
||||
}
|
||||
|
||||
// After OnStartRequest has been called, tell FTPChannelChild to divert the
|
||||
|
|
|
@ -79,6 +79,16 @@ protected:
|
|||
// ChildChannel. Used during HTTP->FTP redirects.
|
||||
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 RecvSuspend() override;
|
||||
virtual bool RecvResume() override;
|
||||
|
@ -119,6 +129,8 @@ protected:
|
|||
bool mSuspendedForDiversion;
|
||||
nsRefPtr<OfflineObserver> mObserver;
|
||||
nsRefPtr<mozilla::dom::TabParent> mTabParent;
|
||||
|
||||
nsRefPtr<ChannelEventQueue> mEventQ;
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
|
|
Загрузка…
Ссылка в новой задаче