--- a/netwerk/protocol/http/HttpBackgroundChannelChild.cpp
+++ b/netwerk/protocol/http/HttpBackgroundChannelChild.cpp
@@ -155,66 +155,155 @@ HttpBackgroundChannelChild::RecvOnStartR
const nsCString& aSecurityInfoSerialization,
const NetAddr& aSelfAddr,
const NetAddr& aPeerAddr,
const int16_t& aRedirectCount,
const uint32_t& aCacheKey,
const nsCString& aAltDataType,
const int64_t& aAltDataLen)
{
+ LOG(("HttpBackgroundChannelChild::RecvOnStartRequest [this=%p]\n", this));
+ MOZ_ASSERT(NS_IsMainThread());
+
+ if (NS_WARN_IF(!mChannelChild)) {
+ return IPC_OK();
+ }
+
+ mChannelChild->ProcessOnStartRequest(aChannelStatus,
+ aResponseHead,
+ aUseResponseHead,
+ aRequestHeaders,
+ aIsFromCache,
+ aCacheEntryAvailable,
+ aCacheExpirationTime,
+ aCachedCharset,
+ aSecurityInfoSerialization,
+ aSelfAddr,
+ aPeerAddr,
+ aRedirectCount,
+ aCacheKey,
+ aAltDataType,
+ aAltDataLen);
return IPC_OK();
}
IPCResult
HttpBackgroundChannelChild::RecvOnTransportAndData(
const nsresult& aChannelStatus,
const nsresult& aTransportStatus,
const uint64_t& aOffset,
const uint32_t& aCount,
const nsCString& aData)
{
+ LOG(("HttpBackgroundChannelChild::RecvOnTransportAndData [this=%p]\n", this));
+ MOZ_ASSERT(NS_IsMainThread());
+
+ if (NS_WARN_IF(!mChannelChild)) {
+ return IPC_OK();
+ }
+
+ mChannelChild->ProcessOnTransportAndData(aChannelStatus,
+ aTransportStatus,
+ aOffset,
+ aCount,
+ aData);
+
return IPC_OK();
}
IPCResult
HttpBackgroundChannelChild::RecvOnStopRequest(
const nsresult& aChannelStatus,
const ResourceTimingStruct& aTiming)
{
+ LOG(("HttpBackgroundChannelChild::RecvOnStopRequest [this=%p]\n", this));
+ MOZ_ASSERT(NS_IsMainThread());
+
+ if (NS_WARN_IF(!mChannelChild)) {
+ return IPC_OK();
+ }
+
+ mChannelChild->ProcessOnStopRequest(aChannelStatus, aTiming);
+
return IPC_OK();
}
IPCResult
HttpBackgroundChannelChild::RecvOnProgress(const int64_t& aProgress,
const int64_t& aProgressMax)
{
+ LOG(("HttpBackgroundChannelChild::RecvOnProgress [this=%p]\n", this));
+ MOZ_ASSERT(NS_IsMainThread());
+
+ if (NS_WARN_IF(!mChannelChild)) {
+ return IPC_OK();
+ }
+
+ mChannelChild->ProcessOnProgress(aProgress, aProgressMax);
+
return IPC_OK();
}
IPCResult
HttpBackgroundChannelChild::RecvOnStatus(const nsresult& aStatus)
{
+ LOG(("HttpBackgroundChannelChild::RecvOnStatus [this=%p]\n", this));
+ MOZ_ASSERT(NS_IsMainThread());
+
+ if (NS_WARN_IF(!mChannelChild)) {
+ return IPC_OK();
+ }
+
+ mChannelChild->ProcessOnStatus(aStatus);
+
return IPC_OK();
}
IPCResult
HttpBackgroundChannelChild::RecvRedirect3Complete()
{
+ LOG(("HttpBackgroundChannelChild::RecvRedirect3Complete [this=%p]\n", this));
+ MOZ_ASSERT(NS_IsMainThread());
+
+ if (NS_WARN_IF(!mChannelChild)) {
+ return IPC_OK();
+ }
+
+ mChannelChild->ProcessRedirect3Complete();
+
return IPC_OK();
}
IPCResult
HttpBackgroundChannelChild::RecvFlushedForDiversion()
{
+ LOG(("HttpBackgroundChannelChild::RecvFlushedForDiversion [this=%p]\n", this));
+ MOZ_ASSERT(NS_IsMainThread());
+
+ if (NS_WARN_IF(!mChannelChild)) {
+ return IPC_OK();
+ }
+
+ mChannelChild->ProcessFlushedForDiversion();
+
return IPC_OK();
}
IPCResult
HttpBackgroundChannelChild::RecvDivertMessages()
{
+ LOG(("HttpBackgroundChannelChild::RecvDivertMessages [this=%p]\n", this));
+ MOZ_ASSERT(NS_IsMainThread());
+
+ if (NS_WARN_IF(!mChannelChild)) {
+ return IPC_OK();
+ }
+
+ mChannelChild->ProcessDivertMessages();
+
return IPC_OK();
}
void
HttpBackgroundChannelChild::ActorDestroy(ActorDestroyReason aWhy)
{
LOG(("HttpBackgroundChannelChild::ActorDestroy[this=%p]\n", this));
MOZ_ASSERT(NS_IsMainThread());
--- a/netwerk/protocol/http/HttpBackgroundChannelParent.cpp
+++ b/netwerk/protocol/http/HttpBackgroundChannelParent.cpp
@@ -7,27 +7,32 @@
// HttpLog.h should generally be included first
#include "HttpLog.h"
#include "HttpBackgroundChannelParent.h"
#include "HttpChannelParent.h"
#include "mozilla/ipc/BackgroundParent.h"
+#include "mozilla/IntegerPrintfMacros.h"
#include "mozilla/Unused.h"
+#include "nsHttpChannel.h"
+#include "nsHttpRequestHead.h"
+#include "nsHttpResponseHead.h"
#include "nsIBackgroundChannelRegistrar.h"
#include "nsNetCID.h"
#include "nsQueryObject.h"
#include "nsThreadUtils.h"
using mozilla::dom::ContentParent;
using mozilla::ipc::AssertIsInMainProcess;
using mozilla::ipc::AssertIsOnBackgroundThread;
using mozilla::ipc::BackgroundParent;
using mozilla::ipc::IPCResult;
+using mozilla::ipc::IsOnBackgroundThread;
namespace mozilla {
namespace net {
/*
* Helper class for continuing the AsyncOpen procedure on main thread.
*/
class ContinueAsyncOpenRunnable final : public Runnable
@@ -129,16 +134,266 @@ HttpBackgroundChannelParent::OnChannelCl
}
Unused << self->Send__delete__(self);
}), NS_DISPATCH_NORMAL);
Unused << NS_WARN_IF(NS_FAILED(rv));
}
+bool
+HttpBackgroundChannelParent::OnStartRequest(
+ nsHttpChannel* aChannel,
+ const nsresult& aChannelStatus,
+ //const nsHttpResponseHead& aResponseHead,
+ //const bool& aUseResponseHead,
+ //const nsHttpHeaderArray& aRequestHeaders,
+ const bool& aIsFromCache,
+ const bool& aCacheEntryAvailable,
+ const uint32_t& aCacheExpirationTime,
+ const nsCString& aCachedCharset,
+ const nsCString& aSecurityInfoSerialization,
+ //const NetAddr& aSelfAddr,
+ //const NetAddr& aPeerAddr,
+ const int16_t& aRedirectCount,
+ const uint32_t& aCacheKey,
+ const nsCString& aAltDataType,
+ const int64_t& aAltDataLength)
+{
+ LOG(("HttpBackgroundChannelParent::OnStartRequest [this=%p]\n", this));
+ AssertIsInMainProcess();
+ MOZ_ASSERT(aChannel);
+
+ if (NS_WARN_IF(!mIPCOpened)) {
+ return false;
+ }
+
+ if (!IsOnBackgroundThread()) {
+ nsresult rv;
+
+ RefPtr<HttpBackgroundChannelParent> self = this;
+ RefPtr<nsHttpChannel> channel = aChannel;
+ rv = mBackgroundThread->Dispatch(
+ NewRunnableMethod<RefPtr<nsHttpChannel>,
+ const nsresult,
+ const bool,
+ const bool,
+ const uint32_t,
+ const nsCString,
+ const nsCString,
+ const int16_t,
+ const uint32_t,
+ const nsCString,
+ const int64_t>
+ (this, &HttpBackgroundChannelParent::OnStartRequest,
+ channel,
+ aChannelStatus,
+ aIsFromCache, aCacheEntryAvailable, aCacheExpirationTime,
+ aCachedCharset, aSecurityInfoSerialization,
+ aRedirectCount, aCacheKey, aAltDataType, aAltDataLength),
+ NS_DISPATCH_NORMAL);
+
+ return !NS_WARN_IF(NS_FAILED(rv));
+ }
+
+ nsHttpResponseHead* responseHead = aChannel->GetResponseHead();
+ nsHttpRequestHead* requestHead = aChannel->GetRequestHead();
+ // !!! We need to lock headers and please don't forget to unlock them !!!
+ requestHead->Enter();
+ bool retVal = SendOnStartRequest(aChannelStatus,
+ responseHead ? *responseHead : nsHttpResponseHead(),
+ !!responseHead,
+ requestHead->Headers(),
+ aIsFromCache, aCacheEntryAvailable,
+ aCacheExpirationTime, aCachedCharset,
+ aSecurityInfoSerialization,
+ aChannel->GetSelfAddr(), aChannel->GetPeerAddr(),
+ aRedirectCount, aCacheKey,
+ aAltDataType, aAltDataLength);
+ requestHead->Exit();
+ return retVal;
+}
+
+bool
+HttpBackgroundChannelParent::OnTransportAndData(
+ const nsresult& aChannelStatus,
+ const nsresult& aTransportStatus,
+ const uint64_t& aOffset,
+ const uint32_t& aCount,
+ const nsCString& aData)
+{
+ LOG(("HttpBackgroundChannelParent::OnTransportAndData [this=%p]\n", this));
+ AssertIsInMainProcess();
+
+ if (NS_WARN_IF(!mIPCOpened)) {
+ return false;
+ }
+
+ if (!IsOnBackgroundThread()) {
+ nsresult rv;
+
+ RefPtr<HttpBackgroundChannelParent> self = this;
+ rv = mBackgroundThread->Dispatch(
+ NewRunnableMethod<const nsresult,
+ const nsresult,
+ const uint64_t,
+ const uint32_t,
+ const nsCString>
+ (this, &HttpBackgroundChannelParent::OnTransportAndData,
+ aChannelStatus, aTransportStatus, aOffset, aCount, aData),
+ NS_DISPATCH_NORMAL);
+
+ return !NS_WARN_IF(NS_FAILED(rv));
+ }
+
+ return SendOnTransportAndData(aChannelStatus, aTransportStatus,
+ aOffset, aCount, aData);
+}
+
+bool
+HttpBackgroundChannelParent::OnStopRequest(const nsresult& aChannelStatus,
+ const ResourceTimingStruct& aTiming)
+{
+ LOG(("HttpBackgroundChannelParent::OnStopRequest [this=%p "
+ "status=%" PRIx32 "]\n", this, static_cast<uint32_t>(aChannelStatus)));
+ AssertIsInMainProcess();
+
+ if (NS_WARN_IF(!mIPCOpened)) {
+ return false;
+ }
+
+ if (!IsOnBackgroundThread()) {
+ nsresult rv;
+
+ RefPtr<HttpBackgroundChannelParent> self = this;
+ rv = mBackgroundThread->Dispatch(
+ NewRunnableMethod<const nsresult, const ResourceTimingStruct>
+ (this, &HttpBackgroundChannelParent::OnStopRequest,
+ aChannelStatus, aTiming),
+ NS_DISPATCH_NORMAL);
+
+ return !NS_WARN_IF(NS_FAILED(rv));
+ }
+
+ return SendOnStopRequest(aChannelStatus, aTiming);
+}
+
+bool
+HttpBackgroundChannelParent::OnProgress(const int64_t& aProgress,
+ const int64_t& aProgressMax)
+{
+ LOG(("HttpBackgroundChannelParent::OnProgress [this=%p]\n", this));
+ AssertIsInMainProcess();
+
+ if (NS_WARN_IF(!mIPCOpened)) {
+ return false;
+ }
+
+ if (!IsOnBackgroundThread()) {
+ nsresult rv;
+
+ RefPtr<HttpBackgroundChannelParent> self = this;
+ rv = mBackgroundThread->Dispatch(
+ NewRunnableMethod<const int64_t, const int64_t>
+ (this, &HttpBackgroundChannelParent::OnProgress,
+ aProgress, aProgressMax),
+ NS_DISPATCH_NORMAL);
+
+ return !NS_WARN_IF(NS_FAILED(rv));
+ }
+
+ return SendOnProgress(aProgress, aProgressMax);
+}
+
+bool
+HttpBackgroundChannelParent::OnStatus(const nsresult& aStatus)
+{
+ LOG(("HttpBackgroundChannelParent::OnStatus [this=%p "
+ "status=%" PRIx32 "]\n", this, static_cast<uint32_t>(aStatus)));
+ AssertIsInMainProcess();
+
+ if (NS_WARN_IF(!mIPCOpened)) {
+ return false;
+ }
+
+ if (!IsOnBackgroundThread()) {
+ nsresult rv;
+
+ RefPtr<HttpBackgroundChannelParent> self = this;
+ rv = mBackgroundThread->Dispatch(
+ NewRunnableMethod<const nsresult>
+ (this, &HttpBackgroundChannelParent::OnStatus,
+ aStatus),
+ NS_DISPATCH_NORMAL);
+
+ return !NS_WARN_IF(NS_FAILED(rv));
+ }
+
+ return SendOnStatus(aStatus);
+}
+
+bool
+HttpBackgroundChannelParent::OnRedirect3Complete()
+{
+ LOG(("HttpBackgroundChannelParent::OnRedirect3Complete [this=%p]\n", this));
+ AssertIsInMainProcess();
+
+ if (NS_WARN_IF(!mIPCOpened)) {
+ return false;
+ }
+
+ if (!IsOnBackgroundThread()) {
+ nsresult rv;
+
+ RefPtr<HttpBackgroundChannelParent> self = this;
+ rv = mBackgroundThread->Dispatch(
+ NewRunnableMethod
+ (this, &HttpBackgroundChannelParent::OnRedirect3Complete),
+ NS_DISPATCH_NORMAL);
+
+ return !NS_WARN_IF(NS_FAILED(rv));
+ }
+
+ return SendRedirect3Complete();
+}
+
+bool
+HttpBackgroundChannelParent::OnDiversion()
+{
+ LOG(("HttpBackgroundChannelParent::OnDiversion [this=%p]\n", this));
+ AssertIsInMainProcess();
+
+ if (NS_WARN_IF(!mIPCOpened)) {
+ return false;
+ }
+
+ if (!IsOnBackgroundThread()) {
+ nsresult rv;
+
+ RefPtr<HttpBackgroundChannelParent> self = this;
+ rv = mBackgroundThread->Dispatch(
+ NewRunnableMethod(this, &HttpBackgroundChannelParent::OnDiversion),
+ NS_DISPATCH_NORMAL);
+
+ return !NS_WARN_IF(NS_FAILED(rv));
+ }
+
+ if (!SendFlushedForDiversion()) {
+ return false;
+ }
+
+ // The listener chain should now be setup; tell HttpChannelChild to divert
+ // the OnDataAvailables and OnStopRequest to this HttpChannelParent.
+ if (!SendDivertMessages()) {
+ return false;
+ }
+
+ return true;
+}
+
void
HttpBackgroundChannelParent::ActorDestroy(ActorDestroyReason aWhy)
{
LOG(("HttpBackgroundChannelParent::ActorDestroy [this=%p]\n", this));
AssertIsInMainProcess();
AssertIsOnBackgroundThread();
mIPCOpened = false;
--- a/netwerk/protocol/http/HttpBackgroundChannelParent.h
+++ b/netwerk/protocol/http/HttpBackgroundChannelParent.h
@@ -14,30 +14,68 @@
#include "nsISupportsImpl.h"
class nsIThread;
namespace mozilla {
namespace net {
class HttpChannelParent;
+class nsHttpChannel;
class HttpBackgroundChannelParent final : public PHttpBackgroundChannelParent
{
public:
explicit HttpBackgroundChannelParent();
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(HttpBackgroundChannelParent)
nsresult Init(const uint64_t& aChannelId);
void LinkToChannel(HttpChannelParent* aChannelParent);
void OnChannelClosed();
+ bool
+ OnStartRequest(nsHttpChannel* aChannel,
+ const nsresult& aChannelStatus,
+ const bool& aIsFromCache,
+ const bool& aCacheEntryAvailable,
+ const uint32_t& aCacheExpirationTime,
+ const nsCString& aCachedCharset,
+ const nsCString& aSecurityInfoSerialization,
+ const int16_t& aRedirectCount,
+ const uint32_t& aCacheKey,
+ const nsCString& aAltDataType,
+ const int64_t& aAltDataLength);
+
+ bool
+ OnTransportAndData(const nsresult& aChannelStatus,
+ const nsresult& aTransportStatus,
+ const uint64_t& aOffset,
+ const uint32_t& aCount,
+ const nsCString& aData);
+
+ bool
+ OnStopRequest(const nsresult& aChannelStatus,
+ const ResourceTimingStruct& aTiming);
+
+ bool
+ OnProgress(const int64_t& aProgress,
+ const int64_t& aProgressMax);
+
+ bool
+ OnStatus(const nsresult& aStatus);
+
+ bool
+ OnRedirect3Complete();
+
+ bool
+ OnDiversion();
+
protected:
void
ActorDestroy(ActorDestroyReason aWhy) override;
private:
virtual ~HttpBackgroundChannelParent();
Atomic<bool> mIPCOpened;
--- a/netwerk/protocol/http/HttpChannelChild.cpp
+++ b/netwerk/protocol/http/HttpChannelChild.cpp
@@ -404,53 +404,53 @@ class StartRequestEvent : public Channel
nsCString mSecurityInfoSerialization;
NetAddr mSelfAddr;
NetAddr mPeerAddr;
uint32_t mCacheKey;
nsCString mAltDataType;
int64_t mAltDataLen;
};
-mozilla::ipc::IPCResult
-HttpChannelChild::RecvOnStartRequest(const nsresult& channelStatus,
- const nsHttpResponseHead& responseHead,
- const bool& useResponseHead,
- const nsHttpHeaderArray& requestHeaders,
- const bool& isFromCache,
- const bool& cacheEntryAvailable,
- const uint32_t& cacheExpirationTime,
- const nsCString& cachedCharset,
- const nsCString& securityInfoSerialization,
- const NetAddr& selfAddr,
- const NetAddr& peerAddr,
- const int16_t& redirectCount,
- const uint32_t& cacheKey,
- const nsCString& altDataType,
- const int64_t& altDataLen)
+void
+HttpChannelChild::ProcessOnStartRequest(
+ const nsresult& aChannelStatus,
+ const nsHttpResponseHead& aResponseHead,
+ const bool& aUseResponseHead,
+ const nsHttpHeaderArray& aRequestHeaders,
+ const bool& aIsFromCache,
+ const bool& aCacheEntryAvailable,
+ const uint32_t& aCacheExpirationTime,
+ const nsCString& aCachedCharset,
+ const nsCString& aSecurityInfoSerialization,
+ const NetAddr& aSelfAddr,
+ const NetAddr& aPeerAddr,
+ const int16_t& aRedirectCount,
+ const uint32_t& aCacheKey,
+ const nsCString& aAltDataType,
+ const int64_t& aAltDataLen)
{
- LOG(("HttpChannelChild::RecvOnStartRequest [this=%p]\n", this));
+ LOG(("HttpChannelChild::ProcessOnStartRequest [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!");
-
-
- mRedirectCount = redirectCount;
-
- mEventQ->RunOrEnqueue(new StartRequestEvent(this, channelStatus, responseHead,
- useResponseHead, requestHeaders,
- isFromCache, cacheEntryAvailable,
- cacheExpirationTime,
- cachedCharset,
- securityInfoSerialization,
- selfAddr, peerAddr, cacheKey,
- altDataType, altDataLen));
- return IPC_OK();
+ MOZ_ASSERT(mWasOpened);
+
+ mRedirectCount = aRedirectCount;
+
+ mEventQ->RunOrEnqueue(
+ new StartRequestEvent(this, aChannelStatus, aResponseHead,
+ aUseResponseHead, aRequestHeaders,
+ aIsFromCache, aCacheEntryAvailable,
+ aCacheExpirationTime, aCachedCharset,
+ aSecurityInfoSerialization,
+ aSelfAddr, aPeerAddr, aCacheKey,
+ aAltDataType, aAltDataLen));
}
void
HttpChannelChild::OnStartRequest(const nsresult& channelStatus,
const nsHttpResponseHead& responseHead,
const bool& useResponseHead,
const nsHttpHeaderArray& requestHeaders,
const bool& isFromCache,
@@ -661,32 +661,32 @@ class TransportAndDataEvent : public Cha
HttpChannelChild* mChild;
nsresult mChannelStatus;
nsresult mTransportStatus;
nsCString mData;
uint64_t mOffset;
uint32_t mCount;
};
-mozilla::ipc::IPCResult
-HttpChannelChild::RecvOnTransportAndData(const nsresult& channelStatus,
- const nsresult& transportStatus,
- const uint64_t& offset,
- const uint32_t& count,
- const nsCString& data)
+void
+HttpChannelChild::ProcessOnTransportAndData(const nsresult& aChannelStatus,
+ const nsresult& aTransportStatus,
+ const uint64_t& aOffset,
+ const uint32_t& aCount,
+ const nsCString& aData)
{
- LOG(("HttpChannelChild::RecvOnTransportAndData [this=%p]\n", this));
+ LOG(("HttpChannelChild::ProcessOnTransportAndData [this=%p]\n", this));
MOZ_RELEASE_ASSERT(!mFlushedForDiversion,
"Should not be receiving any more callbacks from parent!");
-
- mEventQ->RunOrEnqueue(new TransportAndDataEvent(this, channelStatus,
- transportStatus, data, offset,
- count),
+ MOZ_ASSERT(mWasOpened);
+
+ mEventQ->RunOrEnqueue(new TransportAndDataEvent(this, aChannelStatus,
+ aTransportStatus, aData,
+ aOffset, aCount),
mDivertingToParent);
- return IPC_OK();
}
class MaybeDivertOnDataHttpEvent : public ChannelEvent
{
public:
MaybeDivertOnDataHttpEvent(HttpChannelChild* child,
const nsCString& data,
const uint64_t& offset,
@@ -902,27 +902,27 @@ class StopRequestEvent : public ChannelE
return target.forget();
}
private:
HttpChannelChild* mChild;
nsresult mChannelStatus;
ResourceTimingStruct mTiming;
};
-mozilla::ipc::IPCResult
-HttpChannelChild::RecvOnStopRequest(const nsresult& channelStatus,
- const ResourceTimingStruct& timing)
+void
+HttpChannelChild::ProcessOnStopRequest(const nsresult& aChannelStatus,
+ const ResourceTimingStruct& aTiming)
{
- LOG(("HttpChannelChild::RecvOnStopRequest [this=%p]\n", this));
+ LOG(("HttpChannelChild::ProcessOnStopRequest [this=%p]\n", this));
MOZ_RELEASE_ASSERT(!mFlushedForDiversion,
"Should not be receiving any more callbacks from parent!");
-
- mEventQ->RunOrEnqueue(new StopRequestEvent(this, channelStatus, timing),
+ MOZ_ASSERT(mWasOpened);
+
+ mEventQ->RunOrEnqueue(new StopRequestEvent(this, aChannelStatus, aTiming),
mDivertingToParent);
- return IPC_OK();
}
class MaybeDivertOnStopHttpEvent : public ChannelEvent
{
public:
MaybeDivertOnStopHttpEvent(HttpChannelChild* child,
const nsresult& channelStatus)
: mChild(child)
@@ -1143,22 +1143,22 @@ class ProgressEvent : public ChannelEven
nsCOMPtr<nsIEventTarget> target = mChild->GetNeckoTarget();
return target.forget();
}
private:
HttpChannelChild* mChild;
int64_t mProgress, mProgressMax;
};
-mozilla::ipc::IPCResult
-HttpChannelChild::RecvOnProgress(const int64_t& progress,
- const int64_t& progressMax)
+void
+HttpChannelChild::ProcessOnProgress(const int64_t& aProgress,
+ const int64_t& aProgressMax)
{
- mEventQ->RunOrEnqueue(new ProgressEvent(this, progress, progressMax));
- return IPC_OK();
+ MOZ_ASSERT(mWasOpened);
+ mEventQ->RunOrEnqueue(new ProgressEvent(this, aProgress, aProgressMax));
}
void
HttpChannelChild::OnProgress(const int64_t& progress,
const int64_t& progressMax)
{
LOG(("HttpChannelChild::OnProgress [this=%p progress=%" PRId64 "/%" PRId64 "]\n",
this, progress, progressMax));
@@ -1198,21 +1198,21 @@ class StatusEvent : public ChannelEvent
nsCOMPtr<nsIEventTarget> target = mChild->GetNeckoTarget();
return target.forget();
}
private:
HttpChannelChild* mChild;
nsresult mStatus;
};
-mozilla::ipc::IPCResult
-HttpChannelChild::RecvOnStatus(const nsresult& status)
+void
+HttpChannelChild::ProcessOnStatus(const nsresult& aStatus)
{
- mEventQ->RunOrEnqueue(new StatusEvent(this, status));
- return IPC_OK();
+ MOZ_ASSERT(mWasOpened);
+ mEventQ->RunOrEnqueue(new StatusEvent(this, aStatus));
}
void
HttpChannelChild::OnStatus(const nsresult& status)
{
LOG(("HttpChannelChild::OnStatus [this=%p status=%" PRIx32 "]\n",
this, static_cast<uint32_t>(status)));
@@ -1295,18 +1295,18 @@ HttpChannelChild::FailedAsyncOpen(const
if (mIPCOpen) {
TrySendDeletingChannel();
}
}
void
HttpChannelChild::CleanupBackgroundChannel()
{
- LOG(("HttpChannelChild::CleanupBackgroundChannel [this=%p]\n", this));
-
+ LOG(("HttpChannelChild::CleanupBackgroundChannel [this=%p bgChild=%p]\n",
+ this, mBgChild.get()));
if (!mBgChild) {
return;
}
RefPtr<HttpBackgroundChannelChild> bgChild = mBgChild.forget();
if (!NS_IsMainThread()) {
SystemGroup::Dispatch(
@@ -1660,22 +1660,21 @@ class Redirect3Event : public ChannelEve
MOZ_ASSERT(mChild);
nsCOMPtr<nsIEventTarget> target = mChild->GetNeckoTarget();
return target.forget();
}
private:
HttpChannelChild* mChild;
};
-mozilla::ipc::IPCResult
-HttpChannelChild::RecvRedirect3Complete()
+void
+HttpChannelChild::ProcessRedirect3Complete()
{
- LOG(("HttpChannelChild::RecvRedirect3Complete [this=%p]\n", this));
+ LOG(("HttpChannelChild::ProcessRedirect3Complete [this=%p]\n", this));
mEventQ->RunOrEnqueue(new Redirect3Event(this));
- return IPC_OK();
}
class HttpFlushedForDiversionEvent : public ChannelEvent
{
public:
explicit HttpFlushedForDiversionEvent(HttpChannelChild* aChild)
: mChild(aChild)
{
@@ -1692,25 +1691,23 @@ class HttpFlushedForDiversionEvent : pub
MOZ_ASSERT(mChild);
nsCOMPtr<nsIEventTarget> target = mChild->GetNeckoTarget();
return target.forget();
}
private:
HttpChannelChild* mChild;
};
-mozilla::ipc::IPCResult
-HttpChannelChild::RecvFlushedForDiversion()
+void
+HttpChannelChild::ProcessFlushedForDiversion()
{
- LOG(("HttpChannelChild::RecvFlushedForDiversion [this=%p]\n", this));
+ LOG(("HttpChannelChild::ProcessFlushedForDiversion [this=%p]\n", this));
MOZ_RELEASE_ASSERT(mDivertingToParent);
mEventQ->RunOrEnqueue(new HttpFlushedForDiversionEvent(this), true);
-
- return IPC_OK();
}
mozilla::ipc::IPCResult
HttpChannelChild::RecvNotifyTrackingProtectionDisabled()
{
nsChannelClassifier::NotifyTrackingProtectionDisabled(this);
return IPC_OK();
}
@@ -1738,29 +1735,27 @@ HttpChannelChild::FlushedForDiversion()
mozilla::ipc::IPCResult
HttpChannelChild::RecvSetClassifierMatchedInfo(const ClassifierInfo& aInfo)
{
SetMatchedInfo(aInfo.list(), aInfo.provider(), aInfo.prefix());
return IPC_OK();
}
-
-mozilla::ipc::IPCResult
-HttpChannelChild::RecvDivertMessages()
+void
+HttpChannelChild::ProcessDivertMessages()
{
- LOG(("HttpChannelChild::RecvDivertMessages [this=%p]\n", this));
+ LOG(("HttpChannelChild::ProcessDivertMessages [this=%p]\n", this));
+ MOZ_ASSERT(NS_IsMainThread());
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.
MOZ_RELEASE_ASSERT(NS_SUCCEEDED(Resume()));
-
- return IPC_OK();
}
// Returns true if has actually completed the redirect and cleaned up the
// channel, or false the interception logic kicked in and we need to asyncly
// call FinishInterceptedRedirect and CleanupRedirectingChannel.
// The argument is an optional OverrideRunnable that we pass to the redirected
// channel.
bool
--- a/netwerk/protocol/http/HttpChannelChild.h
+++ b/netwerk/protocol/http/HttpChannelChild.h
@@ -117,51 +117,25 @@ public:
mozilla::ipc::IPCResult RecvSetClassifierMatchedInfo(const ClassifierInfo& aInfo) override;
// Callback while background channel is ready.
void OnBackgroundChildReady(HttpBackgroundChannelChild* aBgChild);
// Callback while background channel is destroyed.
void OnBackgroundChildDestroyed();
protected:
- mozilla::ipc::IPCResult RecvOnStartRequest(const nsresult& channelStatus,
- const nsHttpResponseHead& responseHead,
- const bool& useResponseHead,
- const nsHttpHeaderArray& requestHeaders,
- const bool& isFromCache,
- const bool& cacheEntryAvailable,
- const uint32_t& cacheExpirationTime,
- const nsCString& cachedCharset,
- const nsCString& securityInfoSerialization,
- const NetAddr& selfAddr,
- const NetAddr& peerAddr,
- const int16_t& redirectCount,
- const uint32_t& cacheKey,
- const nsCString& altDataType,
- const int64_t& altDataLen) override;
- mozilla::ipc::IPCResult RecvOnTransportAndData(const nsresult& channelStatus,
- const nsresult& status,
- const uint64_t& offset,
- const uint32_t& count,
- const nsCString& data) override;
- mozilla::ipc::IPCResult RecvOnStopRequest(const nsresult& statusCode, const ResourceTimingStruct& timing) override;
- mozilla::ipc::IPCResult RecvOnProgress(const int64_t& progress, const int64_t& progressMax) override;
- mozilla::ipc::IPCResult RecvOnStatus(const nsresult& status) override;
mozilla::ipc::IPCResult RecvFailedAsyncOpen(const nsresult& status) override;
mozilla::ipc::IPCResult RecvRedirect1Begin(const uint32_t& registrarId,
const URIParams& newURI,
const uint32_t& redirectFlags,
const nsHttpResponseHead& responseHead,
const nsCString& securityInfoSerialization,
const uint64_t& channelId) override;
- mozilla::ipc::IPCResult RecvRedirect3Complete() override;
mozilla::ipc::IPCResult RecvAssociateApplicationCache(const nsCString& groupID,
const nsCString& clientID) override;
- mozilla::ipc::IPCResult RecvFlushedForDiversion() override;
- mozilla::ipc::IPCResult RecvDivertMessages() override;
mozilla::ipc::IPCResult RecvDeleteSelf() override;
mozilla::ipc::IPCResult RecvFinishInterceptedRedirect() override;
mozilla::ipc::IPCResult RecvReportSecurityMessage(const nsString& messageTag,
const nsString& messageCategory) override;
mozilla::ipc::IPCResult RecvIssueDeprecationWarning(const uint32_t& warning,
const bool& asError) override;
@@ -211,16 +185,42 @@ private:
// Get event target for processing network events.
already_AddRefed<nsIEventTarget> GetNeckoTarget();
// Get event target for ODA.
already_AddRefed<nsIEventTarget> GetODATarget();
MOZ_MUST_USE nsresult ContinueAsyncOpen();
+ void ProcessOnStartRequest(const nsresult& channelStatus,
+ const nsHttpResponseHead& responseHead,
+ const bool& useResponseHead,
+ const nsHttpHeaderArray& requestHeaders,
+ const bool& isFromCache,
+ const bool& cacheEntryAvailable,
+ const uint32_t& cacheExpirationTime,
+ const nsCString& cachedCharset,
+ const nsCString& securityInfoSerialization,
+ const NetAddr& selfAddr,
+ const NetAddr& peerAddr,
+ const int16_t& redirectCount,
+ const uint32_t& cacheKey,
+ const nsCString& altDataType,
+ const int64_t& altDataLen);
+ void ProcessOnTransportAndData(const nsresult& channelStatus,
+ const nsresult& status,
+ const uint64_t& offset,
+ const uint32_t& count,
+ const nsCString& data);
+ void ProcessOnStopRequest(const nsresult& statusCode, const ResourceTimingStruct& timing);
+ void ProcessOnProgress(const int64_t& progress, const int64_t& progressMax);
+ void ProcessOnStatus(const nsresult& status);
+ void ProcessRedirect3Complete();
+ void ProcessFlushedForDiversion();
+ void ProcessDivertMessages();
void DoOnStartRequest(nsIRequest* aRequest, nsISupports* aContext);
void DoOnStatus(nsIRequest* aRequest, nsresult status);
void DoOnProgress(nsIRequest* aRequest, int64_t progress, int64_t progressMax);
void DoOnDataAvailable(nsIRequest* aRequest, nsISupports* aContext, nsIInputStream* aStream,
uint64_t offset, uint32_t count);
void DoPreOnStopRequest(nsresult aStatus);
void DoOnStopRequest(nsIRequest* aRequest, nsresult aChannelStatus, nsISupports* aContext);
--- a/netwerk/protocol/http/HttpChannelParent.cpp
+++ b/netwerk/protocol/http/HttpChannelParent.cpp
@@ -1343,18 +1343,16 @@ HttpChannelParent::OnStartRequest(nsIReq
if (!mIPCClosed) {
PContentParent* pcp = Manager()->Manager();
MOZ_ASSERT(pcp, "We should have a manager if our IPC isn't closed");
DebugOnly<nsresult> rv =
static_cast<ContentParent*>(pcp)->TransmitPermissionsFor(chan);
MOZ_ASSERT(NS_SUCCEEDED(rv));
}
- nsHttpResponseHead *responseHead = chan->GetResponseHead();
- nsHttpRequestHead *requestHead = chan->GetRequestHead();
bool isFromCache = false;
chan->IsFromCache(&isFromCache);
uint32_t expirationTime = nsICacheEntry::NO_EXPIRATION_TIME;
chan->GetCacheTokenExpirationTime(&expirationTime);
nsCString cachedCharset;
chan->GetCacheTokenCachedCharset(cachedCharset);
bool loadedFromApplicationCache;
@@ -1409,37 +1407,32 @@ HttpChannelParent::OnStartRequest(nsIReq
}
nsAutoCString altDataType;
chan->GetAlternativeDataType(altDataType);
int64_t altDataLen = chan->GetAltDataLength();
MOZ_ASSERT(mIPCClosed || mBgParent || !mPromise.IsEmpty());
- // !!! We need to lock headers and please don't forget to unlock them !!!
- requestHead->Enter();
nsresult rv = NS_OK;
- if (mIPCClosed ||
- !SendOnStartRequest(channelStatus,
- responseHead ? *responseHead : nsHttpResponseHead(),
- !!responseHead,
- requestHead->Headers(),
- isFromCache,
- mCacheEntry ? true : false,
- expirationTime, cachedCharset, secInfoSerialization,
- chan->GetSelfAddr(), chan->GetPeerAddr(),
- redirectCount,
- cacheKeyValue,
- altDataType,
- altDataLen))
+ if (mIPCClosed || !mBgParent ||
+ !mBgParent->OnStartRequest(
+ chan,
+ channelStatus,
+ isFromCache,
+ mCacheEntry ? true : false,
+ expirationTime, cachedCharset, secInfoSerialization,
+ redirectCount,
+ cacheKeyValue,
+ altDataType,
+ altDataLen))
{
rv = NS_ERROR_UNEXPECTED;
}
- requestHead->Exit();
return rv;
}
NS_IMETHODIMP
HttpChannelParent::OnStopRequest(nsIRequest *aRequest,
nsISupports *aContext,
nsresult aStatusCode)
{
@@ -1465,18 +1458,20 @@ HttpChannelParent::OnStopRequest(nsIRequ
// to be passed down.
mChannel->GetProtocolVersion(timing.protocolVersion);
mChannel->GetCacheReadStart(&timing.cacheReadStart);
mChannel->GetCacheReadEnd(&timing.cacheReadEnd);
MOZ_ASSERT(mIPCClosed || mBgParent || !mPromise.IsEmpty());
- if (mIPCClosed || !SendOnStopRequest(aStatusCode, timing))
+ if (mIPCClosed ||
+ !mBgParent || !mBgParent->OnStopRequest(aStatusCode, timing)) {
return NS_ERROR_UNEXPECTED;
+ }
return NS_OK;
}
//-----------------------------------------------------------------------------
// HttpChannelParent::nsIStreamListener
//-----------------------------------------------------------------------------
@@ -1512,18 +1507,19 @@ HttpChannelParent::OnDataAvailable(nsIRe
while (aCount) {
nsresult rv = NS_ReadInputStreamToString(aInputStream, data, toRead);
if (NS_FAILED(rv)) {
return rv;
}
MOZ_ASSERT(mIPCClosed || mBgParent || !mPromise.IsEmpty());
- if (mIPCClosed || !SendOnTransportAndData(channelStatus, transportStatus,
- aOffset, toRead, data)) {
+ if (mIPCClosed || !mBgParent ||
+ !mBgParent->OnTransportAndData(channelStatus, transportStatus,
+ aOffset, toRead, data)) {
return NS_ERROR_UNEXPECTED;
}
MOZ_ASSERT(mBgParent);
aOffset += toRead;
aCount -= toRead;
toRead = std::min<uint32_t>(aCount, kCopyChunkSize);
}
@@ -1547,17 +1543,18 @@ HttpChannelParent::OnProgress(nsIRequest
return NS_OK;
}
MOZ_ASSERT(mIPCClosed || mBgParent || !mPromise.IsEmpty());
// Send OnProgress events to the child for data upload progress notifications
// (i.e. status == NS_NET_STATUS_SENDING_TO) or if the channel has
// LOAD_BACKGROUND set.
- if (mIPCClosed || !SendOnProgress(aProgress, aProgressMax)) {
+ if (mIPCClosed ||
+ !mBgParent || !mBgParent->OnProgress(aProgress, aProgressMax)) {
return NS_ERROR_UNEXPECTED;
}
return NS_OK;
}
NS_IMETHODIMP
HttpChannelParent::OnStatus(nsIRequest *aRequest,
@@ -1573,17 +1570,17 @@ HttpChannelParent::OnStatus(nsIRequest *
// since it is generated by ODA as well.
mIgnoreProgress = true;
return NS_OK;
}
MOZ_ASSERT(mIPCClosed || mBgParent || !mPromise.IsEmpty());
// Otherwise, send to child now
- if (mIPCClosed || !SendOnStatus(aStatus)) {
+ if (mIPCClosed || !mBgParent || !mBgParent->OnStatus(aStatus)) {
return NS_ERROR_UNEXPECTED;
}
return NS_OK;
}
//-----------------------------------------------------------------------------
// HttpChannelParent::nsIParentChannel
@@ -1736,22 +1733,28 @@ HttpChannelParent::ContinueVerification(
callback->ReadyToVerify(aResult);
});
return NS_OK;
}
NS_IMETHODIMP
HttpChannelParent::CompleteRedirect(bool succeeded)
{
- LOG(("HttpChannelParent::CompleteRedirect [this=%p succeeded=%d]\n",
- this, succeeded));
+ LOG(("HttpChannelParent::CompleteRedirect [this=%p succeeded=%d closed=%d]\n",
+ this, succeeded, mIPCClosed));
if (succeeded && !mIPCClosed) {
- // TODO: check return value: assume child dead if failed
- Unused << SendRedirect3Complete();
+ // Send Redirect3Complete on background channel to ensure redirect complete
+ // before any OnStarRequest/OnStatus is handled on the new channel.
+ MOZ_ASSERT(mBgParent);
+ if(mBgParent) {
+ LOG((" > send Redirect3Complete [this=%p]\n", this));
+ // TODO: check return value: assume child dead if failed
+ Unused << mBgParent->OnRedirect3Complete();
+ }
}
mRedirectChannel = nullptr;
return NS_OK;
}
//-----------------------------------------------------------------------------
// HttpChannelParent::ADivertableParentChannel
@@ -1943,24 +1946,17 @@ HttpChannelParent::StartDiversion()
// Now mParentListener can be diverted to mDivertListener.
DebugOnly<nsresult> rvdbg = mParentListener->DivertTo(mDivertListener);
MOZ_ASSERT(NS_SUCCEEDED(rvdbg));
mDivertListener = nullptr;
MOZ_ASSERT(mIPCClosed || mBgParent || !mPromise.IsEmpty());
- if (NS_WARN_IF(mIPCClosed || !SendFlushedForDiversion())) {
- FailDiversion(NS_ERROR_UNEXPECTED);
- return;
- }
-
- // The listener chain should now be setup; tell HttpChannelChild to divert
- // the OnDataAvailables and OnStopRequest to this HttpChannelParent.
- if (NS_WARN_IF(mIPCClosed || !SendDivertMessages())) {
+ if (NS_WARN_IF(mIPCClosed || !mBgParent || !mBgParent->OnDiversion())) {
FailDiversion(NS_ERROR_UNEXPECTED);
return;
}
}
class HTTPFailDiversionEvent : public Runnable
{
public:
--- a/netwerk/protocol/http/PHttpChannel.ipdl
+++ b/netwerk/protocol/http/PHttpChannel.ipdl
@@ -90,80 +90,40 @@ parent:
// After receiving this message, the parent calls SendDeleteSelf, and makes
// sure not to send any more messages after that.
async DeletingChannel();
async __delete__();
child:
- async OnStartRequest(nsresult channelStatus,
- nsHttpResponseHead responseHead,
- bool useResponseHead,
- nsHttpHeaderArray requestHeaders,
- bool isFromCache,
- bool cacheEntryAvailable,
- uint32_t cacheExpirationTime,
- nsCString cachedCharset,
- nsCString securityInfoSerialization,
- NetAddr selfAddr,
- NetAddr peerAddr,
- int16_t redirectCount,
- uint32_t cacheKey,
- nsCString altDataType,
- int64_t altDataLength);
-
- // Combines a single OnDataAvailable and its associated OnProgress &
- // OnStatus calls into one IPDL message
- async OnTransportAndData(nsresult channelStatus,
- nsresult transportStatus,
- uint64_t offset,
- uint32_t count,
- nsCString data);
-
- async OnStopRequest(nsresult channelStatus, ResourceTimingStruct timing);
-
- async OnProgress(int64_t progress, int64_t progressMax);
-
- async OnStatus(nsresult status);
-
// Used to cancel child channel if we hit errors during creating and
// AsyncOpen of nsHttpChannel on the parent.
async FailedAsyncOpen(nsresult status);
// Called to initiate content channel redirect, starts talking to sinks
// on the content process and reports result via Redirect2Verify above
async Redirect1Begin(uint32_t registrarId,
URIParams newUri,
uint32_t redirectFlags,
nsHttpResponseHead responseHead,
nsCString securityInfoSerialization,
uint64_t channelId);
- // Called if redirect successful so that child can complete setup.
- async Redirect3Complete();
-
// Associate the child with an application ids
async AssociateApplicationCache(nsCString groupID,
nsCString clientID);
// Tell the child that tracking protection was disabled for this load.
async NotifyTrackingProtectionDisabled();
// Tell the child that the resource being loaded is on the tracking
// protection list.
async NotifyTrackingResource();
- // 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();
-
// Report a security message to the console associated with this
// channel.
async ReportSecurityMessage(nsString messageTag, nsString messageCategory);
// Tell child to delete channel (all IPDL deletes must be done from child to
// avoid races: see bug 591708).
async DeleteSelf();