commit 0f009118c8bdc161c1f1a25bd237ac771715d08e
parent d46abe6d763df3ce5c5b20673ed531c4e79c49e4
Author: Serban Stanca <sstanca@mozilla.com>
Date: Tue, 6 Jan 2026 19:40:45 +0200
Revert "Bug 2004918 - Remove nsHttpConnection::RequestDone to prevent premature H2 tunnel close, r=necko-reviewers,valentin" for causing mochitests failures in browser_IPPChannelFilter.js.
This reverts commit 805fffea427c8d3be92e8465828bfd361043a33b.
This reverts commit b4b41e381bc7be90a90c5a2d30444f1a06b0dc70.
Diffstat:
11 files changed, 67 insertions(+), 19 deletions(-)
diff --git a/browser/components/ipprotection/IPPChannelFilter.sys.mjs b/browser/components/ipprotection/IPPChannelFilter.sys.mjs
@@ -12,8 +12,7 @@ const lazy = XPCOMUtils.declareLazy({
iid: Ci.nsIProtocolProxyService,
},
});
-const { TRANSPARENT_PROXY_RESOLVES_HOST, ALWAYS_TUNNEL_VIA_PROXY } =
- Ci.nsIProxyInfo;
+const { TRANSPARENT_PROXY_RESOLVES_HOST } = Ci.nsIProxyInfo;
const failOverTimeout = 10; // seconds
const MODE_PREF = "browser.ipProtection.mode";
@@ -109,7 +108,7 @@ export class IPPChannelFilter {
protocol.port,
authToken,
isolationKey,
- TRANSPARENT_PROXY_RESOLVES_HOST | ALWAYS_TUNNEL_VIA_PROXY,
+ TRANSPARENT_PROXY_RESOLVES_HOST,
failOverTimeout,
fallBackInfo
);
diff --git a/netwerk/base/nsIProxyInfo.idl b/netwerk/base/nsIProxyInfo.idl
@@ -117,10 +117,4 @@ interface nsIProxyInfo : nsISupports
* do any form of DNS lookup ourselves.
*/
const unsigned short TRANSPARENT_PROXY_RESOLVES_HOST = 1 << 0;
-
- /**
- * When set, force all requests to use an HTTP CONNECT tunnel
- * through the proxy.
- */
- const unsigned short ALWAYS_TUNNEL_VIA_PROXY = 1 << 1;
};
diff --git a/netwerk/base/nsProtocolProxyService.cpp b/netwerk/base/nsProtocolProxyService.cpp
@@ -2108,9 +2108,6 @@ nsresult nsProtocolProxyService::NewProxyInfo_Internal(
proxyInfo->mPassword = aPassword;
proxyInfo->mFlags = aFlags;
proxyInfo->mResolveFlags = aResolveFlags;
- if (aFlags & nsIProxyInfo::ALWAYS_TUNNEL_VIA_PROXY) {
- proxyInfo->mResolveFlags |= nsIProtocolProxyService::RESOLVE_ALWAYS_TUNNEL;
- }
proxyInfo->mTimeout =
aFailoverTimeout == UINT32_MAX ? mFailedProxyTimeout : aFailoverTimeout;
proxyInfo->mProxyAuthorizationHeader = aProxyAuthorizationHeader;
diff --git a/netwerk/base/nsProxyInfo.cpp b/netwerk/base/nsProxyInfo.cpp
@@ -8,7 +8,6 @@
#include "mozilla/net/NeckoChannelParams.h"
#include "nsCOMPtr.h"
-#include "nsIProtocolProxyService.h"
namespace mozilla {
namespace net {
@@ -62,10 +61,6 @@ nsProxyInfo::nsProxyInfo(const nsACString& aType, const nsACString& aHost,
} else {
mType = kProxyType_DIRECT;
}
-
- if (mFlags & nsIProxyInfo::ALWAYS_TUNNEL_VIA_PROXY) {
- mResolveFlags |= nsIProtocolProxyService::RESOLVE_ALWAYS_TUNNEL;
- }
}
NS_IMETHODIMP
diff --git a/netwerk/protocol/http/Http2StreamTunnel.cpp b/netwerk/protocol/http/Http2StreamTunnel.cpp
@@ -350,11 +350,30 @@ 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,6 +37,7 @@ 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 {
@@ -89,6 +90,7 @@ 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,11 +267,29 @@ 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,
@@ -749,6 +767,10 @@ 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,6 +66,7 @@ class Http3TransportLayer final : public nsISocketTransport,
explicit OutputStreamTunnel(Http3TransportLayer* aTransport);
nsresult OnSocketReady(nsresult condition);
+ void MaybeSetRequestDone(nsIOutputStreamCallback* aCallback);
private:
friend class Http3TransportLayer;
@@ -107,7 +108,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,6 +7,7 @@
// HttpLog.h should generally be included first
#include "HttpLog.h"
+#include "Http2StreamTunnel.h"
#include "TLSTransportLayer.h"
#include "nsISocketProvider.h"
#include "nsITLSSocketControl.h"
@@ -450,6 +451,11 @@ 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,7 +1778,17 @@ 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,6 +197,8 @@ class nsHttpConnection final : public HttpConnectionBase,
HttpConnectionBase** aHttpConnection,
bool aIsExtendedCONNECT = false) override;
+ bool RequestDone() { return mRequestDone; }
+
private:
void SetTunnelSetupDone() override;
nsresult SetupProxyConnectStream() override;
@@ -364,6 +366,7 @@ class nsHttpConnection final : public HttpConnectionBase,
nsCOMPtr<nsIInputStream> mProxyConnectStream;
+ bool mRequestDone{false};
bool mHasTLSTransportLayer{false};
bool mTransactionDisallowHttp3{false};
};