tor-browser

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

commit c7967e41ed424b40194f5bbb739b7f59eb71c454
parent 175e66322f3fda0cd205102880e3f70e10f63eec
Author: Atila Butkovits <abutkovits@mozilla.com>
Date:   Mon, 13 Oct 2025 21:16:04 +0300

Revert "Bug 1993438 - Run tests in http3_common.js with HTTP/3 proxy, r=necko-reviewers,valentin,jesup" for causing failures at test_http3_with_proxy.js.

This reverts commit da45a0fbf96029cc1067c9546f5c136b8a721e1e.

Revert "Bug 1993438 - Make Alt-Svc work for connect-udp, r=necko-reviewers,valentin"

This reverts commit ba8f1b8791ed8233117d4b4b63ab2aabd93aa59b.

Revert "Bug 1993438 - Modernize test_http3.js and extract tests into a separate file, r=necko-reviewers,valentin"

This reverts commit d037b11c9b5a45658b1c9337eebf823fa64b2d83.

Diffstat:
Mnetwerk/protocol/http/AlternateServices.cpp | 4++--
Mnetwerk/protocol/http/Http3ConnectUDPStream.cpp | 12+++---------
Dnetwerk/test/unit/http3_common.js | 719-------------------------------------------------------------------------------
Mnetwerk/test/unit/test_http3.js | 638+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------
Dnetwerk/test/unit/test_http3_with_proxy.js | 180-------------------------------------------------------------------------------
Mnetwerk/test/unit/xpcshell.toml | 12------------
6 files changed, 550 insertions(+), 1015 deletions(-)

