mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-01 00:32:11 +00:00
Backed out 5 changesets (bug 1675016) for causing xpcshell failures in test_http3_fatal_stream_error. CLOSED TREE
Backed out changeset aae840485291 (bug 1675016) Backed out changeset c5f004fdef59 (bug 1675016) Backed out changeset 56b8282707e0 (bug 1675016) Backed out changeset ac23fff376cf (bug 1675016) Backed out changeset 63109e213984 (bug 1675016)
This commit is contained in:
parent
06adde3adb
commit
03e890da15
@ -160,9 +160,7 @@ void AltSvcMapping::ProcessHeader(
|
||||
SpdyInformation* spdyInfo = gHttpHandler->SpdyInfo();
|
||||
if (!(NS_SUCCEEDED(spdyInfo->GetNPNIndex(npnToken, &spdyIndex)) &&
|
||||
spdyInfo->ProtocolEnabled(spdyIndex)) &&
|
||||
!(isHttp3 && gHttpHandler->IsHttp3Enabled() &&
|
||||
!gHttpHandler->IsHttp3Excluded(hostname.IsEmpty() ? originHost
|
||||
: hostname))) {
|
||||
!(isHttp3 && gHttpHandler->IsHttp3Enabled())) {
|
||||
LOG(("Alt Svc unknown protocol %s, ignoring", npnToken.get()));
|
||||
continue;
|
||||
}
|
||||
@ -944,8 +942,7 @@ already_AddRefed<AltSvcMapping> AltSvcCache::LookupMapping(
|
||||
|
||||
if (rv->IsHttp3() &&
|
||||
(!gHttpHandler->IsHttp3Enabled() ||
|
||||
!gHttpHandler->IsHttp3VersionSupported(rv->NPNToken()) ||
|
||||
gHttpHandler->IsHttp3Excluded(rv->AlternateHost()))) {
|
||||
!gHttpHandler->IsHttp3VersionSupported(rv->NPNToken()))) {
|
||||
// If Http3 is disabled or the version not supported anymore, remove the
|
||||
// mapping.
|
||||
mStorage->Remove(
|
||||
|
@ -73,7 +73,8 @@ Http3Session::Http3Session()
|
||||
gHttpHandler->ConnMgr()->CurrentTopLevelOuterContentWindowId();
|
||||
}
|
||||
|
||||
nsresult Http3Session::Init(const nsHttpConnectionInfo* aConnInfo,
|
||||
nsresult Http3Session::Init(const nsACString& aOrigin,
|
||||
const nsACString& aAlpnToken,
|
||||
nsISocketTransport* aSocketTransport,
|
||||
HttpConnectionUDP* readerWriter) {
|
||||
LOG3(("Http3Session::Init %p", this));
|
||||
@ -82,7 +83,7 @@ nsresult Http3Session::Init(const nsHttpConnectionInfo* aConnInfo,
|
||||
MOZ_ASSERT(aSocketTransport);
|
||||
MOZ_ASSERT(readerWriter);
|
||||
|
||||
mConnInfo = aConnInfo->Clone();
|
||||
mAlpnToken = aAlpnToken;
|
||||
mSocketTransport = aSocketTransport;
|
||||
|
||||
nsCOMPtr<nsISupports> info;
|
||||
@ -136,14 +137,14 @@ nsresult Http3Session::Init(const nsHttpConnectionInfo* aConnInfo,
|
||||
LOG3(
|
||||
("Http3Session::Init origin=%s, alpn=%s, selfAddr=%s, peerAddr=%s,"
|
||||
" qpack table size=%u, max blocked streams=%u [this=%p]",
|
||||
PromiseFlatCString(mConnInfo->GetOrigin()).get(),
|
||||
PromiseFlatCString(mConnInfo->GetNPNToken()).get(), selfAddrStr.get(),
|
||||
peerAddrStr.get(), gHttpHandler->DefaultQpackTableSize(),
|
||||
PromiseFlatCString(aOrigin).get(), PromiseFlatCString(aAlpnToken).get(),
|
||||
selfAddrStr.get(), peerAddrStr.get(),
|
||||
gHttpHandler->DefaultQpackTableSize(),
|
||||
gHttpHandler->DefaultHttp3MaxBlockedStreams(), this));
|
||||
|
||||
nsresult rv = NeqoHttp3Conn::Init(
|
||||
mConnInfo->GetOrigin(), mConnInfo->GetNPNToken(), selfAddrStr,
|
||||
peerAddrStr, gHttpHandler->DefaultQpackTableSize(),
|
||||
aOrigin, aAlpnToken, selfAddrStr, peerAddrStr,
|
||||
gHttpHandler->DefaultQpackTableSize(),
|
||||
gHttpHandler->DefaultHttp3MaxBlockedStreams(),
|
||||
gHttpHandler->Http3QlogDir(), getter_AddRefs(mHttp3Connection));
|
||||
if (NS_FAILED(rv)) {
|
||||
@ -186,11 +187,6 @@ nsresult Http3Session::Init(const nsHttpConnectionInfo* aConnInfo,
|
||||
void Http3Session::Shutdown() {
|
||||
MOZ_ASSERT(OnSocketThread(), "not on socket thread");
|
||||
|
||||
if ((mBeforeConnectedError || (mError == NS_ERROR_NET_HTTP3_PROTOCOL_ERROR)) &&
|
||||
(mError != mozilla::psm::GetXPCOMFromNSSError(SSL_ERROR_BAD_CERT_DOMAIN))) {
|
||||
gHttpHandler->ExcludeHttp3(mConnInfo);
|
||||
}
|
||||
|
||||
for (auto iter = mStreamTransactionHash.Iter(); !iter.Done(); iter.Next()) {
|
||||
RefPtr<Http3Stream> stream = iter.Data();
|
||||
|
||||
@ -199,12 +195,10 @@ void Http3Session::Shutdown() {
|
||||
// The transaction restart code path will remove AltSvc mapping and the
|
||||
// direct path will be used.
|
||||
MOZ_ASSERT(NS_FAILED(mError));
|
||||
stream->Close(NS_ERROR_NET_RESET);
|
||||
stream->Close(mError);
|
||||
} else if (!stream->HasStreamId()) {
|
||||
if (NS_SUCCEEDED(mError)) {
|
||||
// Connection has not been started yet. We can restart it.
|
||||
stream->Transaction()->DoNotRemoveAltSvc();
|
||||
}
|
||||
// Connection has not been started yet. We can restart it.
|
||||
stream->Transaction()->DoNotRemoveAltSvc();
|
||||
stream->Close(NS_ERROR_NET_RESET);
|
||||
} else if (stream->RecvdData()) {
|
||||
stream->Close(NS_ERROR_NET_PARTIAL_TRANSFER);
|
||||
@ -842,8 +836,7 @@ void Http3Session::ResetRecvd(uint64_t aStreamId, uint64_t aError) {
|
||||
if (aError == HTTP3_APP_ERROR_VERSION_FALLBACK) {
|
||||
// We will restart the request and the alt-svc will be removed
|
||||
// automatically.
|
||||
// Also disable http3 we want http1.1.
|
||||
stream->Transaction()->DisableHttp3();
|
||||
// Also disable spdy we want http/1.1.
|
||||
stream->Transaction()->DisableSpdy();
|
||||
CloseStream(stream, NS_ERROR_NET_RESET);
|
||||
} else if (aError == HTTP3_APP_ERROR_REQUEST_REJECTED) {
|
||||
@ -1481,11 +1474,11 @@ bool Http3Session::RealJoinConnection(const nsACString& hostname, int32_t port,
|
||||
|
||||
bool joinedReturn = false;
|
||||
if (justKidding) {
|
||||
rv = sslSocketControl->TestJoinConnection(mConnInfo->GetNPNToken(),
|
||||
hostname, port, &isJoined);
|
||||
rv = sslSocketControl->TestJoinConnection(mAlpnToken, hostname, port,
|
||||
&isJoined);
|
||||
} else {
|
||||
rv = sslSocketControl->JoinConnection(mConnInfo->GetNPNToken(), hostname,
|
||||
port, &isJoined);
|
||||
rv =
|
||||
sslSocketControl->JoinConnection(mAlpnToken, hostname, port, &isJoined);
|
||||
}
|
||||
if (NS_SUCCEEDED(rv) && isJoined) {
|
||||
joinedReturn = true;
|
||||
|
@ -46,7 +46,7 @@ class Http3Session final : public nsAHttpTransaction,
|
||||
NS_DECL_NSAHTTPSEGMENTWRITER
|
||||
|
||||
Http3Session();
|
||||
nsresult Init(const nsHttpConnectionInfo* aConnInfo,
|
||||
nsresult Init(const nsACString& aOrigin, const nsACString& aAlpnToken,
|
||||
nsISocketTransport* aSocketTransport,
|
||||
HttpConnectionUDP* readerWriter);
|
||||
|
||||
@ -206,8 +206,6 @@ class Http3Session final : public nsAHttpTransaction,
|
||||
// NS_NET_STATUS_CONNECTED_TO event will be created by the Http3Session.
|
||||
// We want to propagate it to the first transaction.
|
||||
RefPtr<nsHttpTransaction> mFirstHttpTransaction;
|
||||
|
||||
RefPtr<nsHttpConnectionInfo> mConnInfo;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(Http3Session, NS_HTTP3SESSION_IID);
|
||||
|
@ -115,7 +115,8 @@ nsresult HttpConnectionUDP::Init(
|
||||
|
||||
MOZ_ASSERT(mConnInfo->IsHttp3());
|
||||
mHttp3Session = new Http3Session();
|
||||
nsresult rv = mHttp3Session->Init(mConnInfo, mSocketTransport, this);
|
||||
nsresult rv = mHttp3Session->Init(
|
||||
mConnInfo->GetOrigin(), mConnInfo->GetNPNToken(), mSocketTransport, this);
|
||||
if (NS_FAILED(rv)) {
|
||||
LOG(
|
||||
("HttpConnectionUDP::Init mHttp3Session->Init failed "
|
||||
|
@ -396,7 +396,8 @@ nsresult TRRServiceChannel::BeginConnect() {
|
||||
mAllowAltSvc = XRE_IsParentProcess() && mAllowAltSvc;
|
||||
bool http2Allowed = !gHttpHandler->IsHttp2Excluded(connInfo);
|
||||
bool http3Allowed = !mUpgradeProtocolCallback && !mProxyInfo &&
|
||||
!(mCaps & NS_HTTP_BE_CONSERVATIVE) && !mBeConservative;
|
||||
!(mCaps & NS_HTTP_BE_CONSERVATIVE) && !mBeConservative &&
|
||||
!gHttpHandler->IsHttp3Excluded(connInfo);
|
||||
|
||||
RefPtr<AltSvcMapping> mapping;
|
||||
if (!mConnectionInfo && mAllowAltSvc && // per channel
|
||||
|
@ -178,7 +178,6 @@ class nsAHttpTransaction : public nsSupportsWeakReference {
|
||||
}
|
||||
|
||||
virtual void DisableSpdy() {}
|
||||
virtual void DisableHttp3() {}
|
||||
virtual void MakeNonSticky() {}
|
||||
virtual void ReuseConnectionOnRestartOK(bool) {}
|
||||
|
||||
|
@ -6672,7 +6672,7 @@ nsresult nsHttpChannel::BeginConnect() {
|
||||
}
|
||||
bool http3Allowed = !mUpgradeProtocolCallback && !mProxyInfo &&
|
||||
!(mCaps & NS_HTTP_BE_CONSERVATIVE) && !mBeConservative &&
|
||||
mAllowHttp3;
|
||||
!gHttpHandler->IsHttp3Excluded(connInfo) && mAllowHttp3;
|
||||
|
||||
// No need to lookup HTTPSSVC record if we already have one.
|
||||
mUseHTTPSSVC =
|
||||
|
@ -2851,15 +2851,15 @@ void nsHttpHandler::ExcludeHttp3(const nsHttpConnectionInfo* ci) {
|
||||
MOZ_ASSERT(OnSocketThread(), "not on socket thread");
|
||||
|
||||
mConnMgr->ExcludeHttp3(ci);
|
||||
if (!mExcludedHttp3Origins.Contains(ci->GetRoutedHost())) {
|
||||
if (!mExcludedHttp3Origins.Contains(ci->GetOrigin())) {
|
||||
MutexAutoLock lock(mHttpExclusionLock);
|
||||
mExcludedHttp3Origins.PutEntry(ci->GetRoutedHost());
|
||||
mExcludedHttp3Origins.PutEntry(ci->GetOrigin());
|
||||
}
|
||||
}
|
||||
|
||||
bool nsHttpHandler::IsHttp3Excluded(const nsACString& aRoutedHost) {
|
||||
bool nsHttpHandler::IsHttp3Excluded(const nsHttpConnectionInfo* ci) {
|
||||
MutexAutoLock lock(mHttpExclusionLock);
|
||||
return mExcludedHttp3Origins.Contains(aRoutedHost);
|
||||
return mExcludedHttp3Origins.Contains(ci->GetOrigin());
|
||||
}
|
||||
|
||||
HttpTrafficAnalyzer* nsHttpHandler::GetHttpTrafficAnalyzer() {
|
||||
|
@ -855,7 +855,7 @@ class nsHttpHandler final : public nsIHttpProtocolHandler,
|
||||
void ExcludeHttp2(const nsHttpConnectionInfo* ci);
|
||||
[[nodiscard]] bool IsHttp2Excluded(const nsHttpConnectionInfo* ci);
|
||||
void ExcludeHttp3(const nsHttpConnectionInfo* ci);
|
||||
[[nodiscard]] bool IsHttp3Excluded(const nsACString& aRoutedHost);
|
||||
[[nodiscard]] bool IsHttp3Excluded(const nsHttpConnectionInfo* ci);
|
||||
|
||||
private:
|
||||
nsTHashtable<nsCStringHashKey> mExcludedHttp2Origins;
|
||||
|
@ -2413,11 +2413,6 @@ void nsHttpTransaction::DisableHttp3() {
|
||||
// After CloneAsDirectRoute(), http3 will be disabled.
|
||||
RefPtr<nsHttpConnectionInfo> connInfo;
|
||||
mConnInfo->CloneAsDirectRoute(getter_AddRefs(connInfo));
|
||||
if (mRequestHead) {
|
||||
DebugOnly<nsresult> rv =
|
||||
mRequestHead->SetHeader(nsHttp::Alternate_Service_Used, "0"_ns);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
}
|
||||
MOZ_ASSERT(!connInfo->IsHttp3());
|
||||
mConnInfo.swap(connInfo);
|
||||
}
|
||||
@ -2808,11 +2803,6 @@ nsresult nsHttpTransaction::RestartOnFastOpenError() {
|
||||
RefPtr<nsHttpConnectionInfo> ci;
|
||||
mConnInfo->CloneAsDirectRoute(getter_AddRefs(ci));
|
||||
mConnInfo = ci;
|
||||
if (mRequestHead) {
|
||||
DebugOnly<nsresult> rv =
|
||||
mRequestHead->SetHeader(nsHttp::Alternate_Service_Used, "0"_ns);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
}
|
||||
}
|
||||
mEarlyDataDisposition = EARLY_NONE;
|
||||
m0RTTInProgress = false;
|
||||
|
@ -103,7 +103,7 @@ class nsHttpTransaction final : public nsAHttpTransaction,
|
||||
void RemoveDispatchedAsBlocking();
|
||||
|
||||
void DisableSpdy() override;
|
||||
void DisableHttp3() override;
|
||||
void DisableHttp3();
|
||||
|
||||
nsHttpTransaction* QueryHttpTransaction() override { return this; }
|
||||
|
||||
|
@ -304,24 +304,6 @@ impl HttpServer for Server {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct NonRespondingServer {
|
||||
}
|
||||
|
||||
impl ::std::fmt::Display for NonRespondingServer {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
||||
write!(f, "NonRespondingServer")
|
||||
}
|
||||
}
|
||||
|
||||
impl HttpServer for NonRespondingServer {
|
||||
fn process(&mut self, _dgram: Option<Datagram>) -> Output {
|
||||
Output::None
|
||||
}
|
||||
|
||||
fn process_events(&mut self) {}
|
||||
}
|
||||
|
||||
fn emit_packet(socket: &UdpSocket, out_dgram: Datagram) {
|
||||
let sent = socket
|
||||
.send_to(&out_dgram, &out_dgram.destination())
|
||||
@ -386,12 +368,6 @@ fn read_dgram(
|
||||
}
|
||||
}
|
||||
|
||||
enum ServerType {
|
||||
Http3,
|
||||
Http3Fail,
|
||||
Http3NoResponse,
|
||||
}
|
||||
|
||||
struct ServersRunner {
|
||||
hosts: Vec<SocketAddr>,
|
||||
poll: Poll,
|
||||
@ -416,21 +392,19 @@ impl ServersRunner {
|
||||
}
|
||||
|
||||
pub fn init(&mut self) {
|
||||
self.add_new_socket(0, ServerType::Http3);
|
||||
self.add_new_socket(1, ServerType::Http3Fail);
|
||||
self.add_new_socket(3, ServerType::Http3NoResponse);
|
||||
self.add_new_socket(0, true);
|
||||
self.add_new_socket(1, false);
|
||||
println!(
|
||||
"HTTP3 server listening on ports {}, {} and {}",
|
||||
"HTTP3 server listening on ports {} and {}",
|
||||
self.hosts[0].port(),
|
||||
self.hosts[1].port(),
|
||||
self.hosts[2].port()
|
||||
self.hosts[1].port()
|
||||
);
|
||||
self.poll
|
||||
.register(&self.timer, TIMER_TOKEN, Ready::readable(), PollOpt::edge())
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
fn add_new_socket(&mut self, count: usize, server_type: ServerType) -> u16 {
|
||||
fn add_new_socket(&mut self, count: usize, http3: bool) -> u16 {
|
||||
let addr = "127.0.0.1:0".parse().unwrap();
|
||||
|
||||
let socket = match UdpSocket::bind(&addr) {
|
||||
@ -462,49 +436,44 @@ impl ServersRunner {
|
||||
|
||||
self.sockets.push(socket);
|
||||
self.servers
|
||||
.insert(local_addr, (self.create_server(server_type), None));
|
||||
.insert(local_addr, (self.create_server(http3), None));
|
||||
local_addr.port()
|
||||
}
|
||||
|
||||
fn create_server(&self, server_type: ServerType) -> Box<dyn HttpServer> {
|
||||
fn create_server(&self, http3: bool) -> Box<dyn HttpServer> {
|
||||
let anti_replay = AntiReplay::new(Instant::now(), Duration::from_secs(10), 7, 14)
|
||||
.expect("unable to setup anti-replay");
|
||||
let cid_mgr = Rc::new(RefCell::new(FixedConnectionIdManager::new(10)));
|
||||
|
||||
match server_type {
|
||||
ServerType::Http3 =>
|
||||
Box::new(
|
||||
Http3TestServer::new(
|
||||
Http3Server::new(
|
||||
Instant::now(),
|
||||
&[" HTTP2 Test Cert"],
|
||||
PROTOCOLS,
|
||||
anti_replay,
|
||||
cid_mgr,
|
||||
QpackSettings {
|
||||
max_table_size_encoder: MAX_TABLE_SIZE,
|
||||
max_table_size_decoder: MAX_TABLE_SIZE,
|
||||
max_blocked_streams: MAX_BLOCKED_STREAMS,
|
||||
},
|
||||
).expect("We cannot make a server!")
|
||||
)
|
||||
),
|
||||
ServerType::Http3Fail =>
|
||||
Box::new(
|
||||
Server::new(
|
||||
if http3 {
|
||||
Box::new(
|
||||
Http3TestServer::new(
|
||||
Http3Server::new(
|
||||
Instant::now(),
|
||||
&[" HTTP2 Test Cert"],
|
||||
PROTOCOLS,
|
||||
anti_replay,
|
||||
Box::new(AllowZeroRtt {}),
|
||||
cid_mgr,
|
||||
)
|
||||
.expect("We cannot make a server!"),
|
||||
),
|
||||
ServerType::Http3NoResponse =>
|
||||
Box::new(
|
||||
NonRespondingServer::default()
|
||||
),
|
||||
QpackSettings {
|
||||
max_table_size_encoder: MAX_TABLE_SIZE,
|
||||
max_table_size_decoder: MAX_TABLE_SIZE,
|
||||
max_blocked_streams: MAX_BLOCKED_STREAMS,
|
||||
},
|
||||
).expect("We cannot make a server!")
|
||||
)
|
||||
)
|
||||
} else {
|
||||
Box::new(
|
||||
Server::new(
|
||||
Instant::now(),
|
||||
&[" HTTP2 Test Cert"],
|
||||
PROTOCOLS,
|
||||
anti_replay,
|
||||
Box::new(AllowZeroRtt {}),
|
||||
cid_mgr,
|
||||
)
|
||||
.expect("We cannot make a server!"),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,124 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
"use strict";
|
||||
|
||||
let httpsUri;
|
||||
|
||||
registerCleanupFunction(async () => {
|
||||
Services.prefs.clearUserPref("network.http.http3.enabled");
|
||||
Services.prefs.clearUserPref("network.dns.localDomains");
|
||||
Services.prefs.clearUserPref("network.dns.disableIPv6");
|
||||
Services.prefs.clearUserPref(
|
||||
"network.http.http3.alt-svc-mapping-for-testing"
|
||||
);
|
||||
dump("cleanup done\n");
|
||||
});
|
||||
|
||||
function chanPromise(chan, listener) {
|
||||
return new Promise(resolve => {
|
||||
function finish() {
|
||||
resolve();
|
||||
}
|
||||
listener.finish = finish;
|
||||
chan.asyncOpen(listener);
|
||||
});
|
||||
}
|
||||
|
||||
function makeChan() {
|
||||
let chan = NetUtil.newChannel({
|
||||
uri: httpsUri,
|
||||
loadUsingSystemPrincipal: true,
|
||||
}).QueryInterface(Ci.nsIHttpChannel);
|
||||
chan.loadFlags = Ci.nsIChannel.LOAD_INITIAL_DOCUMENT_URI;
|
||||
return chan;
|
||||
}
|
||||
|
||||
function altsvcSetupPromise(chan, listener) {
|
||||
return new Promise(resolve => {
|
||||
function finish(result) {
|
||||
resolve(result);
|
||||
}
|
||||
listener.finish = finish;
|
||||
chan.asyncOpen(listener);
|
||||
});
|
||||
}
|
||||
|
||||
add_task(async function test_fatal_error() {
|
||||
let env = Cc["@mozilla.org/process/environment;1"].getService(
|
||||
Ci.nsIEnvironment
|
||||
);
|
||||
|
||||
let h2Port = env.get("MOZHTTP2_PORT");
|
||||
Assert.notEqual(h2Port, null);
|
||||
let h3Port = env.get("MOZHTTP3_PORT_NO_RESPONSE");
|
||||
Assert.notEqual(h3Port, null);
|
||||
Assert.notEqual(h3Port, "");
|
||||
|
||||
Services.prefs.setBoolPref("network.http.http3.enabled", true);
|
||||
Services.prefs.setCharPref("network.dns.localDomains", "foo.example.com");
|
||||
Services.prefs.setBoolPref("network.dns.disableIPv6", true);
|
||||
// Set AltSvc to point to not existing HTTP3 server on port 443
|
||||
Services.prefs.setCharPref(
|
||||
"network.http.http3.alt-svc-mapping-for-testing",
|
||||
"foo.example.com;h3-27=:" + h3Port
|
||||
);
|
||||
|
||||
let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService(
|
||||
Ci.nsIX509CertDB
|
||||
);
|
||||
addCertFromFile(certdb, "http2-ca.pem", "CTu,u,u");
|
||||
|
||||
httpsUri = "https://foo.example.com:" + h2Port + "/";
|
||||
});
|
||||
|
||||
add_task(async function test_fatal_stream_error() {
|
||||
let result = 1;
|
||||
// We need to loop here because we need to wait for AltSvc storage to
|
||||
// to be started.
|
||||
// We also do not have a way to verify that HTTP3 has been tried, because
|
||||
// the fallback is automatic, so try a couple of times.
|
||||
do {
|
||||
// We need to close HTTP2 connections, otherwise our connection pooling
|
||||
// will dispatch the request over already existing HTTP2 connection.
|
||||
Services.obs.notifyObservers(null, "net:prune-all-connections");
|
||||
let chan = makeChan();
|
||||
let listener = new CheckOnlyHttp2Listener();
|
||||
await altsvcSetupPromise(chan, listener);
|
||||
result++;
|
||||
} while (result < 5);
|
||||
});
|
||||
|
||||
let CheckOnlyHttp2Listener = function() {};
|
||||
|
||||
CheckOnlyHttp2Listener.prototype = {
|
||||
onStartRequest: function testOnStartRequest(request) {},
|
||||
|
||||
onDataAvailable: function testOnDataAvailable(request, stream, off, cnt) {
|
||||
read_stream(stream, cnt);
|
||||
},
|
||||
|
||||
onStopRequest: function testOnStopRequest(request, status) {
|
||||
Assert.equal(status, Cr.NS_OK);
|
||||
let httpVersion = "";
|
||||
try {
|
||||
httpVersion = request.protocolVersion;
|
||||
} catch (e) {}
|
||||
Assert.equal(httpVersion, "h2");
|
||||
this.finish();
|
||||
},
|
||||
};
|
||||
|
||||
add_task(async function test_no_http3_after_error() {
|
||||
let chan = makeChan();
|
||||
let listener = new CheckOnlyHttp2Listener();
|
||||
await altsvcSetupPromise(chan, listener);
|
||||
});
|
||||
|
||||
// also after all connections are closed.
|
||||
add_task(async function test_no_http3_after_error2() {
|
||||
Services.obs.notifyObservers(null, "net:prune-all-connections");
|
||||
let chan = makeChan();
|
||||
let listener = new CheckOnlyHttp2Listener();
|
||||
await altsvcSetupPromise(chan, listener);
|
||||
});
|
@ -1,147 +1,141 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
"use strict";
|
||||
|
||||
let httpsUri;
|
||||
let h3Port;
|
||||
let h3Route;
|
||||
let h3AltSvc;
|
||||
let prefs;
|
||||
let httpsOrigin;
|
||||
|
||||
registerCleanupFunction(async () => {
|
||||
Services.prefs.clearUserPref("network.http.http3.enabled");
|
||||
Services.prefs.clearUserPref("network.dns.localDomains");
|
||||
Services.prefs.clearUserPref("network.dns.disableIPv6");
|
||||
Services.prefs.clearUserPref(
|
||||
"network.http.http3.alt-svc-mapping-for-testing"
|
||||
let tests = [
|
||||
// The altSvc storage may not be up imediately, therefore run test_no_altsvc_pref
|
||||
// for a couple times to wait for the storage.
|
||||
test_no_altsvc_pref,
|
||||
test_no_altsvc_pref,
|
||||
test_no_altsvc_pref,
|
||||
test_protocol_error,
|
||||
testsDone,
|
||||
];
|
||||
|
||||
let current_test = 0;
|
||||
|
||||
function run_next_test() {
|
||||
if (current_test < tests.length) {
|
||||
dump("starting test number " + current_test + "\n");
|
||||
tests[current_test]();
|
||||
current_test++;
|
||||
}
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
let env = Cc["@mozilla.org/process/environment;1"].getService(
|
||||
Ci.nsIEnvironment
|
||||
);
|
||||
dump("cleanup done\n");
|
||||
});
|
||||
h3Port = env.get("MOZHTTP3_PORT_FAILED");
|
||||
Assert.notEqual(h3Port, null);
|
||||
Assert.notEqual(h3Port, "");
|
||||
h3AltSvc = ":" + h3Port;
|
||||
|
||||
let Http3FailedListener = function() {};
|
||||
h3Route = "foo.example.com:" + h3Port;
|
||||
do_get_profile();
|
||||
prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
|
||||
|
||||
Http3FailedListener.prototype = {
|
||||
onStartRequest: function testOnStartRequest(request) {},
|
||||
prefs.setBoolPref("network.http.http3.enabled", true);
|
||||
prefs.setCharPref("network.dns.localDomains", "foo.example.com");
|
||||
prefs.setBoolPref("network.dns.disableIPv6", true);
|
||||
|
||||
// The certificate for the http3server server is for foo.example.com and
|
||||
// is signed by http2-ca.pem so add that cert to the trust list as a
|
||||
// signing cert.
|
||||
let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService(
|
||||
Ci.nsIX509CertDB
|
||||
);
|
||||
addCertFromFile(certdb, "http2-ca.pem", "CTu,u,u");
|
||||
httpsOrigin = "https://foo.example.com/";
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
let Http3CheckListener = function() {};
|
||||
|
||||
Http3CheckListener.prototype = {
|
||||
expectedRoute: "",
|
||||
expectedStatus: Cr.NS_OK,
|
||||
|
||||
onStartRequest: function testOnStartRequest(request) {
|
||||
Assert.ok(request instanceof Ci.nsIHttpChannel);
|
||||
Assert.equal(request.status, this.expectedStatus);
|
||||
if (Components.isSuccessCode(this.expectedStatus)) {
|
||||
Assert.equal(request.responseStatus, 200);
|
||||
}
|
||||
},
|
||||
|
||||
onDataAvailable: function testOnDataAvailable(request, stream, off, cnt) {
|
||||
this.amount += cnt;
|
||||
read_stream(stream, cnt);
|
||||
},
|
||||
|
||||
onStopRequest: function testOnStopRequest(request, status) {
|
||||
if (Components.isSuccessCode(status)) {
|
||||
// This is still HTTP2 connection
|
||||
Assert.equal(status, this.expectedStatus);
|
||||
if (Components.isSuccessCode(this.expectedStatus)) {
|
||||
Assert.equal(request.responseStatus, 200);
|
||||
let routed = "NA";
|
||||
try {
|
||||
routed = request.getRequestHeader("Alt-Used");
|
||||
} catch (e) {}
|
||||
dump("routed is " + routed + "\n");
|
||||
|
||||
Assert.equal(routed, this.expectedRoute);
|
||||
|
||||
let httpVersion = "";
|
||||
try {
|
||||
httpVersion = request.protocolVersion;
|
||||
} catch (e) {}
|
||||
Assert.equal(httpVersion, "h2");
|
||||
this.finish(false);
|
||||
} else {
|
||||
Assert.equal(status, Cr.NS_ERROR_NET_PARTIAL_TRANSFER);
|
||||
this.finish(true);
|
||||
Assert.equal(httpVersion, "h3");
|
||||
}
|
||||
|
||||
run_next_test();
|
||||
do_test_finished();
|
||||
},
|
||||
};
|
||||
|
||||
function chanPromise(chan, listener) {
|
||||
return new Promise(resolve => {
|
||||
function finish(result) {
|
||||
resolve(result);
|
||||
}
|
||||
listener.finish = finish;
|
||||
chan.asyncOpen(listener);
|
||||
});
|
||||
}
|
||||
|
||||
function makeChan() {
|
||||
function makeChan(uri) {
|
||||
let chan = NetUtil.newChannel({
|
||||
uri: httpsUri,
|
||||
uri,
|
||||
loadUsingSystemPrincipal: true,
|
||||
}).QueryInterface(Ci.nsIHttpChannel);
|
||||
chan.loadFlags = Ci.nsIChannel.LOAD_INITIAL_DOCUMENT_URI;
|
||||
return chan;
|
||||
}
|
||||
|
||||
function altsvcSetupPromise(chan, listener) {
|
||||
return new Promise(resolve => {
|
||||
function finish(result) {
|
||||
resolve(result);
|
||||
}
|
||||
listener.finish = finish;
|
||||
chan.asyncOpen(listener);
|
||||
});
|
||||
function test_no_altsvc_pref() {
|
||||
dump("test_no_altsvc_pref");
|
||||
do_test_pending();
|
||||
|
||||
let chan = makeChan(httpsOrigin + "http3-test");
|
||||
let listener = new Http3CheckListener();
|
||||
listener.expectedStatus = Cr.NS_ERROR_CONNECTION_REFUSED;
|
||||
chan.asyncOpen(listener);
|
||||
}
|
||||
|
||||
add_task(async function test_fatal_error() {
|
||||
let env = Cc["@mozilla.org/process/environment;1"].getService(
|
||||
Ci.nsIEnvironment
|
||||
);
|
||||
function test_protocol_error() {
|
||||
dump("test_protocol_error");
|
||||
do_test_pending();
|
||||
|
||||
let h2Port = env.get("MOZHTTP2_PORT");
|
||||
Assert.notEqual(h2Port, null);
|
||||
|
||||
let h3Port = env.get("MOZHTTP3_PORT_FAILED");
|
||||
Assert.notEqual(h3Port, null);
|
||||
Assert.notEqual(h3Port, "");
|
||||
|
||||
Services.prefs.setBoolPref("network.http.http3.enabled", true);
|
||||
Services.prefs.setCharPref("network.dns.localDomains", "foo.example.com");
|
||||
Services.prefs.setBoolPref("network.dns.disableIPv6", true);
|
||||
Services.prefs.setCharPref(
|
||||
prefs.setCharPref(
|
||||
"network.http.http3.alt-svc-mapping-for-testing",
|
||||
"foo.example.com;h3-27=:" + h3Port
|
||||
"foo.example.com;h3-27=" + h3AltSvc
|
||||
);
|
||||
|
||||
let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService(
|
||||
Ci.nsIX509CertDB
|
||||
);
|
||||
addCertFromFile(certdb, "http2-ca.pem", "CTu,u,u");
|
||||
let chan = makeChan(httpsOrigin + "wrong_frame_after_data_frame");
|
||||
let listener = new Http3CheckListener();
|
||||
listener.expectedRoute = h3Route;
|
||||
listener.expectedStatus = Cr.NS_ERROR_NET_PARTIAL_TRANSFER;
|
||||
chan.asyncOpen(listener);
|
||||
}
|
||||
|
||||
httpsUri = "https://foo.example.com:" + h2Port + "/";
|
||||
});
|
||||
|
||||
add_task(async function test_fatal_stream_error() {
|
||||
let result = false;
|
||||
// We need to loop here because we need to wait for AltSvc storage to
|
||||
// to be started.
|
||||
do {
|
||||
// We need to close HTTP2 connections, otherwise our connection pooling
|
||||
// will dispatch the request over already existing HTTP2 connection.
|
||||
Services.obs.notifyObservers(null, "net:prune-all-connections");
|
||||
let chan = makeChan();
|
||||
let listener = new Http3FailedListener();
|
||||
result = await altsvcSetupPromise(chan, listener);
|
||||
} while (result === false);
|
||||
});
|
||||
|
||||
let CheckOnlyHttp2Listener = function() {};
|
||||
|
||||
CheckOnlyHttp2Listener.prototype = {
|
||||
onStartRequest: function testOnStartRequest(request) {},
|
||||
|
||||
onDataAvailable: function testOnDataAvailable(request, stream, off, cnt) {
|
||||
read_stream(stream, cnt);
|
||||
},
|
||||
|
||||
onStopRequest: function testOnStopRequest(request, status) {
|
||||
Assert.equal(status, Cr.NS_OK);
|
||||
let httpVersion = "";
|
||||
try {
|
||||
httpVersion = request.protocolVersion;
|
||||
} catch (e) {}
|
||||
Assert.equal(httpVersion, "h2");
|
||||
this.finish(false);
|
||||
},
|
||||
};
|
||||
|
||||
add_task(async function test_no_http3_after_error() {
|
||||
let chan = makeChan();
|
||||
let listener = new CheckOnlyHttp2Listener();
|
||||
await altsvcSetupPromise(chan, listener);
|
||||
});
|
||||
|
||||
// also after all connections are closed.
|
||||
add_task(async function test_no_http3_after_error2() {
|
||||
Services.obs.notifyObservers(null, "net:prune-all-connections");
|
||||
let chan = makeChan();
|
||||
let listener = new CheckOnlyHttp2Listener();
|
||||
await altsvcSetupPromise(chan, listener);
|
||||
});
|
||||
function testsDone() {
|
||||
prefs.clearUserPref("network.http.http3.enabled");
|
||||
prefs.clearUserPref("network.dns.localDomains");
|
||||
prefs.clearUserPref("network.dns.disableIPv6");
|
||||
prefs.clearUserPref("network.http.http3.alt-svc-mapping-for-testing");
|
||||
dump("testDone\n");
|
||||
}
|
||||
|
@ -1,121 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
"use strict";
|
||||
|
||||
let httpsUri;
|
||||
|
||||
registerCleanupFunction(async () => {
|
||||
Services.prefs.clearUserPref("network.http.http3.enabled");
|
||||
Services.prefs.clearUserPref("network.dns.localDomains");
|
||||
Services.prefs.clearUserPref("network.dns.disableIPv6");
|
||||
Services.prefs.clearUserPref(
|
||||
"network.http.http3.alt-svc-mapping-for-testing"
|
||||
);
|
||||
dump("cleanup done\n");
|
||||
});
|
||||
|
||||
function chanPromise(chan, listener) {
|
||||
return new Promise(resolve => {
|
||||
function finish() {
|
||||
resolve();
|
||||
}
|
||||
listener.finish = finish;
|
||||
chan.asyncOpen(listener);
|
||||
});
|
||||
}
|
||||
|
||||
function makeChan() {
|
||||
let chan = NetUtil.newChannel({
|
||||
uri: httpsUri,
|
||||
loadUsingSystemPrincipal: true,
|
||||
}).QueryInterface(Ci.nsIHttpChannel);
|
||||
chan.loadFlags = Ci.nsIChannel.LOAD_INITIAL_DOCUMENT_URI;
|
||||
return chan;
|
||||
}
|
||||
|
||||
function altsvcSetupPromise(chan, listener) {
|
||||
return new Promise(resolve => {
|
||||
function finish(result) {
|
||||
resolve(result);
|
||||
}
|
||||
listener.finish = finish;
|
||||
chan.asyncOpen(listener);
|
||||
});
|
||||
}
|
||||
|
||||
add_task(async function test_fatal_error() {
|
||||
let env = Cc["@mozilla.org/process/environment;1"].getService(
|
||||
Ci.nsIEnvironment
|
||||
);
|
||||
|
||||
let h2Port = env.get("MOZHTTP2_PORT");
|
||||
Assert.notEqual(h2Port, null);
|
||||
|
||||
Services.prefs.setBoolPref("network.http.http3.enabled", true);
|
||||
Services.prefs.setCharPref("network.dns.localDomains", "foo.example.com");
|
||||
Services.prefs.setBoolPref("network.dns.disableIPv6", true);
|
||||
// Set AltSvc to point to not existing HTTP3 server on port 443
|
||||
Services.prefs.setCharPref(
|
||||
"network.http.http3.alt-svc-mapping-for-testing",
|
||||
"foo.example.com;h3-27=:443"
|
||||
);
|
||||
|
||||
let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService(
|
||||
Ci.nsIX509CertDB
|
||||
);
|
||||
addCertFromFile(certdb, "http2-ca.pem", "CTu,u,u");
|
||||
|
||||
httpsUri = "https://foo.example.com:" + h2Port + "/";
|
||||
});
|
||||
|
||||
add_task(async function test_fatal_stream_error() {
|
||||
let result = 1;
|
||||
// We need to loop here because we need to wait for AltSvc storage to
|
||||
// to be started.
|
||||
// We also do not have a way to verify that HTTP3 has been tried, because
|
||||
// the fallback is automatic, so try a couple of times.
|
||||
do {
|
||||
// We need to close HTTP2 connections, otherwise our connection pooling
|
||||
// will dispatch the request over already existing HTTP2 connection.
|
||||
Services.obs.notifyObservers(null, "net:prune-all-connections");
|
||||
let chan = makeChan();
|
||||
let listener = new CheckOnlyHttp2Listener();
|
||||
await altsvcSetupPromise(chan, listener);
|
||||
result++;
|
||||
} while (result < 5);
|
||||
});
|
||||
|
||||
let CheckOnlyHttp2Listener = function() {};
|
||||
|
||||
CheckOnlyHttp2Listener.prototype = {
|
||||
onStartRequest: function testOnStartRequest(request) {},
|
||||
|
||||
onDataAvailable: function testOnDataAvailable(request, stream, off, cnt) {
|
||||
read_stream(stream, cnt);
|
||||
},
|
||||
|
||||
onStopRequest: function testOnStopRequest(request, status) {
|
||||
Assert.equal(status, Cr.NS_OK);
|
||||
let httpVersion = "";
|
||||
try {
|
||||
httpVersion = request.protocolVersion;
|
||||
} catch (e) {}
|
||||
Assert.equal(httpVersion, "h2");
|
||||
this.finish();
|
||||
},
|
||||
};
|
||||
|
||||
add_task(async function test_no_http3_after_error() {
|
||||
let chan = makeChan();
|
||||
let listener = new CheckOnlyHttp2Listener();
|
||||
await altsvcSetupPromise(chan, listener);
|
||||
});
|
||||
|
||||
// also after all connections are closed.
|
||||
add_task(async function test_no_http3_after_error2() {
|
||||
Services.obs.notifyObservers(null, "net:prune-all-connections");
|
||||
let chan = makeChan();
|
||||
let listener = new CheckOnlyHttp2Listener();
|
||||
await altsvcSetupPromise(chan, listener);
|
||||
});
|
@ -479,9 +479,5 @@ skip-if = asan || tsan || os == 'win' || os =='android'
|
||||
skip-if = asan || tsan || os == 'win' || os =='android'
|
||||
[test_http3_large_post.js]
|
||||
skip-if = asan || tsan || os == 'win' || os =='android'
|
||||
[test_http3_error_before_connect.js]
|
||||
skip-if = asan || tsan || os == 'win' || os =='android'
|
||||
[test_http3_server_not_existing.js]
|
||||
skip-if = asan || tsan || os == 'win' || os =='android'
|
||||
[test_cookie_ipv6.js]
|
||||
|
||||
|
@ -1412,14 +1412,11 @@ class XPCShellTests(object):
|
||||
msg = process.stdout.readline()
|
||||
if "server listening" in msg:
|
||||
searchObj = re.search(
|
||||
r"HTTP3 server listening on ports ([0-9]+), ([0-9]+) and ([0-9]+)",
|
||||
msg,
|
||||
0,
|
||||
r"HTTP3 server listening on ports ([0-9]+) and ([0-9]+)", msg, 0
|
||||
)
|
||||
if searchObj:
|
||||
self.env["MOZHTTP3_PORT"] = searchObj.group(1)
|
||||
self.env["MOZHTTP3_PORT_FAILED"] = searchObj.group(2)
|
||||
self.env["MOZHTTP3_PORT_NO_RESPONSE"] = searchObj.group(3)
|
||||
except OSError as e:
|
||||
# This occurs if the subprocess couldn't be started
|
||||
self.log.error("Could not run the http3 server: %s" % (str(e)))
|
||||
|
Loading…
Reference in New Issue
Block a user