Bug 1220681 P4 Automatically suspend the parent channel after synthesizing the response for diverison. r=jdm

This commit is contained in:
Ben Kelly 2015-12-23 12:20:53 -08:00
parent de50895f4d
commit 31d9e6df91
5 changed files with 28 additions and 3 deletions

View File

@ -116,6 +116,7 @@ struct HttpChannelOpenArgs
nsCString schedulingContextID;
OptionalCorsPreflightArgs preflightArgs;
uint32_t initialRwin;
bool suspendAfterSynthesizeResponse;
};
struct HttpChannelConnectArgs

View File

@ -188,6 +188,7 @@ HttpChannelChild::HttpChannelChild()
, mShouldInterceptSubsequentRedirect(false)
, mRedirectingForSubsequentSynthesizedResponse(false)
, mShouldParentIntercept(false)
, mSuspendParentAfterSynthesizeResponse(false)
{
LOG(("Creating HttpChannelChild @%x\n", this));
@ -1889,8 +1890,11 @@ HttpChannelChild::ContinueAsyncOpen()
if (mResponseHead) {
openArgs.synthesizedResponseHead() = *mResponseHead;
openArgs.suspendAfterSynthesizeResponse() =
mSuspendParentAfterSynthesizeResponse;
} else {
openArgs.synthesizedResponseHead() = mozilla::void_t();
openArgs.suspendAfterSynthesizeResponse() = false;
}
nsCOMPtr<nsISerializable> secInfoSer = do_QueryInterface(mSecurityInfo);
@ -2425,6 +2429,7 @@ HttpChannelChild::DivertToParent(ChannelDiverterChild **aChild)
// yet. We need one, though, in order to have a parent side to divert to.
// Therefore, create the actor just in time for us to suspend and divert it.
if (mSynthesizedResponse && !RemoteChannelExists()) {
mSuspendParentAfterSynthesizeResponse = true;
rv = ContinueAsyncOpen();
NS_ENSURE_SUCCESS(rv, rv);
}

View File

@ -231,6 +231,10 @@ private:
// before the network transaction is initiated.
bool mShouldParentIntercept;
// Set if the corresponding parent channel should suspend after a response
// is synthesized.
bool mSuspendParentAfterSynthesizeResponse;
// true after successful AsyncOpen until OnStopRequest completes.
bool RemoteChannelExists() { return mIPCOpen && !mKeptAlive; }

View File

@ -66,6 +66,7 @@ HttpChannelParent::HttpChannelParent(const PBrowserOrId& iframeEmbedding,
, mSuspendedForDiversion(false)
, mShouldIntercept(false)
, mShouldSuspendIntercept(false)
, mSuspendAfterSynthesizeResponse(false)
, mNestedFrameId(0)
{
LOG(("Creating HttpChannelParent [this=%p]\n", this));
@ -132,7 +133,7 @@ HttpChannelParent::Init(const HttpChannelCreationArgs& aArgs)
a.loadInfo(), a.synthesizedResponseHead(),
a.synthesizedSecurityInfoSerialization(),
a.cacheKey(), a.schedulingContextID(), a.preflightArgs(),
a.initialRwin());
a.initialRwin(), a.suspendAfterSynthesizeResponse());
}
case HttpChannelCreationArgs::THttpChannelConnectArgs:
{
@ -276,6 +277,14 @@ HttpChannelParent::SynthesizeResponse(nsIInterceptedChannel* aChannel)
mSynthesizedResponseHead = nullptr;
// Suspend now even though the FinishSynthesizeResponse runnable has
// not executed. We want to suspend after we get far enough to trigger
// the synthesis, but not actually allow the nsHttpChannel to trigger
// any OnStartRequests().
if (mSuspendAfterSynthesizeResponse) {
mChannel->Suspend();
}
MaybeFlushPendingDiversion();
}
@ -376,7 +385,8 @@ HttpChannelParent::DoAsyncOpen( const URIParams& aURI,
const uint32_t& aCacheKey,
const nsCString& aSchedulingContextID,
const OptionalCorsPreflightArgs& aCorsPreflightArgs,
const uint32_t& aInitialRwin)
const uint32_t& aInitialRwin,
const bool& aSuspendAfterSynthesizeResponse)
{
nsCOMPtr<nsIURI> uri = DeserializeURI(aURI);
if (!uri) {
@ -589,6 +599,8 @@ HttpChannelParent::DoAsyncOpen( const URIParams& aURI,
schedulingContextID.Parse(aSchedulingContextID.BeginReading());
mChannel->SetSchedulingContextID(schedulingContextID);
mSuspendAfterSynthesizeResponse = aSuspendAfterSynthesizeResponse;
if (loadInfo && loadInfo->GetEnforceSecurity()) {
rv = mChannel->AsyncOpen2(mParentListener);
}

View File

@ -128,7 +128,8 @@ protected:
const uint32_t& aCacheKey,
const nsCString& aSchedulingContextID,
const OptionalCorsPreflightArgs& aCorsPreflightArgs,
const uint32_t& aInitialRwin);
const uint32_t& aInitialRwin,
const bool& aSuspendAfterSynthesizeResponse);
virtual bool RecvSetPriority(const uint16_t& priority) override;
virtual bool RecvSetClassOfService(const uint32_t& cos) override;
@ -238,6 +239,8 @@ private:
bool mShouldIntercept : 1;
// Set if this channel should suspend on interception.
bool mShouldSuspendIntercept : 1;
// Set if this channel should be suspended after synthesizing a response.
bool mSuspendAfterSynthesizeResponse : 1;
dom::TabId mNestedFrameId;