Bug 1409858 - H2 CONNECT Tunnel Marked Plaintext Too Late r=nwgh
MozReview-Commit-ID: IjuYDuvufRd
--- a/netwerk/protocol/http/Http2Session.cpp
+++ b/netwerk/protocol/http/Http2Session.cpp
@@ -590,19 +590,28 @@ Http2Session::FlushOutputQueue()
RealignOutputQueue();
}
}
void
Http2Session::DontReuse()
{
LOG3(("Http2Session::DontReuse %p\n", this));
+ if (!OnSocketThread()) {
+ LOG3(("Http2Session %p not on socket thread\n", this));
+ nsCOMPtr<nsIRunnable> event = NewRunnableMethod(
+ "Http2Session::DontReuse", this, &Http2Session::DontReuse);
+ gSocketTransportService->Dispatch(event, NS_DISPATCH_NORMAL);
+ return;
+ }
+
mShouldGoAway = true;
- if (!mStreamTransactionHash.Count())
+ if (!mClosed && !mStreamTransactionHash.Count()) {
Close(NS_OK);
+ }
}
uint32_t
Http2Session::SpdyVersion()
{
return HTTP_VERSION_2;
}
--- a/netwerk/protocol/http/Http2Stream.cpp
+++ b/netwerk/protocol/http/Http2Stream.cpp
@@ -1047,16 +1047,18 @@ Http2Stream::ConvertResponseHeaders(Http
}
LOG3(("Http2Stream::ConvertResponseHeaders %p response code %d\n", this, httpResponseCode));
if (mIsTunnel) {
LOG3(("Http2Stream %p Tunnel Response code %d", this, httpResponseCode));
if ((httpResponseCode / 100) != 2) {
MapStreamToPlainText();
}
+ MapStreamToHttpConnection();
+ ClearTransactionsBlockedOnTunnel();
}
if (httpResponseCode == 101) {
// 8.1.1 of h2 disallows 101.. throw PROTOCOL_ERROR on stream
LOG3(("Http2Stream::ConvertResponseHeaders %p Error - status == 101\n", this));
return NS_ERROR_ILLEGAL_VALUE;
}
@@ -1156,20 +1158,16 @@ Http2Stream::SetAllHeadersReceived()
// pushed streams needs to wait until headers have
// arrived to open up their window
LOG3(("Http2Stream::SetAllHeadersReceived %p state OPEN from reserved\n", this));
mState = OPEN;
AdjustInitialWindow();
}
mAllHeadersReceived = 1;
- if (mIsTunnel) {
- MapStreamToHttpConnection();
- ClearTransactionsBlockedOnTunnel();
- }
}
bool
Http2Stream::AllowFlowControlledWrite()
{
return (mSession->ServerSessionWindow() > 0) && (mServerReceiveWindow > 0);
}
--- a/netwerk/protocol/http/TunnelUtils.cpp
+++ b/netwerk/protocol/http/TunnelUtils.cpp
@@ -387,24 +387,25 @@ TLSFilterTransaction::NudgeTunnel(NudgeT
MOZ_ASSERT(OnSocketThread(), "not on socket thread");
LOG(("TLSFilterTransaction %p NudgeTunnel\n", this));
mNudgeCallback = nullptr;
if (!mSecInfo) {
return NS_ERROR_FAILURE;
}
- uint32_t notUsed;
- int32_t written = PR_Write(mFD, "", 0);
- if ((written < 0) && (PR_GetError() != PR_WOULD_BLOCK_ERROR)) {
+ nsCOMPtr<nsISSLSocketControl> ssl(do_QueryInterface(mSecInfo));
+ nsresult rv = ssl ? ssl->DriveHandshake() : NS_ERROR_FAILURE;
+ if (NS_FAILED(rv) && rv != NS_BASE_STREAM_WOULD_BLOCK) {
// fatal handshake failure
LOG(("TLSFilterTransaction %p Fatal Handshake Failure: %d\n", this, PR_GetError()));
return NS_ERROR_FAILURE;
}
+ uint32_t notUsed;
Unused << OnReadSegment("", 0, ¬Used);
// The SSL Layer does some unusual things with PR_Poll that makes it a bad
// match for multiplexed SSL sessions. We work around this by manually polling for
// the moment during the brief handshake phase or otherwise blocked on write.
// Thankfully this is a pretty unusual state. NSPR doesn't help us here -
// asserting when polling without the NSPR IO layer on the bottom of
// the stack. As a follow-on we can do some NSPR and maybe libssl changes