tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 805fffea427c8d3be92e8465828bfd361043a33b
parent b4b41e381bc7be90a90c5a2d30444f1a06b0dc70
Author: Kershaw Chang <kershaw@mozilla.com>
Date:   Tue,  6 Jan 2026 15:41:36 +0000

Bug 2004918 - Remove nsHttpConnection::RequestDone to prevent premature H2 tunnel close, r=necko-reviewers,valentin

Previously we set mRequestDone = true right after writing the HTTP request. That state propagated to Http2StreamTunnel::mSendClosed, and in Http2StreamBase::ReadSegments the stream was got closed.
As a result, an HTTP/2 tunnel could be closed immediately after sending the request bytes, failing to receive the response.

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

Diffstat:
Mnetwerk/protocol/http/Http2StreamTunnel.cpp | 19-------------------
Mnetwerk/protocol/http/Http2StreamTunnel.h | 2--
Mnetwerk/protocol/http/Http3StreamTunnel.cpp | 22----------------------
Mnetwerk/protocol/http/Http3StreamTunnel.h | 3+--
Mnetwerk/protocol/http/TLSTransportLayer.cpp | 6------
Mnetwerk/protocol/http/nsHttpConnection.cpp | 12+-----------
Mnetwerk/protocol/http/nsHttpConnection.h | 3---
7 files changed, 2 insertions(+), 65 deletions(-)

