Last active
January 13, 2019 14:53
-
-
Save valenting/026dbfe1e3bbb2509a29155b4c0acb5e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/netwerk/protocol/http/HttpChannelParent.cpp b/netwerk/protocol/http/HttpChannelParent.cpp | |
--- a/netwerk/protocol/http/HttpChannelParent.cpp | |
+++ b/netwerk/protocol/http/HttpChannelParent.cpp | |
@@ -1311,20 +1311,24 @@ static void GetTimingAttributes(HttpBase | |
NS_IMETHODIMP | |
HttpChannelParent::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext) { | |
nsresult rv; | |
LOG(("HttpChannelParent::OnStartRequest [this=%p, aRequest=%p]\n", this, | |
aRequest)); | |
MOZ_ASSERT(NS_IsMainThread()); | |
- | |
MOZ_RELEASE_ASSERT(!mDivertingFromChild, | |
"Cannot call OnStartRequest if diverting is set!"); | |
+ if (mDoingCrossProcessRedirect) { | |
+ LOG(("Child was cancelled for cross-process redirect. Bail.")); | |
+ return NS_OK; | |
+ } | |
+ | |
RefPtr<HttpBaseChannel> chan = do_QueryObject(aRequest); | |
if (!chan) { | |
LOG((" aRequest is not HttpBaseChannel")); | |
NS_ERROR( | |
"Expecting only HttpBaseChannel as aRequest in " | |
"HttpChannelParent::OnStartRequest"); | |
return NS_ERROR_UNEXPECTED; | |
} | |
@@ -1478,16 +1482,21 @@ HttpChannelParent::OnStartRequest(nsIReq | |
NS_IMETHODIMP | |
HttpChannelParent::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext, | |
nsresult aStatusCode) { | |
LOG(("HttpChannelParent::OnStopRequest: [this=%p aRequest=%p status=%" PRIx32 | |
"]\n", | |
this, aRequest, static_cast<uint32_t>(aStatusCode))); | |
MOZ_ASSERT(NS_IsMainThread()); | |
+ if (mDoingCrossProcessRedirect) { | |
+ LOG(("Child was cancelled for cross-process redirect. Bail.")); | |
+ return NS_OK; | |
+ } | |
+ | |
MOZ_RELEASE_ASSERT(!mDivertingFromChild, | |
"Cannot call OnStopRequest if diverting is set!"); | |
ResourceTimingStruct timing; | |
GetTimingAttributes(mChannel, timing); | |
RefPtr<nsHttpChannel> httpChannelImpl = do_QueryObject(mChannel); | |
if (httpChannelImpl) { | |
httpChannelImpl->SetWarningReporter(nullptr); | |
@@ -1589,17 +1598,17 @@ HttpChannelParent::OnDataAvailable(nsIRe | |
if (NS_FAILED(rv)) { | |
return rv; | |
} | |
// Either IPC channel is closed or background channel | |
// is ready to send OnTransportAndData. | |
MOZ_ASSERT(mIPCClosed || mBgParent); | |
- if (mIPCClosed || !mBgParent || | |
+ if (mIPCClosed || !mBgParent || mDoingCrossProcessRedirect || | |
!mBgParent->OnTransportAndData(channelStatus, transportStatus, aOffset, | |
toRead, data)) { | |
return NS_ERROR_UNEXPECTED; | |
} | |
aOffset += toRead; | |
aCount -= toRead; | |
toRead = std::min<uint32_t>(aCount, kCopyChunkSize); | |
@@ -1971,27 +1980,31 @@ HttpChannelParent::StartRedirect(uint32_ | |
// Result is handled in RecvRedirect2Verify above | |
mRedirectChannel = newChannel; | |
mRedirectCallback = callback; | |
return NS_OK; | |
} | |
+void HttpChannelParent::CancelChildCrossProcessRedirect() { | |
+ MOZ_ASSERT(!mDoingCrossProcessRedirect, "Already redirected"); | |
+ mDoingCrossProcessRedirect = true; | |
+ if (!mIPCClosed) { | |
+ Unused << SendCancelRedirected(); | |
+ } | |
+} | |
+ | |
NS_IMETHODIMP | |
HttpChannelParent::CompleteRedirect(bool succeeded) { | |
LOG(("HttpChannelParent::CompleteRedirect [this=%p succeeded=%d]\n", this, | |
succeeded)); | |
- // The channel was redirected to another process, and the channel parent | |
- // is about to be deleted. We send a CancelRedirected message in order to | |
- // inform the listener that this child is going away. | |
- if (mDoingCrossProcessRedirect && !mIPCClosed) { | |
- MOZ_ASSERT(!mRedirectChannel); | |
- Unused << SendCancelRedirected(); | |
+ if (mDoingCrossProcessRedirect) { | |
+ LOG(("Child was cancelled for cross-process redirect. Bail.")); | |
return NS_OK; | |
} | |
// If this was an internal redirect for a service worker interception then | |
// we will not have a redirecting channel here. Hide this redirect from | |
// the child. | |
if (!mRedirectChannel) { | |
return NS_OK; | |
diff --git a/netwerk/protocol/http/HttpChannelParent.h b/netwerk/protocol/http/HttpChannelParent.h | |
--- a/netwerk/protocol/http/HttpChannelParent.h | |
+++ b/netwerk/protocol/http/HttpChannelParent.h | |
@@ -118,17 +118,21 @@ class HttpChannelParent final : public n | |
// Callback while background channel is ready. | |
void OnBackgroundParentReady(HttpBackgroundChannelParent* aBgParent); | |
// Callback while background channel is destroyed. | |
void OnBackgroundParentDestroyed(); | |
base::ProcessId OtherPid() const override; | |
- void SetCrossProcessRedirect() { mDoingCrossProcessRedirect = true; } | |
+ // Calling this method will cancel the HttpChannelChild because the consumer | |
+ // needs to be relocated to another process. | |
+ // Any OnStart/Stop/DataAvailable calls that follow will not be sent to the | |
+ // child channel. | |
+ void CancelChildCrossProcessRedirect(); | |
protected: | |
// used to connect redirected-to channel in parent with just created | |
// ChildChannel. Used during redirects. | |
MOZ_MUST_USE bool ConnectChannel(const uint32_t& channelId, | |
const bool& shouldIntercept); | |
MOZ_MUST_USE bool DoAsyncOpen( | |
@@ -329,16 +333,19 @@ class HttpChannelParent final : public n | |
uint8_t mSuspendAfterSynthesizeResponse : 1; | |
// Set if this channel will synthesize its response. | |
uint8_t mWillSynthesizeResponse : 1; | |
// Set if we get the result of and cache |mNeedFlowControl| | |
uint8_t mCacheNeedFlowControlInitialized : 1; | |
uint8_t mNeedFlowControl : 1; | |
uint8_t mSuspendedForFlowControl : 1; | |
+ | |
+ // The child channel was cancelled, as the consumer was relocated to another | |
+ // process. | |
uint8_t mDoingCrossProcessRedirect : 1; | |
// Number of events to wait before actually invoking AsyncOpen on the main | |
// channel. For each asynchronous step required before InvokeAsyncOpen, should | |
// increase 1 to mAsyncOpenBarrier and invoke TryInvokeAsyncOpen after | |
// finished. This attribute is main thread only. | |
uint8_t mAsyncOpenBarrier = 0; | |
}; | |
diff --git a/netwerk/protocol/http/HttpChannelParentListener.cpp b/netwerk/protocol/http/HttpChannelParentListener.cpp | |
--- a/netwerk/protocol/http/HttpChannelParentListener.cpp | |
+++ b/netwerk/protocol/http/HttpChannelParentListener.cpp | |
@@ -152,17 +152,17 @@ HttpChannelParentListener::GetInterface( | |
//----------------------------------------------------------------------------- | |
// HttpChannelParentListener::nsIChannelEventSink | |
//----------------------------------------------------------------------------- | |
nsresult HttpChannelParentListener::TriggerCrossProcessRedirect( | |
nsIChannel* aChannel, nsILoadInfo* aLoadInfo, uint64_t aIdentifier) { | |
RefPtr<HttpChannelParent> channelParent = do_QueryObject(mNextListener); | |
MOZ_ASSERT(channelParent); | |
- channelParent->SetCrossProcessRedirect(); | |
+ channelParent->CancelChildCrossProcessRedirect(); | |
nsCOMPtr<nsIChannel> channel = aChannel; | |
RefPtr<nsHttpChannel> httpChannel = do_QueryObject(channel); | |
RefPtr<nsHttpChannel::TabPromise> p = httpChannel->TakeRedirectTabPromise(); | |
nsCOMPtr<nsILoadInfo> loadInfo = aLoadInfo; | |
RefPtr<HttpChannelParentListener> self = this; | |
p->Then( | |
@@ -193,21 +193,16 @@ nsresult HttpChannelParentListener::Trig | |
channel->GetOriginalURI(getter_AddRefs(originalURI)); | |
uint64_t channelId; | |
MOZ_ALWAYS_SUCCEEDS(httpChannel->GetChannelId(&channelId)); | |
dom::TabParent* tabParent = dom::TabParent::GetFrom(tp); | |
ContentParent* cp = tabParent->Manager()->AsContentParent(); | |
- RefPtr<HttpChannelParent> channelParent = | |
- do_QueryObject(self->mNextListener); | |
- MOZ_ASSERT(channelParent); | |
- channelParent->SetCrossProcessRedirect(); | |
- | |
auto result = cp->SendCrossProcessRedirect( | |
self->mRedirectChannelId, uri, newLoadFlags, loadInfoArgs, | |
channelId, originalURI, aIdentifier); | |
MOZ_ASSERT(result, "SendCrossProcessRedirect failed"); | |
return result ? NS_OK : NS_ERROR_UNEXPECTED; | |
}, |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment