Bug 1321528: Part 1 - Support suspending requests when processing response headers. r=honzab

MozReview-Commit-ID: 8ZtbvqLDksO

--HG--
extra : rebase_source : 8b3ac15e3983e0c3d520a631862430b6d1b23ca1
This commit is contained in:
Kris Maglione 2016-12-16 13:45:40 -08:00
parent c04c07394e
commit b9cfaed91f
2 changed files with 46 additions and 14 deletions

View File

@ -1900,7 +1900,6 @@ nsHttpChannel::ProcessAltService()
nsresult
nsHttpChannel::ProcessResponse()
{
nsresult rv;
uint32_t httpStatus = mResponseHead->Status();
LOG(("nsHttpChannel::ProcessResponse [this=%p httpStatus=%u]\n",
@ -1993,7 +1992,7 @@ nsHttpChannel::ProcessResponse()
} else {
// Given a successful connection, process any STS or PKP data that's
// relevant.
rv = ProcessSecurityHeaders();
DebugOnly<nsresult> rv = ProcessSecurityHeaders();
MOZ_ASSERT(NS_SUCCEEDED(rv), "ProcessSTSHeader failed, continuing load.");
}
@ -2004,6 +2003,37 @@ nsHttpChannel::ProcessResponse()
// notify "http-on-examine-response" observers
gHttpHandler->OnExamineResponse(this);
return ContinueProcessResponse1();
}
void
nsHttpChannel::AsyncContinueProcessResponse()
{
nsresult rv;
rv = ContinueProcessResponse1();
if (NS_FAILED(rv)) {
// A synchronous failure here would normally be passed as the return
// value from OnStartRequest, which would in turn cancel the request.
// If we're continuing asynchronously, we need to cancel the request
// ourselves.
Unused << Cancel(rv);
}
}
nsresult
nsHttpChannel::ContinueProcessResponse1()
{
NS_PRECONDITION(!mCallOnResume, "How did that happen?");
nsresult rv;
if (mSuspendCount) {
LOG(("Waiting until resume to finish processing response [this=%p]\n", this));
mCallOnResume = &nsHttpChannel::AsyncContinueProcessResponse;
return NS_OK;
}
uint32_t httpStatus = mResponseHead->Status();
// Cookies and Alt-Service should not be handled on proxy failure either.
// This would be consolidated with ProcessSecurityHeaders but it should
// happen after OnExamineResponse.
@ -2042,22 +2072,22 @@ nsHttpChannel::ProcessResponse()
nsCOMPtr<nsIURI> redirectTo;
mAPIRedirectToURI.swap(redirectTo);
PushRedirectAsyncFunc(&nsHttpChannel::ContinueProcessResponse1);
PushRedirectAsyncFunc(&nsHttpChannel::ContinueProcessResponse2);
rv = StartRedirectChannelToURI(redirectTo, nsIChannelEventSink::REDIRECT_TEMPORARY);
if (NS_SUCCEEDED(rv)) {
return NS_OK;
}
PopRedirectAsyncFunc(&nsHttpChannel::ContinueProcessResponse1);
PopRedirectAsyncFunc(&nsHttpChannel::ContinueProcessResponse2);
}
// Hack: ContinueProcessResponse1 uses NS_OK to detect successful
// Hack: ContinueProcessResponse2 uses NS_OK to detect successful
// redirects, so we distinguish this codepath (a non-redirect that's
// processing normally) by passing in a bogus error code.
return ContinueProcessResponse1(NS_BINDING_FAILED);
return ContinueProcessResponse2(NS_BINDING_FAILED);
}
nsresult
nsHttpChannel::ContinueProcessResponse1(nsresult rv)
nsHttpChannel::ContinueProcessResponse2(nsresult rv)
{
if (NS_SUCCEEDED(rv)) {
// redirectTo() has passed through, we don't want to go on with
@ -2112,10 +2142,10 @@ nsHttpChannel::ContinueProcessResponse1(nsresult rv)
#endif
// don't store the response body for redirects
MaybeInvalidateCacheEntryForSubsequentGet();
PushRedirectAsyncFunc(&nsHttpChannel::ContinueProcessResponse2);
PushRedirectAsyncFunc(&nsHttpChannel::ContinueProcessResponse3);
rv = AsyncProcessRedirection(httpStatus);
if (NS_FAILED(rv)) {
PopRedirectAsyncFunc(&nsHttpChannel::ContinueProcessResponse2);
PopRedirectAsyncFunc(&nsHttpChannel::ContinueProcessResponse3);
LOG(("AsyncProcessRedirection failed [rv=%x]\n", rv));
// don't cache failed redirect responses.
if (mCacheEntry)
@ -2124,7 +2154,7 @@ nsHttpChannel::ContinueProcessResponse1(nsresult rv)
mStatus = rv;
DoNotifyListener();
} else {
rv = ContinueProcessResponse2(rv);
rv = ContinueProcessResponse3(rv);
}
}
break;
@ -2232,7 +2262,7 @@ nsHttpChannel::ContinueProcessResponse1(nsresult rv)
}
nsresult
nsHttpChannel::ContinueProcessResponse2(nsresult rv)
nsHttpChannel::ContinueProcessResponse3(nsresult rv)
{
bool doNotRender = DoNotRender3xxBody(rv);
@ -2248,7 +2278,7 @@ nsHttpChannel::ContinueProcessResponse2(nsresult rv)
// redirecting to another protocol (perhaps javascript:)
// In that case we want to throw an error instead of displaying the
// non-redirected response body.
LOG(("ContinueProcessResponse2 detected rejected Non-HTTP Redirection"));
LOG(("ContinueProcessResponse3 detected rejected Non-HTTP Redirection"));
doNotRender = true;
rv = NS_ERROR_CORRUPTED_CONTENT;
}
@ -2274,7 +2304,7 @@ nsHttpChannel::ContinueProcessResponse2(nsresult rv)
return NS_OK;
}
LOG(("ContinueProcessResponse2 got failure result [rv=%x]\n", rv));
LOG(("ContinueProcessResponse3 got failure result [rv=%x]\n", rv));
if (mTransaction->ProxyConnectFailed()) {
return ProcessFailedProxyConnect(mRedirectType);
}

View File

@ -290,8 +290,10 @@ private:
void SetupTransactionRequestContext();
nsresult CallOnStartRequest();
nsresult ProcessResponse();
nsresult ContinueProcessResponse1(nsresult);
void AsyncContinueProcessResponse();
nsresult ContinueProcessResponse1();
nsresult ContinueProcessResponse2(nsresult);
nsresult ContinueProcessResponse3(nsresult);
nsresult ProcessNormal();
nsresult ContinueProcessNormal(nsresult);
void ProcessAltService();