Bug 1600211 - Support passsing nsIMultiPartChannel values through PHttpChannel, and conditionally expose this interface on HttpChannelChild. r=mayhemer

Differential Revision: https://phabricator.services.mozilla.com/D55217

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Matt Woodrow 2019-12-04 03:18:13 +00:00
parent ae112914b6
commit 96102b54a4
4 changed files with 113 additions and 9 deletions

View File

@ -288,6 +288,7 @@ NS_INTERFACE_MAP_BEGIN(HttpChannelChild)
NS_INTERFACE_MAP_ENTRY(nsIChildChannel)
NS_INTERFACE_MAP_ENTRY(nsIHttpChannelChild)
NS_INTERFACE_MAP_ENTRY(nsIDivertableChannel)
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIMultiPartChannel, mMultiPartID.isSome())
NS_INTERFACE_MAP_ENTRY(nsIThreadRetargetableRequest)
NS_INTERFACE_MAP_ENTRY_CONCRETE(HttpChannelChild)
NS_INTERFACE_MAP_END_INHERITING(HttpBaseChannel)
@ -378,7 +379,8 @@ mozilla::ipc::IPCResult HttpChannelChild::RecvOnStartRequest(
const int64_t& aAltDataLen, const bool& aDeliveringAltData,
const bool& aApplyConversion, const bool& aIsResolvedByTRR,
const ResourceTimingStructArgs& aTiming,
const bool& aAllRedirectsSameOrigin) {
const bool& aAllRedirectsSameOrigin, const Maybe<uint32_t>& aMultiPartID,
const bool& aIsLastPartOfMultiPart) {
AUTO_PROFILER_LABEL("HttpChannelChild::RecvOnStartRequest", NETWORK);
LOG(("HttpChannelChild::RecvOnStartRequest [this=%p]\n", this));
// mFlushedForDiversion and mDivertingToParent should NEVER be set at this
@ -400,7 +402,7 @@ mozilla::ipc::IPCResult HttpChannelChild::RecvOnStartRequest(
aCacheExpirationTime, aCachedCharset, aSecurityInfoSerialization,
aSelfAddr, aPeerAddr, aCacheKey, aAltDataType, aAltDataLen,
aDeliveringAltData, aApplyConversion, aIsResolvedByTRR, aTiming,
aAllRedirectsSameOrigin]() {
aAllRedirectsSameOrigin, aMultiPartID, aIsLastPartOfMultiPart]() {
self->OnStartRequest(
aChannelStatus, aResponseHead, aUseResponseHead, aRequestHeaders,
aLoadInfoForwarder, aIsFromCache, aIsRacing, aCacheEntryAvailable,
@ -408,7 +410,7 @@ mozilla::ipc::IPCResult HttpChannelChild::RecvOnStartRequest(
aCachedCharset, aSecurityInfoSerialization, aSelfAddr, aPeerAddr,
aCacheKey, aAltDataType, aAltDataLen, aDeliveringAltData,
aApplyConversion, aIsResolvedByTRR, aTiming,
aAllRedirectsSameOrigin);
aAllRedirectsSameOrigin, aMultiPartID, aIsLastPartOfMultiPart);
}));
{
@ -458,7 +460,8 @@ void HttpChannelChild::OnStartRequest(
const nsCString& aAltDataType, const int64_t& aAltDataLen,
const bool& aDeliveringAltData, const bool& aApplyConversion,
const bool& aIsResolvedByTRR, const ResourceTimingStructArgs& aTiming,
const bool& aAllRedirectsSameOrigin) {
const bool& aAllRedirectsSameOrigin, const Maybe<uint32_t>& aMultiPartID,
const bool& aIsLastPartOfMultiPart) {
LOG(("HttpChannelChild::OnStartRequest [this=%p]\n", this));
// mFlushedForDiversion and mDivertingToParent should NEVER be set at this
@ -536,6 +539,9 @@ void HttpChannelChild::OnStartRequest(
mAllRedirectsSameOrigin = aAllRedirectsSameOrigin;
mMultiPartID = aMultiPartID;
mIsLastPartOfMultiPart = aIsLastPartOfMultiPart;
DoOnStartRequest(this, nullptr);
}
@ -1000,6 +1006,16 @@ void HttpChannelChild::OnStopRequest(
return;
}
// If we're a multi-part stream, and this wasn't the last part, then don't
// cleanup yet, as we're expecting more parts.
if (mMultiPartID && !mIsLastPartOfMultiPart) {
LOG(
("HttpChannelChild::OnStopRequest - Expecting future parts on a "
"multipart channel"
"postpone cleaning up."));
return;
}
CleanupBackgroundChannel();
// If there is a possibility we might want to write alt data to the cache
@ -1114,6 +1130,18 @@ void HttpChannelChild::DoOnStopRequest(nsIRequest* aRequest,
}
mOnStopRequestCalled = true;
// If we're a multi-part stream, and this wasn't the last part, then don't
// cleanup yet, as we're expecting more parts.
if (mMultiPartID && !mIsLastPartOfMultiPart) {
LOG(
("HttpChannelChild::DoOnStopRequest - Expecting future parts on a "
"multipart channel"
"not releasing listeners."));
mOnStopRequestCalled = false;
mOnStartRequestCalled = false;
return;
}
// notify "http-on-stop-connect" observers
gHttpHandler->OnStopRequest(this);
@ -3406,6 +3434,40 @@ HttpChannelChild::GetDivertingToParent(bool* aDiverting) {
return NS_OK;
}
//-----------------------------------------------------------------------------
// HttpChannelChild::nsIMuliPartChannel
//-----------------------------------------------------------------------------
NS_IMETHODIMP
HttpChannelChild::GetBaseChannel(nsIChannel** aBaseChannel) {
if (!mMultiPartID) {
MOZ_ASSERT(false, "Not a multipart channel");
return NS_ERROR_NOT_AVAILABLE;
}
nsCOMPtr<nsIChannel> channel = this;
channel.forget(aBaseChannel);
return NS_OK;
}
NS_IMETHODIMP
HttpChannelChild::GetPartID(uint32_t* aPartID) {
if (!mMultiPartID) {
MOZ_ASSERT(false, "Not a multipart channel");
return NS_ERROR_NOT_AVAILABLE;
}
*aPartID = *mMultiPartID;
return NS_OK;
}
NS_IMETHODIMP
HttpChannelChild::GetIsLastPart(bool* aIsLastPart) {
if (!mMultiPartID) {
return NS_ERROR_NOT_AVAILABLE;
}
*aIsLastPart = mIsLastPartOfMultiPart;
return NS_OK;
}
//-----------------------------------------------------------------------------
// HttpChannelChild::nsIThreadRetargetableRequest
//-----------------------------------------------------------------------------

View File

@ -31,6 +31,7 @@
#include "nsIChildChannel.h"
#include "nsIHttpChannelChild.h"
#include "nsIDivertableChannel.h"
#include "nsIMultiPartChannel.h"
#include "nsIThreadRetargetableRequest.h"
#include "mozilla/net/DNS.h"
@ -65,6 +66,7 @@ class HttpChannelChild final : public PHttpChannelChild,
public nsIChildChannel,
public nsIHttpChannelChild,
public nsIDivertableChannel,
public nsIMultiPartChannel,
public nsIThreadRetargetableRequest,
public NeckoTargetHolder {
virtual ~HttpChannelChild();
@ -79,6 +81,7 @@ class HttpChannelChild final : public PHttpChannelChild,
NS_DECL_NSICHILDCHANNEL
NS_DECL_NSIHTTPCHANNELCHILD
NS_DECL_NSIDIVERTABLECHANNEL
NS_DECL_NSIMULTIPARTCHANNEL
NS_DECL_NSITHREADRETARGETABLEREQUEST
NS_DECLARE_STATIC_IID_ACCESSOR(HTTP_CHANNEL_CHILD_IID)
@ -143,7 +146,8 @@ class HttpChannelChild final : public PHttpChannelChild,
const int64_t& altDataLen, const bool& deliveringAltData,
const bool& aApplyConversion, const bool& aIsResolvedByTRR,
const ResourceTimingStructArgs& aTiming,
const bool& aAllRedirectsSameOrigin) override;
const bool& aAllRedirectsSameOrigin, const Maybe<uint32_t>& aMultiPartID,
const bool& aIsLastPartOfMultiPart) override;
mozilla::ipc::IPCResult RecvFailedAsyncOpen(const nsresult& status) override;
mozilla::ipc::IPCResult RecvRedirect1Begin(
const uint32_t& registrarId, const URIParams& newURI,
@ -405,6 +409,10 @@ class HttpChannelChild final : public PHttpChannelChild,
int32_t mCacheFetchCount;
uint32_t mCacheExpirationTime;
// If we're handling a multi-part response, then this is set to the current
// part ID during OnStartRequest.
Maybe<uint32_t> mMultiPartID;
// To ensure only one SendDeletingChannel is triggered.
Atomic<bool> mDeletingChannelSent;
@ -467,6 +475,10 @@ class HttpChannelChild final : public PHttpChannelChild,
// is synthesized.
uint8_t mSuspendParentAfterSynthesizeResponse : 1;
// True if this channel is a multi-part channel, and the last part
// is currently being processed.
uint8_t mIsLastPartOfMultiPart : 1;
void FinishInterceptedRedirect();
void CleanupRedirectingChannel(nsresult rv);
@ -488,7 +500,8 @@ class HttpChannelChild final : public PHttpChannelChild,
const nsCString& altDataType, const int64_t& altDataLen,
const bool& deliveringAltData, const bool& aApplyConversion,
const bool& aIsResolvedByTRR, const ResourceTimingStructArgs& aTiming,
const bool& aAllRedirectsSameOrigin);
const bool& aAllRedirectsSameOrigin, const Maybe<uint32_t>& aMultiPartID,
const bool& aIsLastPartOfMultiPart);
void MaybeDivertOnData(const nsCString& data, const uint64_t& offset,
const uint32_t& count);
void OnTransportAndData(const nsresult& channelStatus, const nsresult& status,

View File

@ -55,6 +55,7 @@
#include "nsThreadUtils.h"
#include "nsQueryObject.h"
#include "nsIURIClassifier.h"
#include "nsIMultiPartChannel.h"
using mozilla::BasePrincipal;
using namespace mozilla::dom;
@ -1322,7 +1323,24 @@ HttpChannelParent::OnStartRequest(nsIRequest* aRequest) {
MOZ_RELEASE_ASSERT(!mDivertingFromChild,
"Cannot call OnStartRequest if diverting is set!");
Maybe<uint32_t> multiPartID;
bool isLastPartOfMultiPart = false;
RefPtr<HttpBaseChannel> chan = do_QueryObject(aRequest);
if (!chan) {
nsCOMPtr<nsIMultiPartChannel> multiPartChannel =
do_QueryInterface(aRequest);
if (multiPartChannel) {
nsCOMPtr<nsIChannel> baseChannel;
multiPartChannel->GetBaseChannel(getter_AddRefs(baseChannel));
chan = do_QueryObject(baseChannel);
uint32_t partID = 0;
multiPartChannel->GetPartID(&partID);
multiPartID = Some(partID);
multiPartChannel->GetIsLastPart(&isLastPartOfMultiPart);
}
}
if (!chan) {
LOG((" aRequest is not HttpBaseChannel"));
NS_ERROR(
@ -1427,9 +1445,17 @@ HttpChannelParent::OnStartRequest(nsIRequest* aRequest) {
nsHttpResponseHead* responseHead = chan->GetResponseHead();
bool useResponseHead = !!responseHead;
nsHttpResponseHead cleanedUpResponseHead;
if (responseHead && responseHead->HasHeader(nsHttp::Set_Cookie)) {
if (responseHead &&
(responseHead->HasHeader(nsHttp::Set_Cookie) || multiPartID)) {
cleanedUpResponseHead = *responseHead;
cleanedUpResponseHead.ClearHeader(nsHttp::Set_Cookie);
if (multiPartID) {
nsCOMPtr<nsIChannel> chan = do_QueryInterface(aRequest);
MOZ_ASSERT(chan);
nsAutoCString contentType;
chan->GetContentType(contentType);
cleanedUpResponseHead.SetContentType(contentType);
}
responseHead = &cleanedUpResponseHead;
}
@ -1465,7 +1491,8 @@ HttpChannelParent::OnStartRequest(nsIRequest* aRequest) {
cachedCharset, secInfoSerialization, chan->GetSelfAddr(),
chan->GetPeerAddr(), redirectCount, cacheKey, altDataType, altDataLen,
deliveringAltData, applyConversion, isResolvedByTRR,
GetTimingAttributes(mChannel), allRedirectsSameOrigin)) {
GetTimingAttributes(mChannel), allRedirectsSameOrigin, multiPartID,
isLastPartOfMultiPart)) {
rv = NS_ERROR_UNEXPECTED;
}
requestHead->Exit();

View File

@ -128,7 +128,9 @@ child:
bool applyConversion,
bool isResolvedByTRR,
ResourceTimingStructArgs timing,
bool allRedirectsSameOrigin);
bool allRedirectsSameOrigin,
uint32_t? multiPartId,
bool isLastPartOfMultiPart);
// Used to cancel child channel if we hit errors during creating and
// AsyncOpen of nsHttpChannel on the parent.