Bug 1487113 - nsICacheInfoChannel.originalInputStream as attribute, r=valentin

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Andrea Marchesini 2019-05-20 15:18:25 +00:00
parent 48d4ac04df
commit aa9560f5f0
9 changed files with 74 additions and 91 deletions

View File

@ -148,10 +148,9 @@ interface nsICacheInfoChannel : nsISupports
/**
* Sometimes when the channel is delivering alt-data, we may want to somehow
* access the original content too. This method asynchronously opens the
* input stream and delivers it to the receiver.
* access the original content too.
*/
void getOriginalInputStream(in nsIInputStreamReceiver aReceiver);
readonly attribute nsIInputStream originalInputStream;
/**
* Opens and returns an output stream that a consumer may use to save an

View File

@ -395,20 +395,24 @@ void HttpChannelChild::AssociateApplicationCache(const nsCString& groupID,
class StartRequestEvent : public NeckoTargetChannelEvent<HttpChannelChild> {
public:
StartRequestEvent(
HttpChannelChild* aChild, const nsresult& aChannelStatus,
const nsHttpResponseHead& aResponseHead, const bool& aUseResponseHead,
const nsHttpHeaderArray& aRequestHeaders,
const ParentLoadInfoForwarderArgs& loadInfoForwarder,
const bool& aIsFromCache, const bool& aIsRacing,
const bool& aCacheEntryAvailable, const uint64_t& aCacheEntryId,
const int32_t& aCacheFetchCount, const uint32_t& aCacheExpirationTime,
const nsCString& aCachedCharset,
const nsCString& aSecurityInfoSerialization, const NetAddr& aSelfAddr,
const NetAddr& aPeerAddr, const uint32_t& aCacheKey,
const nsCString& altDataType, const int64_t& altDataLen,
const bool& deliveringAltData, const bool& aApplyConversion,
const bool& aIsResolvedByTRR, const ResourceTimingStruct& aTiming)
StartRequestEvent(HttpChannelChild* aChild, const nsresult& aChannelStatus,
const nsHttpResponseHead& aResponseHead,
const bool& aUseResponseHead,
const nsHttpHeaderArray& aRequestHeaders,
const ParentLoadInfoForwarderArgs& loadInfoForwarder,
const bool& aIsFromCache, const bool& aIsRacing,
const bool& aCacheEntryAvailable,
const uint64_t& aCacheEntryId,
const int32_t& aCacheFetchCount,
const uint32_t& aCacheExpirationTime,
const nsCString& aCachedCharset,
const nsCString& aSecurityInfoSerialization,
const NetAddr& aSelfAddr, const NetAddr& aPeerAddr,
const uint32_t& aCacheKey, const nsCString& altDataType,
const int64_t& altDataLen, const bool& deliveringAltData,
already_AddRefed<nsIInputStream> originalCacheInputStream,
const bool& aApplyConversion, const bool& aIsResolvedByTRR,
const ResourceTimingStruct& aTiming)
: NeckoTargetChannelEvent<HttpChannelChild>(aChild),
mChannelStatus(aChannelStatus),
mResponseHead(aResponseHead),
@ -429,6 +433,7 @@ class StartRequestEvent : public NeckoTargetChannelEvent<HttpChannelChild> {
mAltDataType(altDataType),
mAltDataLen(altDataLen),
mDeliveringAltData(deliveringAltData),
mOriginalCacheInputStream(originalCacheInputStream),
mLoadInfoForwarder(loadInfoForwarder),
mIsResolvedByTRR(aIsResolvedByTRR),
mTiming(aTiming) {}
@ -440,8 +445,9 @@ class StartRequestEvent : public NeckoTargetChannelEvent<HttpChannelChild> {
mLoadInfoForwarder, mIsFromCache, mIsRacing, mCacheEntryAvailable,
mCacheEntryId, mCacheFetchCount, mCacheExpirationTime, mCachedCharset,
mSecurityInfoSerialization, mSelfAddr, mPeerAddr, mCacheKey,
mAltDataType, mAltDataLen, mDeliveringAltData, mApplyConversion,
mIsResolvedByTRR, mTiming);
mAltDataType, mAltDataLen, mDeliveringAltData,
mOriginalCacheInputStream.forget(), mApplyConversion, mIsResolvedByTRR,
mTiming);
}
private:
@ -464,6 +470,7 @@ class StartRequestEvent : public NeckoTargetChannelEvent<HttpChannelChild> {
nsCString mAltDataType;
int64_t mAltDataLen;
bool mDeliveringAltData;
nsCOMPtr<nsIInputStream> mOriginalCacheInputStream;
ParentLoadInfoForwarderArgs mLoadInfoForwarder;
bool mIsResolvedByTRR;
ResourceTimingStruct mTiming;
@ -480,8 +487,10 @@ mozilla::ipc::IPCResult HttpChannelChild::RecvOnStartRequest(
const NetAddr& selfAddr, const NetAddr& peerAddr,
const int16_t& redirectCount, const uint32_t& cacheKey,
const nsCString& altDataType, const int64_t& altDataLen,
const bool& deliveringAltData, const bool& aApplyConversion,
const bool& aIsResolvedByTRR, const ResourceTimingStruct& aTiming) {
const bool& deliveringAltData,
const Maybe<IPCStream>& aOriginalCacheInputStream,
const bool& aApplyConversion, const bool& aIsResolvedByTRR,
const ResourceTimingStruct& aTiming) {
AUTO_PROFILER_LABEL("HttpChannelChild::RecvOnStartRequest", NETWORK);
LOG(("HttpChannelChild::RecvOnStartRequest [this=%p]\n", this));
// mFlushedForDiversion and mDivertingToParent should NEVER be set at this
@ -495,13 +504,16 @@ mozilla::ipc::IPCResult HttpChannelChild::RecvOnStartRequest(
mRedirectCount = redirectCount;
nsCOMPtr<nsIInputStream> originalCacheInputStream =
DeserializeIPCStream(aOriginalCacheInputStream);
mEventQ->RunOrEnqueue(new StartRequestEvent(
this, channelStatus, responseHead, useResponseHead, requestHeaders,
loadInfoForwarder, isFromCache, isRacing, cacheEntryAvailable,
cacheEntryId, cacheFetchCount, cacheExpirationTime, cachedCharset,
securityInfoSerialization, selfAddr, peerAddr, cacheKey, altDataType,
altDataLen, deliveringAltData, aApplyConversion, aIsResolvedByTRR,
aTiming));
altDataLen, deliveringAltData, originalCacheInputStream.forget(),
aApplyConversion, aIsResolvedByTRR, aTiming));
{
// Child's mEventQ is to control the execution order of the IPC messages
@ -534,8 +546,10 @@ void HttpChannelChild::OnStartRequest(
const nsCString& cachedCharset, const nsCString& securityInfoSerialization,
const NetAddr& selfAddr, const NetAddr& peerAddr, const uint32_t& cacheKey,
const nsCString& altDataType, const int64_t& altDataLen,
const bool& deliveringAltData, const bool& aApplyConversion,
const bool& aIsResolvedByTRR, const ResourceTimingStruct& aTiming) {
const bool& deliveringAltData,
already_AddRefed<nsIInputStream> originalCacheInputStream,
const bool& aApplyConversion, const bool& aIsResolvedByTRR,
const ResourceTimingStruct& aTiming) {
LOG(("HttpChannelChild::OnStartRequest [this=%p]\n", this));
// mFlushedForDiversion and mDivertingToParent should NEVER be set at this
@ -547,6 +561,8 @@ void HttpChannelChild::OnStartRequest(
!mDivertingToParent,
"mDivertingToParent should be unset before OnStartRequest!");
mOriginalCacheInputStream = originalCacheInputStream;
// If this channel was aborted by ActorDestroy, then there may be other
// OnStartRequest/OnStopRequest/OnDataAvailable IPC messages that need to
// be handled. In that case we just ignore them to avoid calling the listener
@ -3236,17 +3252,15 @@ HttpChannelChild::OpenAlternativeOutputStream(const nsACString& aType,
}
NS_IMETHODIMP
HttpChannelChild::GetOriginalInputStream(nsIInputStreamReceiver* aReceiver) {
if (aReceiver == nullptr) {
return NS_ERROR_INVALID_ARG;
}
HttpChannelChild::GetOriginalInputStream(nsIInputStream** aInputStream) {
NS_ENSURE_ARG_POINTER(aInputStream);
if (!mIPCOpen) {
return NS_ERROR_NOT_AVAILABLE;
}
mOriginalInputStreamReceiver = aReceiver;
Unused << SendOpenOriginalCacheInputStream();
nsCOMPtr<nsIInputStream> is = mOriginalCacheInputStream;
is.forget(aInputStream);
return NS_OK;
}
@ -3268,18 +3282,6 @@ HttpChannelChild::GetAltDataInputStream(const nsACString& aType,
return NS_OK;
}
mozilla::ipc::IPCResult HttpChannelChild::RecvOriginalCacheInputStreamAvailable(
const Maybe<IPCStream>& aStream) {
nsCOMPtr<nsIInputStream> stream = DeserializeIPCStream(aStream);
nsCOMPtr<nsIInputStreamReceiver> receiver;
receiver.swap(mOriginalInputStreamReceiver);
if (receiver) {
receiver->OnInputStreamReady(stream);
}
return IPC_OK();
}
mozilla::ipc::IPCResult HttpChannelChild::RecvAltDataCacheInputStreamAvailable(
const Maybe<IPCStream>& aStream) {
nsCOMPtr<nsIInputStream> stream = DeserializeIPCStream(aStream);

View File

@ -146,6 +146,7 @@ class HttpChannelChild final : public PHttpChannelChild,
const NetAddr& peerAddr, const int16_t& redirectCount,
const uint32_t& cacheKey, const nsCString& altDataType,
const int64_t& altDataLen, const bool& deliveringAltData,
const Maybe<IPCStream>& originalCacheInputStream,
const bool& aApplyConversion, const bool& aIsResolvedByTRR,
const ResourceTimingStruct& aTiming) override;
mozilla::ipc::IPCResult RecvFailedAsyncOpen(const nsresult& status) override;
@ -177,9 +178,6 @@ class HttpChannelChild final : public PHttpChannelChild,
mozilla::ipc::IPCResult RecvCancelRedirected() override;
mozilla::ipc::IPCResult RecvOriginalCacheInputStreamAvailable(
const Maybe<IPCStream>& aStream) override;
mozilla::ipc::IPCResult RecvAltDataCacheInputStreamAvailable(
const Maybe<IPCStream>& aStream) override;
@ -350,7 +348,7 @@ class HttpChannelChild final : public PHttpChannelChild,
nsCOMPtr<nsICacheInfoChannel> mSynthesizedCacheInfo;
RefPtr<ChannelEventQueue> mEventQ;
nsCOMPtr<nsIInputStreamReceiver> mOriginalInputStreamReceiver;
nsCOMPtr<nsIInputStream> mOriginalCacheInputStream;
nsCOMPtr<nsIInputStreamReceiver> mAltDataInputStreamReceiver;
// Used to ensure atomicity of mBgChild and mBgInitFailCallback
@ -478,8 +476,10 @@ class HttpChannelChild final : public PHttpChannelChild,
const nsCString& securityInfoSerialization, const NetAddr& selfAddr,
const NetAddr& peerAddr, const uint32_t& cacheKey,
const nsCString& altDataType, const int64_t& altDataLen,
const bool& deliveringAltData, const bool& aApplyConversion,
const bool& aIsResolvedByTRR, const ResourceTimingStruct& aTiming);
const bool& deliveringAltData,
already_AddRefed<nsIInputStream> originalCacheInputStream,
const bool& aApplyConversion, const bool& aIsResolvedByTRR,
const ResourceTimingStruct& aTiming);
void MaybeDivertOnData(const nsCString& data, const uint64_t& offset,
const uint32_t& count);
void OnTransportAndData(const nsresult& channelStatus, const nsresult& status,

View File

@ -1467,6 +1467,17 @@ HttpChannelParent::OnStartRequest(nsIRequest* aRequest) {
bool isResolvedByTRR = false;
chan->GetIsResolvedByTRR(&isResolvedByTRR);
AutoIPCStream originalCacheInputStream(true /* delay start */);
if (mCacheEntry) {
nsCOMPtr<nsIInputStream> inputStream;
nsresult rv = mCacheEntry->OpenInputStream(0, getter_AddRefs(inputStream));
if (NS_SUCCEEDED(rv)) {
PContentParent* pcp = Manager()->Manager();
Unused << originalCacheInputStream.Serialize(
inputStream, static_cast<ContentParent*>(pcp));
}
}
rv = NS_OK;
if (mIPCClosed ||
!SendOnStartRequest(
@ -1476,7 +1487,8 @@ HttpChannelParent::OnStartRequest(nsIRequest* aRequest) {
mCacheEntry ? true : false, cacheEntryId, fetchCount, expirationTime,
cachedCharset, secInfoSerialization, chan->GetSelfAddr(),
chan->GetPeerAddr(), redirectCount, cacheKey, altDataType, altDataLen,
deliveringAltData, applyConversion, isResolvedByTRR, timing)) {
deliveringAltData, originalCacheInputStream.TakeOptionalValue(),
applyConversion, isResolvedByTRR, timing)) {
rv = NS_ERROR_UNEXPECTED;
}
requestHead->Exit();
@ -1692,26 +1704,6 @@ mozilla::ipc::IPCResult HttpChannelParent::RecvBytesRead(
return IPC_OK();
}
mozilla::ipc::IPCResult HttpChannelParent::RecvOpenOriginalCacheInputStream() {
if (mIPCClosed) {
return IPC_OK();
}
AutoIPCStream autoStream;
if (mCacheEntry) {
nsCOMPtr<nsIInputStream> inputStream;
nsresult rv = mCacheEntry->OpenInputStream(0, getter_AddRefs(inputStream));
if (NS_SUCCEEDED(rv)) {
PContentParent* pcp = Manager()->Manager();
Unused << autoStream.Serialize(inputStream,
static_cast<ContentParent*>(pcp));
}
}
Unused << SendOriginalCacheInputStreamAvailable(
autoStream.TakeOptionalValue());
return IPC_OK();
}
mozilla::ipc::IPCResult HttpChannelParent::RecvOpenAltDataCacheInputStream(
const nsCString& aType) {
if (mIPCClosed) {

View File

@ -205,7 +205,6 @@ class HttpChannelParent final : public nsIInterfaceRequestor,
const URIParams& uri,
const mozilla::ipc::PrincipalInfo& requestingPrincipal) override;
virtual mozilla::ipc::IPCResult RecvBytesRead(const int32_t& aCount) override;
virtual mozilla::ipc::IPCResult RecvOpenOriginalCacheInputStream() override;
virtual mozilla::ipc::IPCResult RecvOpenAltDataCacheInputStream(
const nsCString& aType) override;
virtual void ActorDestroy(ActorDestroyReason why) override;

View File

@ -1284,10 +1284,9 @@ InterceptedHttpChannel::OpenAlternativeOutputStream(
}
NS_IMETHODIMP
InterceptedHttpChannel::GetOriginalInputStream(
nsIInputStreamReceiver* aReceiver) {
InterceptedHttpChannel::GetOriginalInputStream(nsIInputStream** aStream) {
if (mSynthesizedCacheInfo) {
return mSynthesizedCacheInfo->GetOriginalInputStream(aReceiver);
return mSynthesizedCacheInfo->GetOriginalInputStream(aStream);
}
return NS_ERROR_NOT_AVAILABLE;
}

View File

@ -94,9 +94,6 @@ parent:
// sure not to send any more messages after that.
async DeletingChannel();
// Called to get the input stream when altData was delivered.
async OpenOriginalCacheInputStream();
// Called to get the input stream when altData is available.
async OpenAltDataCacheInputStream(nsCString aType);
@ -127,6 +124,7 @@ child:
nsCString altDataType,
int64_t altDataLength,
bool deliveringAltData,
IPCStream? originalCacheInputStream,
bool applyConversion,
bool isResolvedByTRR,
ResourceTimingStruct timing);
@ -185,8 +183,6 @@ child:
// See ADivertableParentChannel::CancelDiversion
async CancelDiversion();
async OriginalCacheInputStreamAvailable(IPCStream? stream);
async AltDataCacheInputStreamAvailable(IPCStream? stream);
both:

View File

@ -8613,18 +8613,18 @@ nsHttpChannel::OpenAlternativeOutputStream(const nsACString& type,
}
NS_IMETHODIMP
nsHttpChannel::GetOriginalInputStream(nsIInputStreamReceiver* aReceiver) {
if (aReceiver == nullptr) {
return NS_ERROR_INVALID_ARG;
}
nsCOMPtr<nsIInputStream> inputStream;
nsHttpChannel::GetOriginalInputStream(nsIInputStream** aInputStream) {
NS_ENSURE_ARG_POINTER(aInputStream);
*aInputStream = nullptr;
nsCOMPtr<nsICacheEntry> cacheEntry =
mCacheEntry ? mCacheEntry : mAltDataCacheEntry;
if (cacheEntry) {
cacheEntry->OpenInputStream(0, getter_AddRefs(inputStream));
nsresult rv = cacheEntry->OpenInputStream(0, aInputStream);
NS_ENSURE_SUCCESS(rv, rv);
}
aReceiver->OnInputStreamReady(inputStream);
return NS_OK;
}

View File

@ -150,11 +150,7 @@ function readAltContent(request, buffer)
Assert.equal(buffer, altContent);
check_has_alt_data_in_index(true);
cc.getOriginalInputStream({
onInputStreamReady: function(aInputStream) {
executeSoon(() => readOriginalInputStream(aInputStream));
}
});
executeSoon(() => readOriginalInputStream(cc.originalInputStream));
}
function readOriginalInputStream(aInputStream)