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 10 kB image not shown  

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


"use strict";

const { AppConstants } = ChromeUtils.importESModule(
  "resource://gre/modules/AppConstants.sys.mjs"
);

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

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

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

const mockController = Cc[
  "@mozilla.org/network/mock-network-controller;1"
].getService(Ci.nsIMockNetworkLayerController);

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

add_setup(function () {
  Services.prefs.setBoolPref("network.http.happy_eyeballs_enabled", true);
  Services.prefs.setBoolPref("network.socket.attach_mock_network_layer", true);
  registerCleanupFunction(() => {
    Services.prefs.clearUserPref("network.http.happy_eyeballs_enabled");
    Services.prefs.clearUserPref("network.socket.attach_mock_network_layer");
    Services.prefs.clearUserPref("network.http.speculative-parallel-limit");
    override.clearOverrides();
    mockController.clearBlockedTCPConnect();
    mockController.clearPausedTCPConnect();
  });
});

async function openChan(uri) {
  let chan = NetUtil.newChannel({
    uri,
    loadUsingSystemPrincipal: true,
  }).QueryInterface(Ci.nsIHttpChannel);
  chan.loadFlags = Ci.nsIChannel.LOAD_INITIAL_DOCUMENT_URI;

  let result = await new Promise(resolve => {
    chan.asyncOpen(
      new ChannelListener(
        (r, b) => resolve({ req: r, buffer: b }),
        null,
        CL_ALLOW_UNKNOWN_CL
      )
    );
  });

  return {
    addr: result.req.QueryInterface(Ci.nsIHttpChannelInternal).remoteAddress,
    status: result.req.QueryInterface(Ci.nsIHttpChannel).responseStatus,
    buffer: result.buffer,
  };
}

async function resetConnections() {
  Services.obs.notifyObservers(null, "net:cancel-all-connections");
  let nssComponent = Cc["@mozilla.org/psm;1"].getService(Ci.nsINSSComponent);
  await nssComponent.asyncClearSSLExternalAndInternalSessionCache();
  override.clearOverrides();
  mockController.clearBlockedTCPConnect();
  mockController.clearPausedTCPConnect();
  Services.dns.clearCache(true);
  // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
  await new Promise(resolve => setTimeout(resolve, 1000));
}

async function do_test_first_attempt_succeeds(host) {
  await resetConnections();

  let server = new NodeHTTPSServer();
  await server.start();
  await server.registerPathHandler("/test", (_req, resp) => {
    resp.writeHead(200, { "Content-Type": "text/plain" });
    resp.end("ok");
  });

  let port = server.port();

  // Set up DNS to return both IPv6 and IPv4. IPv6 is preferred and should
  // succeed on the first attempt.
  override.addIPOverride(host, "::1");
  override.addIPOverride(host, "127.0.0.1");

  let { status, buffer } = await openChan(`https://${host}:${port}/test`);

  Assert.equal(status, 200, "Request should succeed");
  Assert.equal(buffer, "ok", "Response body should match");

  await server.stop();
}

// Test first connection attempt succeeds, speculative disabled.
add_task(async function test_first_attempt_succeeds_no_speculative() {
  Services.prefs.setIntPref("network.http.speculative-parallel-limit", 0);
  await do_test_first_attempt_succeeds("foo.example.com");
});

// Test first connection attempt succeeds, speculative enabled.
add_task(async function test_first_attempt_succeeds_with_speculative() {
  Services.prefs.setIntPref("network.http.speculative-parallel-limit", 6);
  await do_test_first_attempt_succeeds("foo.example.com");
});

async function do_test_first_attempt_fails(host) {
  await resetConnections();

  let server = new NodeHTTPSServer();
  await server.start();
  await server.registerPathHandler("/test", (_req, resp) => {
    resp.writeHead(200, { "Content-Type": "text/plain" });
    resp.end("ok");
  });

  let port = server.port();

  // Set up DNS to return both IPv6 and IPv4.
  override.addIPOverride(host, "::1");
  override.addIPOverride(host, "127.0.0.1");

  // Block TCP connect on the IPv6 address to force connection refused.
  let blockedAddr = mockController.createScriptableNetAddr("::1", port);
  mockController.blockTCPConnect(blockedAddr);

  let { addr, status, buffer } = await openChan(`https://${host}:${port}/test`);

  Assert.equal(status, 200, "Request should succeed");
  Assert.equal(buffer, "ok", "Response body should match");
  Assert.equal(
    addr,
    "127.0.0.1",
    "Should fall back to IPv4 after IPv6 failure"
  );

  await server.stop();
}

// Test fallback with speculative connections disabled.
add_task(async function test_first_attempt_fails_no_speculative() {
  Services.prefs.setIntPref("network.http.speculative-parallel-limit", 0);
  await do_test_first_attempt_fails("alt1.example.com");
});

// Test fallback with speculative connections enabled.
add_task(async function test_first_attempt_fails_with_speculative() {
  Services.prefs.setIntPref("network.http.speculative-parallel-limit", 6);
  await do_test_first_attempt_fails("alt1.example.com");
});

