diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /netwerk/test/unit/test_http_server_timing.js | |
parent | Initial commit. (diff) | |
download | firefox-esr-upstream.tar.xz firefox-esr-upstream.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'netwerk/test/unit/test_http_server_timing.js')
-rw-r--r-- | netwerk/test/unit/test_http_server_timing.js | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/netwerk/test/unit/test_http_server_timing.js b/netwerk/test/unit/test_http_server_timing.js new file mode 100644 index 0000000000..2e71c65c1e --- /dev/null +++ b/netwerk/test/unit/test_http_server_timing.js @@ -0,0 +1,138 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et: */ +/* 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/. */ + +/* eslint-env node */ + +"use strict"; + +class ServerCode { + static async startServer(port) { + global.http = require("http"); + global.server = global.http.createServer((req, res) => { + res.setHeader("Content-Type", "text/plain"); + res.setHeader("Content-Length", "12"); + res.setHeader("Transfer-Encoding", "chunked"); + res.setHeader("Trailer", "Server-Timing"); + res.setHeader( + "Server-Timing", + "metric; dur=123.4; desc=description, metric2; dur=456.78; desc=description1" + ); + res.write("data reached"); + res.addTrailers({ + "Server-Timing": + "metric3; dur=789.11; desc=description2, metric4; dur=1112.13; desc=description3", + }); + res.end(); + }); + + let serverPort = await new Promise(resolve => { + global.server.listen(0, "0.0.0.0", 2000, () => { + resolve(global.server.address().port); + }); + }); + + if (process.env.MOZ_ANDROID_DATA_DIR) { + // When creating a server on Android we must make sure that the port + // is forwarded from the host machine to the emulator. + let adb_path = "adb"; + if (process.env.MOZ_FETCHES_DIR) { + adb_path = `${process.env.MOZ_FETCHES_DIR}/android-sdk-linux/platform-tools/adb`; + } + + await new Promise(resolve => { + const { exec } = require("child_process"); + exec( + `${adb_path} reverse tcp:${serverPort} tcp:${serverPort}`, + (error, stdout, stderr) => { + if (error) { + console.log(`error: ${error.message}`); + return; + } + if (stderr) { + console.log(`stderr: ${stderr}`); + } + // console.log(`stdout: ${stdout}`); + resolve(); + } + ); + }); + } + + return serverPort; + } +} + +const responseServerTiming = [ + { metric: "metric", duration: "123.4", description: "description" }, + { metric: "metric2", duration: "456.78", description: "description1" }, +]; +const trailerServerTiming = [ + { metric: "metric3", duration: "789.11", description: "description2" }, + { metric: "metric4", duration: "1112.13", description: "description3" }, +]; + +let port; + +add_task(async function setup() { + let processId = await NodeServer.fork(); + registerCleanupFunction(async () => { + await NodeServer.kill(processId); + }); + await NodeServer.execute(processId, ServerCode); + port = await NodeServer.execute(processId, `ServerCode.startServer(0)`); + ok(port); +}); + +// Test that secure origins can use server-timing, even with plain http +add_task(async function test_localhost_origin() { + let chan = NetUtil.newChannel({ + uri: `http://localhost:${port}/`, + loadUsingSystemPrincipal: true, + }); + await new Promise(resolve => { + chan.asyncOpen( + new ChannelListener((request, buffer) => { + let channel = request.QueryInterface(Ci.nsITimedChannel); + let headers = channel.serverTiming.QueryInterface(Ci.nsIArray); + ok(headers.length); + + let expectedResult = responseServerTiming.concat(trailerServerTiming); + Assert.equal(headers.length, expectedResult.length); + + for (let i = 0; i < expectedResult.length; i++) { + let header = headers.queryElementAt(i, Ci.nsIServerTiming); + Assert.equal(header.name, expectedResult[i].metric); + Assert.equal(header.description, expectedResult[i].description); + Assert.equal(header.duration, parseFloat(expectedResult[i].duration)); + } + resolve(); + }, null) + ); + }); +}); + +// Test that insecure origins can't use server timing. +add_task(async function test_http_non_localhost() { + Services.prefs.setBoolPref("network.dns.native-is-localhost", true); + registerCleanupFunction(async () => { + Services.prefs.clearUserPref("network.dns.native-is-localhost"); + }); + + let chan = NetUtil.newChannel({ + uri: `http://example.org:${port}/`, + loadUsingSystemPrincipal: true, + }); + await new Promise(resolve => { + chan.asyncOpen( + new ChannelListener((request, buffer) => { + let channel = request.QueryInterface(Ci.nsITimedChannel); + let headers = channel.serverTiming.QueryInterface(Ci.nsIArray); + Assert.equal(headers.length, 0); + resolve(); + }, null) + ); + }); +}); |