commit 42e92f77039be21302d7a97ae0de0417c30dd7f2
parent f933e64c34f94e61b3c2489e203f920b456b22b4
Author: Kershaw Chang <kershaw@mozilla.com>
Date: Tue, 6 Jan 2026 09:25:28 +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:
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};
};