Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  test_happy_eyeballs_h2_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 { NodeHTTP2Server } = 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,
    httpVersion: result.req.protocolVersion,
    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 NodeHTTP2Server();
  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");

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

  Assert.equal(status, 200, "Request should succeed");
  Assert.equal(buffer, "ok", "Response body should match");
  Assert.equal(httpVersion, "h2", "Should use HTTP/2");

  await server.stop();
}

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");
});

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 NodeHTTP2Server();
  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");

  let blockedAddr = mockController.createScriptableNetAddr("::1", port);
  mockController.blockTCPConnect(blockedAddr);

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

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

  await server.stop();
}

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");
});

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_all_attempts_fail(host) {
  await resetConnections();

  let server = new NodeHTTP2Server();
  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");

  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();
}

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");
});

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 NodeHTTP2Server();
  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");

  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");
});

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

  let server = new NodeHTTP2Server();
  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");

  let pausedAddr = mockController.createScriptableNetAddr("::1", port);
  mockController.pauseTCPConnect(pausedAddr);

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

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

  await server.stop();
}

// 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");
  }
);

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=99 H=78 G=88

¤ Dauer der Verarbeitung: 0.15 Sekunden  (vorverarbeitet am  2026-09-28) ¤

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






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=1126438
#Domains=1867298