async function do_test_first_attempt_slow(host) {
  await resetConnections();

  let server = new NodeHTTPSServer();
  await server.start();
  await server.registerPathHandler("/test", (_req, resp) => {
    resp.writeHead(200, { "Content-Type": "text/plain" });
    resp.end("ok");
  });

  let port = server.port();

  // Set up DNS to return both IPv6 and IPv4.
  override.addIPOverride(host, "::1");
  override.addIPOverride(host, "127.0.0.1");

  // Pause TCP connect on the IPv6 address so it hangs indefinitely.
  let pausedAddr = mockController.createScriptableNetAddr("::1", port);
  mockController.pauseTCPConnect(pausedAddr);

  let { addr, status, buffer } = await openChan(`https://${host}:${port}/test`);

  Assert.equal(status, 200, "Request should succeed");
  Assert.equal(buffer, "ok", "Response body should match");
  Assert.equal(addr, "127.0.0.1", "Should fall back to IPv4 after IPv6 hangs");

  await server.stop();
}

async function do_test_all_attempts_fail(host) {
  await resetConnections();

  let server = new NodeHTTPSServer();
  await server.start();
  await server.registerPathHandler("/test", (_req, resp) => {
    resp.writeHead(200, { "Content-Type": "text/plain" });
    resp.end("ok");
  });

  let port = server.port();

  // Set up DNS to return both IPv6 and IPv4.
  override.addIPOverride(host, "::1");
  override.addIPOverride(host, "127.0.0.1");

  // Block TCP connect on both addresses so all attempts fail.
  let blockedAddr6 = mockController.createScriptableNetAddr("::1", port);
  mockController.blockTCPConnect(blockedAddr6);
  let blockedAddr4 = mockController.createScriptableNetAddr("127.0.0.1", port);
  mockController.blockTCPConnect(blockedAddr4);

  let chan = NetUtil.newChannel({
    uri: `https://${host}:${port}/test`,
    loadUsingSystemPrincipal: true,
  }).QueryInterface(Ci.nsIHttpChannel);
  chan.loadFlags = Ci.nsIChannel.LOAD_INITIAL_DOCUMENT_URI;

  await new Promise(resolve => {
    chan.asyncOpen(
      new ChannelListener(() => resolve(), null, CL_EXPECT_FAILURE)
    );
  });

  Assert.equal(
    chan.status,
    Cr.NS_ERROR_CONNECTION_REFUSED,
    "Should fail with connection refused"
  );

  await server.stop();
}

// Test all attempts fail, speculative disabled.
add_task(async function test_all_attempts_fail_no_speculative() {
  Services.prefs.setIntPref("network.http.speculative-parallel-limit", 0);
  await do_test_all_attempts_fail("alt1.example.com");
});

// Test all attempts fail, speculative enabled.
add_task(async function test_all_attempts_fail_with_speculative() {
  Services.prefs.setIntPref("network.http.speculative-parallel-limit", 6);
  await do_test_all_attempts_fail("alt1.example.com");
});

async function do_test_cancel_during_connection(host) {
  await resetConnections();

  let server = new NodeHTTPSServer();
  await server.start();
  await server.registerPathHandler("/test", (_req, resp) => {
    resp.writeHead(200, { "Content-Type": "text/plain" });
    resp.end("ok");
  });

  let port = server.port();

  override.addIPOverride(host, "::1");
  override.addIPOverride(host, "127.0.0.1");

  // Pause TCP connect on both addresses so connections hang.
  let pausedAddr6 = mockController.createScriptableNetAddr("::1", port);
  mockController.pauseTCPConnect(pausedAddr6);
  let pausedAddr4 = mockController.createScriptableNetAddr("127.0.0.1", port);
  mockController.pauseTCPConnect(pausedAddr4);

  let chan = NetUtil.newChannel({
    uri: `https://${host}:${port}/test`,
    loadUsingSystemPrincipal: true,
  }).QueryInterface(Ci.nsIHttpChannel);
  chan.loadFlags = Ci.nsIChannel.LOAD_INITIAL_DOCUMENT_URI;

  let openPromise = new Promise(resolve => {
    chan.asyncOpen(
      new ChannelListener(() => resolve(), null, CL_EXPECT_FAILURE)
    );
  });

  // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
  await new Promise(resolve => setTimeout(resolve, 100));
  chan.cancel(Cr.NS_BINDING_ABORTED);

  await openPromise;

  Assert.equal(chan.status, Cr.NS_BINDING_ABORTED, "Should be cancelled");

  await server.stop();
}

add_task(async function test_cancel_during_connection_no_speculative() {
  Services.prefs.setIntPref("network.http.speculative-parallel-limit", 0);
  await do_test_cancel_during_connection("alt2.example.com");
});

add_task(async function test_cancel_during_connection_with_speculative() {
  Services.prefs.setIntPref("network.http.speculative-parallel-limit", 6);
  await do_test_cancel_during_connection("alt2.example.com");
});

// Test fallback when first attempt hangs, speculative disabled.
// pauseTCPConnect does not work on Linux, so skip these tests there.
add_task(
  { skip_if: () => AppConstants.platform == "linux" },
  async function test_first_attempt_slow_no_speculative() {
    Services.prefs.setIntPref("network.http.speculative-parallel-limit", 0);
    await do_test_first_attempt_slow("alt2.example.com");
  }
);

// Test fallback when first attempt hangs, speculative enabled.
add_task(
  { skip_if: () => AppConstants.platform == "linux" },
  async function test_first_attempt_slow_with_speculative() {
    Services.prefs.setIntPref("network.http.speculative-parallel-limit", 6);
    await do_test_first_attempt_slow("alt2.example.com");
  }
);

Messung V0.5 in Prozent
C=91 H=100 G=95

¤ Dauer der Verarbeitung: 0.20 Sekunden  (vorverarbeitet am  2026-10-02) ¤

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