Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/netwerk/test/unit/   (Firefox Browser Version 153.0.1©)  Datei vom 27.6.2026 mit Größe 6 kB image not shown  

Quelle  test_happy_eyeballs_h3_0rtt.js   Sprache: JAVA

 

/* 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/. */


// Verifies the Happy Eyeballs HTTP/3 0-RTT-accepted code path against
// the Neqo HTTP/3 test server. Mirrors test_happy_eyeballs_h2_0rtt.js
// but for h3:
//  * Second fetch resumes with 0-RTT (securityInfo.resumed == true)
//    and still returns 200.
//  * Protocol negotiates to h3 on both fetches.
//
// http3_setup_tests("h3") points foo.example.com at the H3 test server
// via alt-svc and sets network.dns.disableIPv6 = true so HE only races
// IPv4 attempts against the single-use session ticket.

"use strict";

const { HTTP3Server } = ChromeUtils.importESModule(
  "resource://testing-common/NodeServer.sys.mjs"
);

var { setTimeout } = ChromeUtils.importESModule(
  "resource://gre/modules/Timer.sys.mjs"
);

const override = Cc["@mozilla.org/network/native-dns-override;1"].getService(
  Ci.nsINativeDNSResolverOverride
);

let server;
let h3Port;

registerCleanupFunction(async () => {
  http3_clear_prefs();
  Services.prefs.clearUserPref("network.http.happy_eyeballs_enabled");
  Services.prefs.clearUserPref("network.http.speculative-parallel-limit");
  Services.prefs.clearUserPref("network.http.http3.enable_0rtt");
  override.clearOverrides();
  await server.stop();
});

add_task(async function setup() {
  Services.prefs.setBoolPref("network.http.happy_eyeballs_enabled", true);
  Services.prefs.setIntPref("network.http.speculative-parallel-limit", 0);
  Services.prefs.setBoolPref("network.http.http3.enable_0rtt", true);

  let h3ServerPath = Services.env.get("MOZ_HTTP3_SERVER_PATH");
  let h3DBPath = Services.env.get("MOZ_HTTP3_CERT_DB_PATH");

  let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService(
    Ci.nsIX509CertDB
  );
  addCertFromFile(certdb, "http2-ca.pem", "CTu,u,u");

  server = new HTTP3Server();
  await server.start(h3ServerPath, h3DBPath);
  h3Port = server.port();
  Services.prefs.setCharPref(
    "network.http.http3.alt-svc-mapping-for-testing",
    `foo.example.com;h3=:${h3Port}`
  );

  override.addIPOverride("foo.example.com", "127.0.0.1");
});

function openChan(uri) {
  return new Promise(resolve => {
    let chan = NetUtil.newChannel({
      uri,
      loadUsingSystemPrincipal: true,
    }).QueryInterface(Ci.nsIHttpChannel);
    chan.loadFlags = Ci.nsIChannel.LOAD_INITIAL_DOCUMENT_URI;
    chan.asyncOpen(
      new ChannelListener(
        req => {
          let httpChan = req.QueryInterface(Ci.nsIHttpChannel);
          let resumed = false;
          try {
            resumed = req.securityInfo.resumed;
          } catch (e) {}
          resolve({
            status: httpChan.responseStatus,
            protocol: httpChan.protocolVersion,
            resumed,
          });
        },
        null,
        CL_ALLOW_UNKNOWN_CL
      )
    );
  });
}

// Like openChan but resolves on both success and failure.
function openChanMayFail(uri) {
  const chan = NetUtil.newChannel({
    uri,
    loadUsingSystemPrincipal: true,
  }).QueryInterface(Ci.nsIHttpChannel);
  chan.loadFlags = Ci.nsIChannel.LOAD_INITIAL_DOCUMENT_URI;
  const promise = new Promise(resolve => {
    chan.asyncOpen({
      onStartRequest() {},
      onDataAvailable(_req, stream, _offset, count) {
        read_stream(stream, count);
      },
      onStopRequest(_req, status) {
        resolve(status);
      },
      QueryInterface: ChromeUtils.generateQI(["nsIStreamListener"]),
    });
  });
  return { chan, promise };
}

add_task(async function test_he_h3_0rtt_resumes() {
  const url = "https://foo.example.com/30";

  let r1 = await openChan(url);
  Assert.equal(r1.status, 200, "First fetch should succeed");
  Assert.equal(r1.protocol, "h3", "First fetch should be h3");
  Assert.equal(r1.resumed, false, "First fetch should not be resumed");

  // Let the NewSessionTicket arrive and be cached before we tear down
  // the connection.
  // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
  await new Promise(resolve => setTimeout(resolve, 1000));

  Services.obs.notifyObservers(null, "net:cancel-all-connections");
  // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
  await new Promise(resolve => setTimeout(resolve, 1000));

  let r2 = await openChan(url);
  Assert.equal(r2.status, 200, "Second fetch should succeed");
  Assert.equal(r2.protocol, "h3", "Second fetch should be h3");
  Assert.equal(r2.resumed, true, "Second fetch should resume via 0-RTT");
});

// Verifies that when ZeroRttHandle::Finish0RTT sees a null real transaction.
add_task(async function test_he_h3_0rtt_txn_gone_closes_connection() {
  const url = "https://foo.example.com/30";

  // Establish a fresh H3 connection and obtain a session ticket so the next
  // request can attempt 0-RTT.
  let r1 = await openChan(url);
  Assert.equal(r1.status, 200, "warm-up request should succeed");
  Assert.equal(r1.protocol, "h3", "warm-up request should be h3");

  // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
  await new Promise(resolve => setTimeout(resolve, 1000));
  Services.obs.notifyObservers(null, "net:cancel-all-connections");
  // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
  await new Promise(resolve => setTimeout(resolve, 500));

  Services.prefs.setBoolPref(
    "network.http.0rtt_force_txn_gone_for_testing",
    true
  );

  const { promise: failPromise } = openChanMayFail(url);
  const failStatus = await failPromise;
  Assert.equal(
    failStatus,
    Cr.NS_ERROR_ABORT,
    "request with forced-null txn should be aborted cleanly"
  );

  Services.prefs.clearUserPref("network.http.0rtt_force_txn_gone_for_testing");

  // Allow the closed connection to be fully torn down before retrying.
  Services.obs.notifyObservers(null, "net:cancel-all-connections");
  // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
  await new Promise(resolve => setTimeout(resolve, 500));

  // The networking stack must still be functional after the forced close.
  let r3 = await openChan(url);
  Assert.equal(r3.status, 200, "recovery request should succeed");
  Assert.equal(r3.protocol, "h3", "recovery request should be h3");
});

Messung V0.5 in Prozent
C=85 H=100 G=92

¤ Dauer der Verarbeitung: 0.30 Sekunden  (vorverarbeitet am  2026-09-29) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.