diff --git a/netwerk/protocol/http/Http2StreamTunnel.cpp b/netwerk/protocol/http/Http2StreamTunnel.cpp @@ -350,30 +350,11 @@ nsresult OutputStreamTunnel::OnSocketReady(nsresult condition) { nsresult rv = NS_OK; if (callback) { rv = callback->OnOutputStreamReady(this); - MaybeSetRequestDone(callback); } return rv; } -void OutputStreamTunnel::MaybeSetRequestDone( - nsIOutputStreamCallback* aCallback) { - RefPtr<nsHttpConnection> conn = do_QueryObject(aCallback); - if (!conn) { - return; - } - - RefPtr<Http2StreamTunnel> tunnel; - nsresult rv = GetStream(getter_AddRefs(tunnel)); - if (NS_FAILED(rv)) { - return; - } - - if (conn->RequestDone()) { - tunnel->SetRequestDone(); - } -} - NS_IMPL_ISUPPORTS(OutputStreamTunnel, nsIOutputStream, nsIAsyncOutputStream) NS_IMETHODIMP diff --git a/netwerk/protocol/http/Http2StreamTunnel.h b/netwerk/protocol/http/Http2StreamTunnel.h @@ -37,7 +37,6 @@ class Http2StreamTunnel : public Http2StreamBase, public nsISocketTransport { nsHttpConnectionInfo* ConnectionInfo() override { return mConnectionInfo; } - void SetRequestDone() { mSendClosed = true; } nsresult Condition() override { return mCondition; } void CloseStream(nsresult reason) override; void DisableSpdy() override { @@ -90,7 +89,6 @@ class OutputStreamTunnel : public nsIAsyncOutputStream { explicit OutputStreamTunnel(Http2StreamTunnel* aStream); nsresult OnSocketReady(nsresult condition); - void MaybeSetRequestDone(nsIOutputStreamCallback* aCallback); private: virtual ~OutputStreamTunnel(); diff --git a/netwerk/protocol/http/Http3StreamTunnel.cpp b/netwerk/protocol/http/Http3StreamTunnel.cpp @@ -267,29 +267,11 @@ nsresult Http3TransportLayer::OutputStreamTunnel::OnSocketReady( nsresult rv = NS_OK; if (callback) { rv = callback->OnOutputStreamReady(this); - MaybeSetRequestDone(callback); } return rv; } -void Http3TransportLayer::OutputStreamTunnel::MaybeSetRequestDone( - nsIOutputStreamCallback* aCallback) { - RefPtr<nsHttpConnection> conn = do_QueryObject(aCallback); - if (!conn) { - return; - } - - RefPtr<Http3StreamTunnel> tunnel = mTransport->GetStream(); - if (!tunnel) { - return; - } - - if (conn->RequestDone()) { - tunnel->SetRequestDone(); - } -} - NS_IMETHODIMP Http3TransportLayer::OutputStreamTunnel::AsyncWait( nsIOutputStreamCallback* callback, uint32_t flags, uint32_t amount, @@ -767,10 +749,6 @@ nsresult Http3StreamTunnel::OnWriteSegment(char* buf, uint32_t count, return Http3Stream::OnWriteSegment(buf, count, countWritten); } -void Http3StreamTunnel::SetRequestDone() { - LOG(("Http3StreamTunnel::SetRequestDone %p", this)); -} - void Http3StreamTunnel::HasDataToWrite() { mSession->StreamHasDataToWrite(this); } diff --git a/netwerk/protocol/http/Http3StreamTunnel.h b/netwerk/protocol/http/Http3StreamTunnel.h @@ -66,7 +66,6 @@ class Http3TransportLayer final : public nsISocketTransport, explicit OutputStreamTunnel(Http3TransportLayer* aTransport); nsresult OnSocketReady(nsresult condition); - void MaybeSetRequestDone(nsIOutputStreamCallback* aCallback); private: friend class Http3TransportLayer; @@ -108,7 +107,7 @@ class Http3StreamTunnel final : public Http3Stream { bool aIsExtendedCONNECT); void CleanupStream(nsresult aReason); - void SetRequestDone(); + void HasDataToWrite(); void HasDataToRead(); diff --git a/netwerk/protocol/http/TLSTransportLayer.cpp b/netwerk/protocol/http/TLSTransportLayer.cpp @@ -7,7 +7,6 @@ // HttpLog.h should generally be included first #include "HttpLog.h" -#include "Http2StreamTunnel.h" #include "TLSTransportLayer.h" #include "nsISocketProvider.h" #include "nsITLSSocketControl.h" @@ -451,11 +450,6 @@ TLSTransportLayer::OnOutputStreamReady(nsIAsyncOutputStream* out) { nsresult rv = NS_OK; if (callback) { rv = callback->OnOutputStreamReady(&mSocketOutWrapper); - - RefPtr<OutputStreamTunnel> tunnel = do_QueryObject(out); - if (tunnel) { - tunnel->MaybeSetRequestDone(callback); - } } return rv; } diff --git a/netwerk/protocol/http/nsHttpConnection.cpp b/netwerk/protocol/http/nsHttpConnection.cpp @@ -1778,17 +1778,7 @@ nsresult nsHttpConnection::OnSocketWritable() { rv = ResumeRecv(); // start reading } - // When Spdy tunnel is used we need to explicitly set when a request is - // done. - if ((mState != HttpConnectionState::SETTING_UP_TUNNEL) && !mSpdySession) { - nsHttpTransaction* trans = - mTransaction ? mTransaction->QueryHttpTransaction() : nullptr; - // needed for websocket over h2 (direct) - if (!trans || - (!trans->IsWebsocketUpgrade() && !trans->IsForWebTransport())) { - mRequestDone = true; - } - } + again = false; } else if (writeAttempts >= maxWriteAttempts) { LOG((" yield for other transactions\n")); diff --git a/netwerk/protocol/http/nsHttpConnection.h b/netwerk/protocol/http/nsHttpConnection.h @@ -197,8 +197,6 @@ class nsHttpConnection final : public HttpConnectionBase, HttpConnectionBase** aHttpConnection, bool aIsExtendedCONNECT = false) override; - bool RequestDone() { return mRequestDone; } - private: void SetTunnelSetupDone() override; nsresult SetupProxyConnectStream() override; @@ -366,7 +364,6 @@ class nsHttpConnection final : public HttpConnectionBase, nsCOMPtr<nsIInputStream> mProxyConnectStream; - bool mRequestDone{false}; bool mHasTLSTransportLayer{false}; bool mTransactionDisallowHttp3{false}; };