diff --git a/netwerk/protocol/http/AlternateServices.cpp b/netwerk/protocol/http/AlternateServices.cpp @@ -1130,8 +1130,8 @@ void AltSvcCache::UpdateAltServiceMapping( } if (map->IsHttp3()) { - bool isProxyAllowed = pi ? (pi->IsDirect() || pi->IsHttp3Proxy()) : true; - if (!isProxyAllowed) { + bool isDirectOrNoProxy = pi ? pi->IsDirect() : true; + if (!isDirectOrNoProxy) { LOG( ("AltSvcCache::UpdateAltServiceMapping %p map %p ignored h3 because " "proxy is in use %p\n", diff --git a/netwerk/protocol/http/Http3ConnectUDPStream.cpp b/netwerk/protocol/http/Http3ConnectUDPStream.cpp @@ -101,19 +101,13 @@ nsresult Http3ConnectUDPStream::TryActivating() { return NS_ERROR_UNEXPECTED; } - bool useRoutedHost = - !mTransaction->ConnectionInfo()->GetRoutedHost().IsEmpty(); - nsresult rv = builder->Set( - "target_host"_ns, useRoutedHost - ? mTransaction->ConnectionInfo()->GetRoutedHost() - : mTransaction->ConnectionInfo()->GetOrigin()); + nsresult rv = builder->Set("target_host"_ns, + mTransaction->ConnectionInfo()->GetOrigin()); if (NS_FAILED(rv)) { return rv; } rv = builder->Set("target_port"_ns, - useRoutedHost - ? mTransaction->ConnectionInfo()->RoutedPort() - : mTransaction->ConnectionInfo()->OriginPort()); + mTransaction->ConnectionInfo()->OriginPort()); if (NS_FAILED(rv)) { return rv; } diff --git a/netwerk/test/unit/http3_common.js b/netwerk/test/unit/http3_common.js @@ -1,719 +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"; - -/* import-globals-from head_cache.js */ -/* import-globals-from head_cookies.js */ -/* import-globals-from head_channels.js */ -/* import-globals-from head_http3.js */ - -const { HttpServer } = ChromeUtils.importESModule( - "resource://testing-common/httpd.sys.mjs" -); - -function makeChan(uri) { - let chan = NetUtil.newChannel({ - uri, - loadUsingSystemPrincipal: true, - }).QueryInterface(Ci.nsIHttpChannel); - chan.loadFlags = Ci.nsIChannel.LOAD_INITIAL_DOCUMENT_URI; - return chan; -} - -// Promise-backed Http3CheckListener -class Http3CheckListener { - constructor( - { expectedStatus = Cr.NS_OK, expectedRoute = "" } = {}, - resolve, - reject - ) { - this.onDataAvailableFired = false; - this.expectedStatus = expectedStatus; - this.expectedRoute = expectedRoute; - this._resolve = resolve; - this._reject = reject; - } - - onStartRequest(request) { - Assert.ok(request instanceof Ci.nsIHttpChannel); - Assert.equal(request.status, this.expectedStatus); - if (Components.isSuccessCode(this.expectedStatus)) { - Assert.equal(request.responseStatus, 200); - } - } - - onDataAvailable(request, stream, off, cnt) { - this.onDataAvailableFired = true; - read_stream(stream, cnt); - } - - onStopRequest(request, status) { - Assert.equal(status, this.expectedStatus); - - let routed = "NA"; - try { - routed = request.getRequestHeader("Alt-Used"); - } catch (e) {} - dump("routed is " + routed + "\n"); - - Assert.equal(routed, this.expectedRoute); - - if (Components.isSuccessCode(this.expectedStatus)) { - let httpVersion = ""; - try { - httpVersion = request.protocolVersion; - } catch (e) {} - Assert.equal(httpVersion, "h3"); - Assert.equal(this.onDataAvailableFired, true); - Assert.equal(request.getResponseHeader("X-Firefox-Http3"), "h3"); - } - - this._resolve?.(request); - } -} - -class WaitForHttp3Listener extends Http3CheckListener { - constructor( - { - expectedStatus = Cr.NS_OK, - expectedRoute = "", - uri = "", - h3AltSvc = "", - retry, - delayMs = 500, - } = {}, - resolve, - reject - ) { - super({ expectedStatus, expectedRoute }, resolve, reject); - this.uri = uri; - this.h3AltSvc = h3AltSvc; - this._retry = retry; // function to re-open the request - this._delayMs = delayMs; // poll interval - } - - onStopRequest(request, status) { - Assert.equal(status, this.expectedStatus); - - let routed = "NA"; - try { - routed = request.getRequestHeader("Alt-Used"); - } catch (e) {} - dump(`routed is ${routed}\n`); - - let httpVersion = ""; - try { - httpVersion = request.protocolVersion; - } catch (e) {} - - if (routed === this.expectedRoute) { - // (This is where run_next_test() used to be.) - Assert.equal(routed, this.expectedRoute); // useful log/assert - Assert.equal(httpVersion, "h3"); - this._resolve?.(request); - return; - } - - // Not routed yet: mirror old behavior (log + supportsHTTP3 check + retry) - dump("poll later for alt-svc mapping\n"); - if (httpVersion === "h2") { - request.QueryInterface(Ci.nsIHttpChannelInternal); - Assert.ok(request.supportsHTTP3); - } - - if (typeof this._retry === "function") { - // schedule another attempt (replaces do_test_pending/do_timeout recursion) - do_timeout(this._delayMs, () => - this._retry(this.uri, this.expectedRoute, this.h3AltSvc) - ); - } - // Promise remains pending until a later attempt matches expectedRoute. - } -} - -// Factory to create { listener, promise } -function createHttp3CheckListener(options = {}) { - let resolve, reject; - const promise = new Promise((res, rej) => { - resolve = res; - reject = rej; - }); - const listener = new Http3CheckListener(options, resolve, reject); - return { listener, promise }; -} - -function createWaitForHttp3Listener(options = {}) { - let resolve, reject; - const promise = new Promise((res, rej) => { - resolve = res; - reject = rej; - }); - const listener = new WaitForHttp3Listener(options, resolve, reject); - return { listener, promise }; -} - -// --- Async wrapper that does the polling by re-issuing the request --- -async function waitForHttp3Route( - uri, - expectedRoute, - altSvc, - { delayMs = 500 } = {} -) { - let listenerRef; - - // Function to (re)open the channel using the same listener instance. - const retry = () => { - const chan = makeChan(uri); - if (altSvc) { - chan.setRequestHeader("x-altsvc", altSvc, false); - } - chan.asyncOpen(listenerRef); - }; - - const { listener, promise } = createWaitForHttp3Listener({ - expectedStatus: Cr.NS_OK, - expectedRoute, - uri, - h3AltSvc: altSvc, - retry, - delayMs, - }); - listenerRef = listener; - - // Kick off first attempt; subsequent attempts are scheduled by the listener. - retry(); - - // Resolves only when routed === expectedRoute - return promise; -} - -// Promise-backed MultipleListener -class MultipleListener { - constructor( - { - number_of_parallel_requests = 0, - expectedRoute = "", - with_error = Cr.NS_OK, // NS_OK means we expect success for all - } = {}, - resolve, - reject - ) { - this.number_of_parallel_requests = number_of_parallel_requests; - this.expectedRoute = expectedRoute; - this.with_error = with_error; - - this.count_of_done_requests = 0; - this.error_found_onstart = false; - this.error_found_onstop = false; - this.need_cancel_found = false; - - this._resolve = resolve; - this._reject = reject; - } - - onStartRequest(request) { - Assert.ok(request instanceof Ci.nsIHttpChannel); - - // Optional cancel behavior via header "CancelMe" - let need_cancel = ""; - try { - need_cancel = request.getRequestHeader("CancelMe"); - } catch (_) {} - if (need_cancel !== "") { - this.need_cancel_found = true; - request.cancel(Cr.NS_ERROR_ABORT); - return; - } - - // Original logic: either 200 OK for success, or exactly one failure - if (Components.isSuccessCode(request.status)) { - Assert.equal(request.responseStatus, 200); - } else if (this.error_found_onstart) { - // Fail fast: more than one failing request on start - this._reject?.( - new Error("We should have only one request failing (onStart).") - ); - } else { - Assert.equal(request.status, this.with_error); - this.error_found_onstart = true; - } - } - - onDataAvailable(request, stream, off, cnt) { - read_stream(stream, cnt); - } - - onStopRequest(request) { - // Check Alt-Used routing matches expectation - let routed = ""; - try { - routed = request.getRequestHeader("Alt-Used"); - } catch (_) {} - Assert.equal(routed, this.expectedRoute); - - // If success, ensure HTTP/3 - if (Components.isSuccessCode(request.status)) { - let httpVersion = ""; - try { - httpVersion = request.protocolVersion; - } catch (_) {} - Assert.equal(httpVersion, "h3"); - } - - // Track/validate failures (at most one) - if (!Components.isSuccessCode(request.status)) { - if (this.error_found_onstop) { - this._reject?.( - new Error("We should have only one request failing (onStop).") - ); - return; - } - Assert.equal(request.status, this.with_error); - this.error_found_onstop = true; - } - - // Count completion and maybe resolve - this.count_of_done_requests++; - if (this.count_of_done_requests === this.number_of_parallel_requests) { - if (Components.isSuccessCode(this.with_error)) { - // All were expected to succeed - Assert.equal(this.error_found_onstart, false); - Assert.equal(this.error_found_onstop, false); - } else { - // One failure was expected OR a cancel path was exercised - Assert.ok(this.error_found_onstart || this.need_cancel_found); - Assert.equal(this.error_found_onstop, true); - } - this._resolve?.(); - } - } -} - -// Factory to create { listener, promise } -function createMultipleListener(options = {}) { - let resolve, reject; - const promise = new Promise((res, rej) => { - resolve = res; - reject = rej; - }); - const listener = new MultipleListener(options, resolve, reject); - return { listener, promise }; -} - -async function do_test_multiple_requests( - number_of_parallel_requests, - h3Route, - httpsOrigin -) { - dump("test_multiple_requests()\n"); - - const { listener, promise } = createMultipleListener({ - number_of_parallel_requests, - expectedRoute: h3Route, - with_error: Cr.NS_OK, - }); - - for (let i = 0; i < number_of_parallel_requests; i++) { - const chan = makeChan(httpsOrigin + "20000"); - chan.asyncOpen(listener); - } - - await promise; -} - -async function do_test_request_cancelled_by_server(h3Route, httpsOrigin) { - dump("do_test_request_cancelled_by_server()\n"); - - const { listener, promise } = createHttp3CheckListener({ - expectedStatus: Cr.NS_ERROR_NET_INTERRUPT, - expectedRoute: h3Route, - }); - - const chan = makeChan(httpsOrigin + "RequestCancelled"); - chan.asyncOpen(listener); - - // Resolves at the point where run_next_test() used to be called - await promise; -} - -// Promise-backed Http3CheckListener must already exist: -// createHttp3CheckListener({ expectedStatus, expectedRoute }) - -class CancelRequestListener extends Http3CheckListener { - constructor({ expectedRoute = "" } = {}, resolve, reject) { - super( - { expectedStatus: Cr.NS_ERROR_ABORT, expectedRoute }, - resolve, - reject - ); - } - - onStartRequest(request) { - Assert.ok(request instanceof Ci.nsIHttpChannel); - Assert.equal(Components.isSuccessCode(request.status), true); - // Cancel the request immediately (simulate Necko cancelling) - request.cancel(Cr.NS_ERROR_ABORT); - } -} - -function createCancelRequestListener(options = {}) { - let resolve, reject; - const promise = new Promise((res, rej) => { - resolve = res; - reject = rej; - }); - const listener = new CancelRequestListener(options, resolve, reject); - return { listener, promise }; -} - -// Cancel stream after OnStartRequest. -async function do_test_stream_cancelled_by_necko(h3Route, httpsOrigin) { - dump("do_test_stream_cancelled_by_necko()\n"); - - const { listener, promise } = createCancelRequestListener({ - expectedRoute: h3Route, - }); - - const chan = makeChan(httpsOrigin + "20000"); - chan.asyncOpen(listener); - - // Resolves at the end of onStopRequest (where run_next_test() used to be) - await promise; -} - -async function do_test_multiple_request_one_is_cancelled( - number_of_parallel_requests, - h3Route, - httpsOrigin -) { - dump("do_test_multiple_request_one_is_cancelled()\n"); - - const { listener, promise } = createMultipleListener({ - number_of_parallel_requests, - expectedRoute: h3Route, - with_error: Cr.NS_ERROR_NET_INTERRUPT, // one request is expected to fail (server-cancelled) - }); - - for (let i = 0; i < number_of_parallel_requests; i++) { - let uri = httpsOrigin + "20000"; - if (i === 4) { - // Add a request that will be cancelled by the server. - uri = httpsOrigin + "RequestCancelled"; - } - const chan = makeChan(uri); - chan.asyncOpen(listener); - } - - // Resolves when all parallel requests complete and invariants are checked - await promise; -} - -async function do_test_multiple_request_one_is_cancelled_by_necko( - number_of_parallel_requests, - h3Route, - httpsOrigin -) { - dump("do_test_multiple_request_one_is_cancelled_by_necko()\n"); - - const { listener, promise } = createMultipleListener({ - number_of_parallel_requests, - expectedRoute: h3Route, - with_error: Cr.NS_ERROR_ABORT, - }); - - for (let i = 0; i < number_of_parallel_requests; i++) { - let chan = makeChan(httpsOrigin + "20000"); - if (i === 4) { - // MultipleListener will cancel request with this header. - chan.setRequestHeader("CancelMe", "true", false); - } - chan.asyncOpen(listener); - } - - // Resolves when all parallel requests complete and invariants are checked - await promise; -} - -// Promise-backed Http3CheckListener assumed available: -// function createHttp3CheckListener({ expectedStatus, expectedRoute }) - -class PostListener extends Http3CheckListener { - constructor(opts = {}, resolve, reject) { - super(opts, resolve, reject); - } - onDataAvailable(request, stream, off, cnt) { - this.onDataAvailableFired = true; - read_stream(stream, cnt); - } -} - -// Factory for PostListener -function createPostListener(options = {}) { - let resolve, reject; - const promise = new Promise((res, rej) => { - resolve = res; - reject = rej; - }); - const listener = new PostListener(options, resolve, reject); - return { listener, promise }; -} - -// Helper to perform a POST (or any method with a body) -function openWithBody( - content, - chan, - method = "POST", - contentType = "text/plain" -) { - const stream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance( - Ci.nsIStringInputStream - ); - stream.setByteStringData(content); - - const uchan = chan.QueryInterface(Ci.nsIUploadChannel); - uchan.setUploadStream(stream, contentType, stream.available()); - chan.requestMethod = method; - return chan; -} - -// Generate a post with known pre-calculated md5 sum. -function generateContent(size) { - let content = ""; - for (let i = 0; i < size; i++) { - content += "0"; - } - return content; -} - -let post = generateContent(10); - -// Test a simple POST (async) -async function do_test_post(httpsOrigin, h3Route) { - dump("do_test_post()\n"); - - const chan = makeChan(httpsOrigin + "post"); - openWithBody(post, chan, "POST"); - - const { listener, promise } = createPostListener({ - expectedStatus: Cr.NS_OK, - expectedRoute: h3Route, - }); - - chan.asyncOpen(listener); - await promise; // resolves at end of onStopRequest in Http3CheckListener -} - -// Test a simple PATCH -async function do_test_patch(httpsOrigin, h3Route) { - dump("do_test_post()\n"); - - const chan = makeChan(httpsOrigin + "patch"); - openWithBody(post, chan, "PATCH"); - - const { listener, promise } = createPostListener({ - expectedStatus: Cr.NS_OK, - expectedRoute: h3Route, - }); - - chan.asyncOpen(listener); - await promise; -} - -let h1Server = null; -let altsvcHost = ""; -let httpOrigin = ""; - -function h1Response(metadata, response) { - response.setStatusLine(metadata.httpVersion, 200, "OK"); - response.setHeader("Content-Type", "text/plain", false); - response.setHeader("Connection", "close", false); - response.setHeader("Cache-Control", "no-cache", false); - response.setHeader("Access-Control-Allow-Origin", "*", false); - response.setHeader("Access-Control-Allow-Method", "GET", false); - response.setHeader("Access-Control-Allow-Headers", "x-altsvc", false); - - try { - let hval = "h3=" + metadata.getHeader("x-altsvc"); - response.setHeader("Alt-Svc", hval, false); - } catch (e) {} - - let body = "Q: What did 0 say to 8? A: Nice Belt!\n"; - response.bodyOutputStream.write(body, body.length); -} - -function h1ServerWK(metadata, response) { - response.setStatusLine(metadata.httpVersion, 200, "OK"); - response.setHeader("Content-Type", "application/json", false); - response.setHeader("Connection", "close", false); - response.setHeader("Cache-Control", "no-cache", false); - response.setHeader("Access-Control-Allow-Origin", "*", false); - response.setHeader("Access-Control-Allow-Method", "GET", false); - response.setHeader("Access-Control-Allow-Headers", "x-altsvc", false); - - let body = `["http://${altsvcHost}:${h1Server.identity.primaryPort}"]`; - response.bodyOutputStream.write(body, body.length); -} - -function setup_h1_server(host) { - altsvcHost = host; - h1Server = new HttpServer(); - h1Server.registerPathHandler("/http3-test", h1Response); - h1Server.registerPathHandler("/.well-known/http-opportunistic", h1ServerWK); - h1Server.registerPathHandler("/VersionFallback", h1Response); - h1Server.start(-1); - h1Server.identity.setPrimary( - "http", - altsvcHost, - h1Server.identity.primaryPort - ); - httpOrigin = `http://${altsvcHost}:${h1Server.identity.primaryPort}/`; - registerCleanupFunction(() => { - h1Server.stop(); - }); -} - -// Promise-backed base assumed available: -// class Http3CheckListener { ... } -// function createHttp3CheckListener(opts) { return { listener, promise }; } - -class SlowReceiverListener extends Http3CheckListener { - constructor( - { - expectedStatus = Cr.NS_OK, - expectedRoute = "", - expectedBytes = 10_000_000, - } = {}, - resolve, - reject - ) { - super({ expectedStatus, expectedRoute }, resolve, reject); - this.count = 0; - this.expectedBytes = expectedBytes; - } - - onDataAvailable(request, stream, off, cnt) { - this.onDataAvailableFired = true; - this.count += cnt; - read_stream(stream, cnt); - } - - onStopRequest(request, status) { - Assert.equal(status, this.expectedStatus); - Assert.equal(this.count, this.expectedBytes); - - let routed = "NA"; - try { - routed = request.getRequestHeader("Alt-Used"); - } catch (e) {} - dump(`routed is ${routed}\n`); - Assert.equal(routed, this.expectedRoute); - - if (Components.isSuccessCode(this.expectedStatus)) { - let httpVersion = ""; - try { - httpVersion = request.protocolVersion; - } catch (e) {} - Assert.equal(httpVersion, "h3"); - Assert.equal(this.onDataAvailableFired, true); - } - - // Resolve where run_next_test() used to be - this._resolve?.(request); - } -} - -function createSlowReceiverListener(options = {}) { - let resolve, reject; - const promise = new Promise((res, rej) => { - resolve = res; - reject = rej; - }); - const listener = new SlowReceiverListener(options, resolve, reject); - return { listener, promise }; -} - -// Test: slow receiver (suspend, then resume) -async function do_test_slow_receiver(httpsOrigin, h3Route) { - dump("do_test_slow_receiver()\n"); - - const chan = makeChan(httpsOrigin + "10000000"); - - const { listener, promise } = createSlowReceiverListener({ - expectedStatus: Cr.NS_OK, - expectedRoute: h3Route, - expectedBytes: 10_000_000, - }); - - chan.asyncOpen(listener); - - // Suspend immediately, then resume after 1s (replaces do_test_pending/do_timeout) - chan.suspend(); - await new Promise(r => do_timeout(1000, r)); - chan.resume(); - - // Wait for completion (used to be run_next_test/do_test_finished) - await promise; -} - -// Promise-backed listener for version fallback checks -class CheckFallbackListener { - constructor(resolve, reject) { - this._resolve = resolve; - this._reject = reject; - } - - onStartRequest(request) { - Assert.ok(request instanceof Ci.nsIHttpChannel); - Assert.equal(request.status, Cr.NS_OK); - Assert.equal(request.responseStatus, 200); - } - - onDataAvailable(request, stream, off, cnt) { - read_stream(stream, cnt); - } - - onStopRequest(request, status) { - Assert.equal(status, Cr.NS_OK); - - let routed = "NA"; - try { - routed = request.getRequestHeader("Alt-Used"); - } catch (e) {} - dump(`routed is ${routed}\n`); - Assert.equal(routed, "0"); - - let httpVersion = ""; - try { - httpVersion = request.protocolVersion; - } catch (e) {} - Assert.equal(httpVersion, "http/1.1"); - - // Resolve where run_next_test() used to be called - this._resolve?.(request); - } -} - -// Factory to create { listener, promise } -function createCheckFallbackListener() { - let resolve, reject; - const promise = new Promise((res, rej) => { - resolve = res; - reject = rej; - }); - const listener = new CheckFallbackListener(resolve, reject); - return { listener, promise }; -} - -// Server cancels request with VersionFallback. -async function do_test_version_fallback(httpsOrigin) { - dump("do_test_version_fallback()\n"); - - const chan = makeChan(httpsOrigin + "VersionFallback"); - const { listener, promise } = createCheckFallbackListener(); - - chan.asyncOpen(listener); - - await promise; -} diff --git a/netwerk/test/unit/test_http3.js b/netwerk/test/unit/test_http3.js @@ -1,18 +1,64 @@ "use strict"; -/* import-globals-from http3_common.js */ +const { HttpServer } = ChromeUtils.importESModule( + "resource://testing-common/httpd.sys.mjs" +); + +// Generate a post with known pre-calculated md5 sum. +function generateContent(size) { + let content = ""; + for (let i = 0; i < size; i++) { + content += "0"; + } + return content; +} + +let post = generateContent(10); // Max concurent stream number in neqo is 100. // Openning 120 streams will test queuing of streams. let number_of_parallel_requests = 120; +let h1Server = null; let h3Route; let httpsOrigin; +let httpOrigin; let h3AltSvc; let h3Port; -let h3ServerDomain; + let prefs; -add_setup(async function () { +let tests = [ + // This test must be the first because it setsup alt-svc connection, that + // other tests use. + test_https_alt_svc, + test_multiple_requests, + test_request_cancelled_by_server, + test_stream_cancelled_by_necko, + test_multiple_request_one_is_cancelled, + test_multiple_request_one_is_cancelled_by_necko, + test_post, + test_patch, + test_http_alt_svc, + test_slow_receiver, + // This test should be at the end, because it will close http3 + // connection and the transaction will switch to already existing http2 + // connection. + // TODO: Bug 1582667 should try to fix issue with connection being closed. + test_version_fallback, + 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 h2Port = Services.env.get("MOZHTTP2_PORT"); Assert.notEqual(h2Port, null); Assert.notEqual(h2Port, ""); @@ -20,21 +66,185 @@ add_setup(async function () { Assert.notEqual(h3Port, null); Assert.notEqual(h3Port, ""); h3AltSvc = ":" + h3Port; - h3ServerDomain = "foo.example.com"; - h3Route = `${h3ServerDomain}:${h3Port}`; + + h3Route = "foo.example.com:" + h3Port; do_get_profile(); prefs = Services.prefs; prefs.setBoolPref("network.http.http3.enable", true); - prefs.setCharPref( - "network.dns.localDomains", - "foo.example.com, alt1.example.com" - ); + prefs.setCharPref("network.dns.localDomains", "foo.example.com"); // We always resolve elements of localDomains as it's hardcoded without the // following pref: prefs.setBoolPref("network.proxy.allow_hijacking_localhost", true); prefs.setBoolPref("network.http.altsvc.oe", 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:" + h2Port + "/"; + + h1Server = new HttpServer(); + h1Server.registerPathHandler("/http3-test", h1Response); + h1Server.registerPathHandler("/.well-known/http-opportunistic", h1ServerWK); + h1Server.registerPathHandler("/VersionFallback", h1Response); + h1Server.start(-1); + h1Server.identity.setPrimary( + "http", + "foo.example.com", + h1Server.identity.primaryPort + ); + httpOrigin = "http://foo.example.com:" + h1Server.identity.primaryPort + "/"; + + run_next_test(); +} + +function h1Response(metadata, response) { + response.setStatusLine(metadata.httpVersion, 200, "OK"); + response.setHeader("Content-Type", "text/plain", false); + response.setHeader("Connection", "close", false); + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Access-Control-Allow-Origin", "*", false); + response.setHeader("Access-Control-Allow-Method", "GET", false); + response.setHeader("Access-Control-Allow-Headers", "x-altsvc", false); + + try { + let hval = "h3=" + metadata.getHeader("x-altsvc"); + response.setHeader("Alt-Svc", hval, false); + } catch (e) {} + + let body = "Q: What did 0 say to 8? A: Nice Belt!\n"; + response.bodyOutputStream.write(body, body.length); +} + +function h1ServerWK(metadata, response) { + response.setStatusLine(metadata.httpVersion, 200, "OK"); + response.setHeader("Content-Type", "application/json", false); + response.setHeader("Connection", "close", false); + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Access-Control-Allow-Origin", "*", false); + response.setHeader("Access-Control-Allow-Method", "GET", false); + response.setHeader("Access-Control-Allow-Headers", "x-altsvc", false); + + let body = '["http://foo.example.com:' + h1Server.identity.primaryPort + '"]'; + response.bodyOutputStream.write(body, body.length); +} + +function makeChan(uri) { + let chan = NetUtil.newChannel({ + uri, + loadUsingSystemPrincipal: true, + }).QueryInterface(Ci.nsIHttpChannel); + chan.loadFlags = Ci.nsIChannel.LOAD_INITIAL_DOCUMENT_URI; + return chan; +} + +let Http3CheckListener = function () {}; + +Http3CheckListener.prototype = { + onDataAvailableFired: false, + expectedStatus: Cr.NS_OK, + expectedRoute: "", + + 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.onDataAvailableFired = true; + read_stream(stream, cnt); + }, + + onStopRequest: function testOnStopRequest(request, status) { + Assert.equal(status, this.expectedStatus); + let routed = "NA"; + try { + routed = request.getRequestHeader("Alt-Used"); + } catch (e) {} + dump("routed is " + routed + "\n"); + + Assert.equal(routed, this.expectedRoute); + + if (Components.isSuccessCode(this.expectedStatus)) { + let httpVersion = ""; + try { + httpVersion = request.protocolVersion; + } catch (e) {} + Assert.equal(httpVersion, "h3"); + Assert.equal(this.onDataAvailableFired, true); + Assert.equal(request.getResponseHeader("X-Firefox-Http3"), "h3"); + } + run_next_test(); + do_test_finished(); + }, +}; + +let WaitForHttp3Listener = function () {}; + +WaitForHttp3Listener.prototype = new Http3CheckListener(); + +WaitForHttp3Listener.prototype.uri = ""; +WaitForHttp3Listener.prototype.h3AltSvc = ""; + +WaitForHttp3Listener.prototype.onStopRequest = function testOnStopRequest( + request, + status +) { + Assert.equal(status, this.expectedStatus); + + let routed = "NA"; + try { + routed = request.getRequestHeader("Alt-Used"); + } catch (e) {} + dump("routed is " + routed + "\n"); + + let httpVersion = ""; + try { + httpVersion = request.protocolVersion; + } catch (e) {} + + if (routed == this.expectedRoute) { + Assert.equal(routed, this.expectedRoute); // always true, but a useful log + Assert.equal(httpVersion, "h3"); + run_next_test(); + } else { + dump("poll later for alt svc mapping\n"); + if (httpVersion == "h2") { + request.QueryInterface(Ci.nsIHttpChannelInternal); + Assert.ok(request.supportsHTTP3); + } + do_test_pending(); + do_timeout(500, () => { + doTest(this.uri, this.expectedRoute, this.h3AltSvc); + }); + } + + do_test_finished(); +}; + +function doTest(uri, expectedRoute, altSvc) { + let chan = makeChan(uri); + let listener = new WaitForHttp3Listener(); + listener.uri = uri; + listener.expectedRoute = expectedRoute; + listener.h3AltSvc = altSvc; + chan.setRequestHeader("x-altsvc", altSvc, false); + chan.asyncOpen(listener); +} + +// Test Alt-Svc for http3. +// H2 server returns alt-svc=h3=:h3port +function test_https_alt_svc() { + dump("test_https_alt_svc()\n"); + do_test_pending(); if (mozinfo.os == "android") { // Set necessary prefs to make Firefox connect to the http3Server on the // host machine. @@ -42,99 +252,341 @@ add_setup(async function () { const overrideService = Cc[ "@mozilla.org/network/native-dns-override;1" ].getService(Ci.nsINativeDNSResolverOverride); - overrideService.addIPOverride(h3ServerDomain, "10.0.2.2"); + overrideService.addIPOverride("foo.example.com", "10.0.2.2"); prefs.setCharPref( "network.http.http3.alt-svc-mapping-for-testing", - `${h3ServerDomain};h3=:${h3Port}` + `foo.example.com;h3=:${h3Port}` ); } + doTest(httpsOrigin + "http3-test", h3Route, h3AltSvc); +} - // 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://${h3ServerDomain}:${h2Port}/`; - - registerCleanupFunction(() => { - prefs.clearUserPref("network.http.http3.enable"); - prefs.clearUserPref("network.dns.localDomains"); - prefs.clearUserPref("network.proxy.allow_hijacking_localhost"); - prefs.clearUserPref("network.http.altsvc.oe"); - }); -}); - -add_task(async function test_https_alt_svc() { - await waitForHttp3Route(httpsOrigin + "http3-test", h3Route, h3AltSvc, { - delayMs: 500, - }); -}); - -add_task(async function test_multiple_requests() { - await do_test_multiple_requests( - number_of_parallel_requests, - h3Route, - httpsOrigin - ); -}); +// Listener for a number of parallel requests. if with_error is set, one of +// the channels will be cancelled (by the server or in onStartRequest). +let MultipleListener = function () {}; -add_task(async function test_request_cancelled_by_server() { - await do_test_request_cancelled_by_server(h3Route, httpsOrigin); -}); +MultipleListener.prototype = { + number_of_parallel_requests: 0, + with_error: Cr.NS_OK, + count_of_done_requests: 0, + error_found_onstart: false, + error_found_onstop: false, + need_cancel_found: false, -add_task(async function test_stream_cancelled_by_necko() { - await do_test_stream_cancelled_by_necko(h3Route, httpsOrigin); -}); + onStartRequest: function testOnStartRequest(request) { + Assert.ok(request instanceof Ci.nsIHttpChannel); -add_task(async function test_multiple_request_one_is_cancelled() { - await do_test_multiple_request_one_is_cancelled( - number_of_parallel_requests, - h3Route, - httpsOrigin - ); -}); + let need_cancel = ""; + try { + need_cancel = request.getRequestHeader("CancelMe"); + } catch (e) {} + if (need_cancel != "") { + this.need_cancel_found = true; + request.cancel(Cr.NS_ERROR_ABORT); + } else if (Components.isSuccessCode(request.status)) { + Assert.equal(request.responseStatus, 200); + } else if (this.error_found_onstart) { + do_throw("We should have only one request failing."); + } else { + Assert.equal(request.status, this.with_error); + this.error_found_onstart = true; + } + }, -add_task(async function test_multiple_request_one_is_cancelled_by_necko() { - await do_test_multiple_request_one_is_cancelled_by_necko( - number_of_parallel_requests, - h3Route, - httpsOrigin - ); -}); - -add_task(async function test_post() { - await do_test_post(httpsOrigin, h3Route); -}); - -add_task(async function test_patch() { - await do_test_patch(httpsOrigin, h3Route); -}); - -add_task( - { - // Skip this test on Android because the httpOrigin (http://foo.example.com) - // is on 127.0.0.1, while the http3Server (https://foo.example.com) is - // on 10.0.2.2. Currently, we can't change the IP mapping dynamically. - skip_if: () => mozinfo.os == "android", + onDataAvailable: function testOnDataAvailable(request, stream, off, cnt) { + read_stream(stream, cnt); }, - async function test_http_alt_svc() { - setup_h1_server(h3ServerDomain); - await waitForHttp3Route(httpOrigin + "http3-test", h3Route, h3AltSvc, { - delayMs: 500, - }); + + onStopRequest: function testOnStopRequest(request) { + let routed = ""; + try { + routed = request.getRequestHeader("Alt-Used"); + } catch (e) {} + Assert.equal(routed, this.expectedRoute); + + if (Components.isSuccessCode(request.status)) { + let httpVersion = ""; + try { + httpVersion = request.protocolVersion; + } catch (e) {} + Assert.equal(httpVersion, "h3"); + } + + if (!Components.isSuccessCode(request.status)) { + if (this.error_found_onstop) { + do_throw("We should have only one request failing."); + } else { + Assert.equal(request.status, this.with_error); + this.error_found_onstop = true; + } + } + this.count_of_done_requests++; + if (this.count_of_done_requests == this.number_of_parallel_requests) { + if (Components.isSuccessCode(this.with_error)) { + Assert.equal(this.error_found_onstart, false); + Assert.equal(this.error_found_onstop, false); + } else { + Assert.ok(this.error_found_onstart || this.need_cancel_found); + Assert.equal(this.error_found_onstop, true); + } + run_next_test(); + } + do_test_finished(); + }, +}; + +// Multiple requests +function test_multiple_requests() { + dump("test_multiple_requests()\n"); + + let listener = new MultipleListener(); + listener.number_of_parallel_requests = number_of_parallel_requests; + listener.expectedRoute = h3Route; + + for (let i = 0; i < number_of_parallel_requests; i++) { + let chan = makeChan(httpsOrigin + "20000"); + chan.asyncOpen(listener); + do_test_pending(); } -); +} + +// A request cancelled by a server. +function test_request_cancelled_by_server() { + dump("test_request_cancelled_by_server()\n"); + + let listener = new Http3CheckListener(); + listener.expectedStatus = Cr.NS_ERROR_NET_INTERRUPT; + listener.expectedRoute = h3Route; + let chan = makeChan(httpsOrigin + "RequestCancelled"); + chan.asyncOpen(listener); + do_test_pending(); +} + +let CancelRequestListener = function () {}; + +CancelRequestListener.prototype = new Http3CheckListener(); + +CancelRequestListener.prototype.expectedStatus = Cr.NS_ERROR_ABORT; + +CancelRequestListener.prototype.onStartRequest = function testOnStartRequest( + request +) { + Assert.ok(request instanceof Ci.nsIHttpChannel); + + Assert.equal(Components.isSuccessCode(request.status), true); + request.cancel(Cr.NS_ERROR_ABORT); +}; + +// Cancel stream after OnStartRequest. +function test_stream_cancelled_by_necko() { + dump("test_stream_cancelled_by_necko()\n"); + + let listener = new CancelRequestListener(); + listener.expectedRoute = h3Route; + let chan = makeChan(httpsOrigin + "20000"); + chan.asyncOpen(listener); + do_test_pending(); +} + +// Multiple requests, one gets cancelled by the server, the other should finish normally. +function test_multiple_request_one_is_cancelled() { + dump("test_multiple_request_one_is_cancelled()\n"); + + let listener = new MultipleListener(); + listener.number_of_parallel_requests = number_of_parallel_requests; + listener.with_error = Cr.NS_ERROR_NET_INTERRUPT; + listener.expectedRoute = h3Route; + + for (let i = 0; i < number_of_parallel_requests; i++) { + let uri = httpsOrigin + "20000"; + if (i == 4) { + // Add a request that will be cancelled by the server. + uri = httpsOrigin + "RequestCancelled"; + } + let chan = makeChan(uri); + chan.asyncOpen(listener); + do_test_pending(); + } +} + +// Multiple requests, one gets cancelled by us, the other should finish normally. +function test_multiple_request_one_is_cancelled_by_necko() { + dump("test_multiple_request_one_is_cancelled_by_necko()\n"); + + let listener = new MultipleListener(); + listener.number_of_parallel_requests = number_of_parallel_requests; + listener.with_error = Cr.NS_ERROR_ABORT; + listener.expectedRoute = h3Route; + for (let i = 0; i < number_of_parallel_requests; i++) { + let chan = makeChan(httpsOrigin + "20000"); + if (i == 4) { + // MultipleListener will cancel request with this header. + chan.setRequestHeader("CancelMe", "true", false); + } + chan.asyncOpen(listener); + do_test_pending(); + } +} + +let PostListener = function () {}; + +PostListener.prototype = new Http3CheckListener(); + +PostListener.prototype.onDataAvailable = function (request, stream, off, cnt) { + this.onDataAvailableFired = true; + read_stream(stream, cnt); +}; + +// Support for doing a POST +function do_post(content, chan, listener, method) { + let stream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance( + Ci.nsIStringInputStream + ); + stream.setByteStringData(content); + + let uchan = chan.QueryInterface(Ci.nsIUploadChannel); + uchan.setUploadStream(stream, "text/plain", stream.available()); + + chan.requestMethod = method; + + chan.asyncOpen(listener); +} + +// Test a simple POST +function test_post() { + dump("test_post()"); + let chan = makeChan(httpsOrigin + "post"); + let listener = new PostListener(); + listener.expectedRoute = h3Route; + do_post(post, chan, listener, "POST"); + do_test_pending(); +} + +// Test a simple PATCH +function test_patch() { + dump("test_patch()"); + let chan = makeChan(httpsOrigin + "patch"); + let listener = new PostListener(); + listener.expectedRoute = h3Route; + do_post(post, chan, listener, "PATCH"); + do_test_pending(); +} + +// Test alt-svc for http (without s) +function test_http_alt_svc() { + dump("test_http_alt_svc()\n"); + // Skip this test on Android because the httpOrigin (http://foo.example.com) + // is on 127.0.0.1, while the http3Server (https://foo.example.com) is + // on 10.0.2.2. Currently, we can't change the IP mapping dynamically. + if (mozinfo.os == "android") { + current_test++; + run_next_test(); + return; + } + do_test_pending(); + doTest(httpOrigin + "http3-test", h3Route, h3AltSvc); +} + +let SlowReceiverListener = function () {}; + +SlowReceiverListener.prototype = new Http3CheckListener(); +SlowReceiverListener.prototype.count = 0; + +SlowReceiverListener.prototype.onDataAvailable = function ( + request, + stream, + off, + cnt +) { + this.onDataAvailableFired = true; + this.count += cnt; + read_stream(stream, cnt); +}; + +SlowReceiverListener.prototype.onStopRequest = function (request, status) { + Assert.equal(status, this.expectedStatus); + Assert.equal(this.count, 10000000); + let routed = "NA"; + try { + routed = request.getRequestHeader("Alt-Used"); + } catch (e) {} + dump("routed is " + routed + "\n"); + + Assert.equal(routed, this.expectedRoute); + + if (Components.isSuccessCode(this.expectedStatus)) { + let httpVersion = ""; + try { + httpVersion = request.protocolVersion; + } catch (e) {} + Assert.equal(httpVersion, "h3"); + Assert.equal(this.onDataAvailableFired, true); + } + run_next_test(); + do_test_finished(); +}; + +function test_slow_receiver() { + dump("test_slow_receiver()\n"); + let chan = makeChan(httpsOrigin + "10000000"); + let listener = new SlowReceiverListener(); + listener.expectedRoute = h3Route; + chan.asyncOpen(listener); + do_test_pending(); + chan.suspend(); + do_timeout(1000, chan.resume); +} + +let CheckFallbackListener = function () {}; + +CheckFallbackListener.prototype = { + onStartRequest: function testOnStartRequest(request) { + Assert.ok(request instanceof Ci.nsIHttpChannel); + + Assert.equal(request.status, Cr.NS_OK); + Assert.equal(request.responseStatus, 200); + }, + + onDataAvailable: function testOnDataAvailable(request, stream, off, cnt) { + read_stream(stream, cnt); + }, + + onStopRequest: function testOnStopRequest(request, status) { + Assert.equal(status, Cr.NS_OK); + let routed = "NA"; + try { + routed = request.getRequestHeader("Alt-Used"); + } catch (e) {} + dump("routed is " + routed + "\n"); + + Assert.equal(routed, "0"); + + let httpVersion = ""; + try { + httpVersion = request.protocolVersion; + } catch (e) {} + Assert.equal(httpVersion, "http/1.1"); + run_next_test(); + do_test_finished(); + }, +}; + +// Server cancels request with VersionFallback. +function test_version_fallback() { + dump("test_version_fallback()\n"); + + let chan = makeChan(httpsOrigin + "VersionFallback"); + let listener = new CheckFallbackListener(); + chan.asyncOpen(listener); + do_test_pending(); +} -add_task(async function test_slow_receiver() { - await do_test_slow_receiver(httpsOrigin, h3Route); -}); - -// This test should be at the end, because it will close http3 -// connection and the transaction will switch to already existing http2 -// connection. -// TODO: Bug 1582667 should try to fix issue with connection being closed. -add_task(async function test_version_fallback() { - await do_test_version_fallback(httpsOrigin); -}); +function testsDone() { + prefs.clearUserPref("network.http.http3.enable"); + prefs.clearUserPref("network.dns.localDomains"); + prefs.clearUserPref("network.proxy.allow_hijacking_localhost"); + prefs.clearUserPref("network.http.altsvc.oe"); + dump("testDone\n"); + do_test_pending(); + h1Server.stop(do_test_finished); +} diff --git a/netwerk/test/unit/test_http3_with_proxy.js b/netwerk/test/unit/test_http3_with_proxy.js @@ -1,180 +0,0 @@ -"use strict"; - -/* import-globals-from http3_common.js */ - -const { Http3ProxyFilter, NodeHTTP2ProxyServer } = ChromeUtils.importESModule( - "resource://testing-common/NodeServer.sys.mjs" -); - -// Max concurent stream number in neqo is 100. -// Openning 120 streams will test queuing of streams. -let number_of_parallel_requests = 120; -let h3Route; -let httpsOrigin; -let h3AltSvc; -let h3Port; -let h3ServerDomain; -let prefs; - -let pps = Cc["@mozilla.org/network/protocol-proxy-service;1"].getService(); -let proxyHost; -let proxyPort; -let proxyFilter; - -add_setup(async function () { - let h2Port = Services.env.get("MOZHTTP2_PORT"); - Assert.notEqual(h2Port, null); - Assert.notEqual(h2Port, ""); - h3Port = Services.env.get("MOZHTTP3_PORT"); - Assert.notEqual(h3Port, null); - Assert.notEqual(h3Port, ""); - h3AltSvc = ":" + h3Port; - h3ServerDomain = "foo.example.com"; - h3Route = `${h3ServerDomain}:${h3Port}`; - do_get_profile(); - prefs = Services.prefs; - - prefs.setBoolPref("network.http.http3.enable", true); - // We always resolve elements of localDomains as it's hardcoded without the - // following pref: - prefs.setBoolPref("network.proxy.allow_hijacking_localhost", true); - prefs.setBoolPref("network.http.altsvc.oe", true); - - if (mozinfo.os == "android") { - // Set necessary prefs to make Firefox connect to the http3Server on the - // host machine. - prefs.setCharPref("network.dns.localDomains", ""); - const overrideService = Cc[ - "@mozilla.org/network/native-dns-override;1" - ].getService(Ci.nsINativeDNSResolverOverride); - overrideService.addIPOverride(h3ServerDomain, "10.0.2.2"); - prefs.setCharPref( - "network.http.http3.alt-svc-mapping-for-testing", - `${h3ServerDomain};h3=:${h3Port}` - ); - } else { - prefs.setCharPref( - "network.dns.localDomains", - "foo.example.com, alt1.example.com" - ); - } - - // 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"); - addCertFromFile(certdb, "proxy-ca.pem", "CTu,u,u"); - httpsOrigin = `https://${h3ServerDomain}:${h2Port}/`; - - proxyHost = "alt1.example.com"; - proxyPort = Services.env.get("MOZHTTP3_PORT_MASQUE"); - Assert.notEqual(proxyPort, null); - Assert.notEqual(proxyPort, ""); - proxyFilter = new Http3ProxyFilter( - proxyHost, - proxyPort, - 0, - "/.well-known/masque/udp/{target_host}/{target_port}/", - "" - ); - pps.registerFilter(proxyFilter, 10); - - registerCleanupFunction(() => { - prefs.clearUserPref("network.http.http3.enable"); - prefs.clearUserPref("network.dns.localDomains"); - prefs.clearUserPref("network.proxy.allow_hijacking_localhost"); - prefs.clearUserPref("network.http.altsvc.oe"); - prefs.clearUserPref("network.http.http3.alt-svc-mapping-for-testing"); - pps.unregisterFilter(proxyFilter); - if (mozinfo.os == "android") { - const overrideService = Cc[ - "@mozilla.org/network/native-dns-override;1" - ].getService(Ci.nsINativeDNSResolverOverride); - overrideService.clearOverrides(); - } - }); -}); - -add_task(async function test_https_alt_svc() { - await waitForHttp3Route(httpsOrigin + "http3-test", h3Route, h3AltSvc, { - delayMs: 500, - }); -}); - -add_task(async function test_multiple_requests() { - await do_test_multiple_requests( - number_of_parallel_requests, - h3Route, - httpsOrigin - ); -}); - -add_task(async function test_request_cancelled_by_server() { - await do_test_request_cancelled_by_server(h3Route, httpsOrigin); -}); - -add_task(async function test_stream_cancelled_by_necko() { - await do_test_stream_cancelled_by_necko(h3Route, httpsOrigin); -}); - -add_task(async function test_multiple_request_one_is_cancelled() { - await do_test_multiple_request_one_is_cancelled( - number_of_parallel_requests, - h3Route, - httpsOrigin - ); -}); - -add_task(async function test_multiple_request_one_is_cancelled_by_necko() { - await do_test_multiple_request_one_is_cancelled_by_necko( - number_of_parallel_requests, - h3Route, - httpsOrigin - ); -}); - -add_task(async function test_post() { - await do_test_post(httpsOrigin, h3Route); -}); - -add_task(async function test_patch() { - await do_test_patch(httpsOrigin, h3Route); -}); - -add_task( - { - // Skip this test on Android because the httpOrigin (http://foo.example.com) - // is on 127.0.0.1, while the http3Server (https://foo.example.com) is - // on 10.0.2.2. Currently, we can't change the IP mapping dynamically. - skip_if: () => mozinfo.os == "android", - }, - async function test_http_alt_svc() { - setup_h1_server(h3ServerDomain); - await waitForHttp3Route(httpOrigin + "http3-test", h3Route, h3AltSvc, { - delayMs: 500, - }); - } -); - -add_task(async function test_slow_receiver() { - await do_test_slow_receiver(httpsOrigin, h3Route); -}); - -// This test should be at the end, because it will close http3 -// connection and the transaction will switch to already existing http2 -// connection. -// TODO: Bug 1582667 should try to fix issue with connection being closed. -add_task(async function test_version_fallback() { - let proxy = new NodeHTTP2ProxyServer(); - await proxy.startWithoutProxyFilter(proxyPort); - registerCleanupFunction(async () => { - await proxy.stop(); - }); - Assert.equal(proxyPort, proxy.port()); - info(`proxy port=${proxy.port()}\n`); - - await do_test_version_fallback(httpsOrigin); -}); diff --git a/netwerk/test/unit/xpcshell.toml b/netwerk/test/unit/xpcshell.toml @@ -27,7 +27,6 @@ support-files = [ "test_http3_prio_helpers.js", "http2_test_common.js", "http3_proxy_common.js", - "http3_common.js", ] # dom.serviceWorkers.enabled is currently set to false in StaticPrefList.yaml @@ -710,17 +709,6 @@ run-sequentially = ["true"] # node server exceptions dont replay well head = "head_channels.js head_cache.js head_cookies.js head_trr.js head_http3.js http2_test_common.js" ["test_http3.js"] -head = "head_cookies.js head_channels.js head_cache.js head_http3.js http3_common.js" -run-sequentially = ["true"] # http3server -skip-if = [ - "os == 'android' && os_version == '14' && processor == 'x86_64'", # Bug 1982955 - "os == 'win' && os_version == '10.2009' && processor == 'x86_64'", # Bug 1807931 - "os == 'win' && os_version == '11.26100' && processor == 'x86'", # Bug 1807931 - "os == 'win' && os_version == '11.26100' && processor == 'x86_64' && msix", # Bug 1807931 -] - -["test_http3_with_proxy.js"] -head = "head_cookies.js head_channels.js head_cache.js head_http3.js http3_common.js" run-sequentially = ["true"] # http3server skip-if = [ "os == 'android' && os_version == '14' && processor == 'x86_64'", # Bug 1982955