11cb0ef41Sopenharmony_ci// Flags: --experimental-network-imports --dns-result-order=ipv4first 21cb0ef41Sopenharmony_ciimport * as common from '../common/index.mjs'; 31cb0ef41Sopenharmony_ciimport { path, readKey } from '../common/fixtures.mjs'; 41cb0ef41Sopenharmony_ciimport { pathToFileURL } from 'url'; 51cb0ef41Sopenharmony_ciimport assert from 'assert'; 61cb0ef41Sopenharmony_ciimport http from 'http'; 71cb0ef41Sopenharmony_ciimport os from 'os'; 81cb0ef41Sopenharmony_ciimport util from 'util'; 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ciif (!common.hasCrypto) { 111cb0ef41Sopenharmony_ci common.skip('missing crypto'); 121cb0ef41Sopenharmony_ci} 131cb0ef41Sopenharmony_ci 141cb0ef41Sopenharmony_ciconst https = (await import('https')).default; 151cb0ef41Sopenharmony_ci 161cb0ef41Sopenharmony_ciconst createHTTPServer = http.createServer; 171cb0ef41Sopenharmony_ci 181cb0ef41Sopenharmony_ci// Needed to deal w/ test certs 191cb0ef41Sopenharmony_ciprocess.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; 201cb0ef41Sopenharmony_ciconst options = { 211cb0ef41Sopenharmony_ci key: readKey('agent1-key.pem'), 221cb0ef41Sopenharmony_ci cert: readKey('agent1-cert.pem') 231cb0ef41Sopenharmony_ci}; 241cb0ef41Sopenharmony_ci 251cb0ef41Sopenharmony_ciconst createHTTPSServer = https.createServer.bind(null, options); 261cb0ef41Sopenharmony_ci 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_ciconst testListeningOptions = [ 291cb0ef41Sopenharmony_ci { 301cb0ef41Sopenharmony_ci hostname: 'localhost', 311cb0ef41Sopenharmony_ci listenOptions: { 321cb0ef41Sopenharmony_ci host: '127.0.0.1' 331cb0ef41Sopenharmony_ci } 341cb0ef41Sopenharmony_ci }, 351cb0ef41Sopenharmony_ci]; 361cb0ef41Sopenharmony_ci 371cb0ef41Sopenharmony_ciconst internalInterfaces = Object.values(os.networkInterfaces()).flat().filter( 381cb0ef41Sopenharmony_ci (iface) => iface?.internal && iface.address && !iface.scopeid 391cb0ef41Sopenharmony_ci); 401cb0ef41Sopenharmony_cifor (const iface of internalInterfaces) { 411cb0ef41Sopenharmony_ci testListeningOptions.push({ 421cb0ef41Sopenharmony_ci hostname: iface?.family === 'IPv6' ? `[${iface?.address}]` : iface?.address, 431cb0ef41Sopenharmony_ci listenOptions: { 441cb0ef41Sopenharmony_ci host: iface?.address, 451cb0ef41Sopenharmony_ci ipv6Only: iface?.family === 'IPv6' 461cb0ef41Sopenharmony_ci } 471cb0ef41Sopenharmony_ci }); 481cb0ef41Sopenharmony_ci} 491cb0ef41Sopenharmony_ci 501cb0ef41Sopenharmony_cifor (const { protocol, createServer } of [ 511cb0ef41Sopenharmony_ci { protocol: 'http:', createServer: createHTTPServer }, 521cb0ef41Sopenharmony_ci { protocol: 'https:', createServer: createHTTPSServer }, 531cb0ef41Sopenharmony_ci]) { 541cb0ef41Sopenharmony_ci const body = ` 551cb0ef41Sopenharmony_ci export default (a) => () => a; 561cb0ef41Sopenharmony_ci export let url = import.meta.url; 571cb0ef41Sopenharmony_ci `; 581cb0ef41Sopenharmony_ci 591cb0ef41Sopenharmony_ci const base = 'http://127.0.0.1'; 601cb0ef41Sopenharmony_ci for (const { hostname, listenOptions } of testListeningOptions) { 611cb0ef41Sopenharmony_ci const host = new URL(base); 621cb0ef41Sopenharmony_ci host.protocol = protocol; 631cb0ef41Sopenharmony_ci host.hostname = hostname; 641cb0ef41Sopenharmony_ci // /not-found is a 404 651cb0ef41Sopenharmony_ci // ?redirect causes a redirect, no body. JSON.parse({status:number,location:string}) 661cb0ef41Sopenharmony_ci // ?mime sets the content-type, string 671cb0ef41Sopenharmony_ci // ?body sets the body, string 681cb0ef41Sopenharmony_ci const server = createServer(function(_req, res) { 691cb0ef41Sopenharmony_ci const url = new URL(_req.url, host); 701cb0ef41Sopenharmony_ci const redirect = url.searchParams.get('redirect'); 711cb0ef41Sopenharmony_ci if (url.pathname === '/not-found') { 721cb0ef41Sopenharmony_ci res.writeHead(404); 731cb0ef41Sopenharmony_ci res.end(); 741cb0ef41Sopenharmony_ci return; 751cb0ef41Sopenharmony_ci } 761cb0ef41Sopenharmony_ci if (redirect) { 771cb0ef41Sopenharmony_ci const { status, location } = JSON.parse(redirect); 781cb0ef41Sopenharmony_ci res.writeHead(status, { 791cb0ef41Sopenharmony_ci location 801cb0ef41Sopenharmony_ci }); 811cb0ef41Sopenharmony_ci res.end(); 821cb0ef41Sopenharmony_ci return; 831cb0ef41Sopenharmony_ci } 841cb0ef41Sopenharmony_ci res.writeHead(200, { 851cb0ef41Sopenharmony_ci 'content-type': url.searchParams.get('mime') || 'text/javascript' 861cb0ef41Sopenharmony_ci }); 871cb0ef41Sopenharmony_ci res.end(url.searchParams.get('body') || body); 881cb0ef41Sopenharmony_ci }); 891cb0ef41Sopenharmony_ci 901cb0ef41Sopenharmony_ci const listen = util.promisify(server.listen.bind(server)); 911cb0ef41Sopenharmony_ci await listen({ 921cb0ef41Sopenharmony_ci ...listenOptions, 931cb0ef41Sopenharmony_ci port: 0 941cb0ef41Sopenharmony_ci }); 951cb0ef41Sopenharmony_ci const url = new URL(host); 961cb0ef41Sopenharmony_ci url.port = server?.address()?.port; 971cb0ef41Sopenharmony_ci 981cb0ef41Sopenharmony_ci const ns = await import(url.href); 991cb0ef41Sopenharmony_ci assert.strict.deepStrictEqual(Object.keys(ns), ['default', 'url']); 1001cb0ef41Sopenharmony_ci const obj = {}; 1011cb0ef41Sopenharmony_ci assert.strict.equal(ns.default(obj)(), obj); 1021cb0ef41Sopenharmony_ci assert.strict.equal(ns.url, url.href); 1031cb0ef41Sopenharmony_ci 1041cb0ef41Sopenharmony_ci // Redirects have same import.meta.url but different cache 1051cb0ef41Sopenharmony_ci // entry on Web 1061cb0ef41Sopenharmony_ci const redirect = new URL(url.href); 1071cb0ef41Sopenharmony_ci redirect.searchParams.set('redirect', JSON.stringify({ 1081cb0ef41Sopenharmony_ci status: 302, 1091cb0ef41Sopenharmony_ci location: url.href 1101cb0ef41Sopenharmony_ci })); 1111cb0ef41Sopenharmony_ci const redirectedNS = await import(redirect.href); 1121cb0ef41Sopenharmony_ci assert.strict.deepStrictEqual( 1131cb0ef41Sopenharmony_ci Object.keys(redirectedNS), 1141cb0ef41Sopenharmony_ci ['default', 'url'] 1151cb0ef41Sopenharmony_ci ); 1161cb0ef41Sopenharmony_ci assert.strict.notEqual(redirectedNS.default, ns.default); 1171cb0ef41Sopenharmony_ci assert.strict.equal(redirectedNS.url, url.href); 1181cb0ef41Sopenharmony_ci 1191cb0ef41Sopenharmony_ci // Redirects have the same import.meta.url but different cache 1201cb0ef41Sopenharmony_ci // entry on Web 1211cb0ef41Sopenharmony_ci const relativeAfterRedirect = new URL(url.href + 'foo/index.js'); 1221cb0ef41Sopenharmony_ci const redirected = new URL(url.href + 'bar/index.js'); 1231cb0ef41Sopenharmony_ci redirected.searchParams.set('body', 'export let relativeDepURL = (await import("./baz.js")).url'); 1241cb0ef41Sopenharmony_ci relativeAfterRedirect.searchParams.set('redirect', JSON.stringify({ 1251cb0ef41Sopenharmony_ci status: 302, 1261cb0ef41Sopenharmony_ci location: redirected.href 1271cb0ef41Sopenharmony_ci })); 1281cb0ef41Sopenharmony_ci const relativeAfterRedirectedNS = await import(relativeAfterRedirect.href); 1291cb0ef41Sopenharmony_ci assert.strict.equal( 1301cb0ef41Sopenharmony_ci relativeAfterRedirectedNS.relativeDepURL, 1311cb0ef41Sopenharmony_ci url.href + 'bar/baz.js' 1321cb0ef41Sopenharmony_ci ); 1331cb0ef41Sopenharmony_ci 1341cb0ef41Sopenharmony_ci const crossProtocolRedirect = new URL(url.href); 1351cb0ef41Sopenharmony_ci crossProtocolRedirect.searchParams.set('redirect', JSON.stringify({ 1361cb0ef41Sopenharmony_ci status: 302, 1371cb0ef41Sopenharmony_ci location: 'data:text/javascript,' 1381cb0ef41Sopenharmony_ci })); 1391cb0ef41Sopenharmony_ci await assert.rejects( 1401cb0ef41Sopenharmony_ci import(crossProtocolRedirect.href), 1411cb0ef41Sopenharmony_ci { code: 'ERR_NETWORK_IMPORT_DISALLOWED' } 1421cb0ef41Sopenharmony_ci ); 1431cb0ef41Sopenharmony_ci 1441cb0ef41Sopenharmony_ci const deps = new URL(url.href); 1451cb0ef41Sopenharmony_ci deps.searchParams.set('body', ` 1461cb0ef41Sopenharmony_ci export {data} from 'data:text/javascript,export let data = 1'; 1471cb0ef41Sopenharmony_ci import * as http from ${JSON.stringify(url.href)}; 1481cb0ef41Sopenharmony_ci export {http}; 1491cb0ef41Sopenharmony_ci `); 1501cb0ef41Sopenharmony_ci const depsNS = await import(deps.href); 1511cb0ef41Sopenharmony_ci assert.strict.deepStrictEqual(Object.keys(depsNS), ['data', 'http']); 1521cb0ef41Sopenharmony_ci assert.strict.equal(depsNS.data, 1); 1531cb0ef41Sopenharmony_ci assert.strict.equal(depsNS.http, ns); 1541cb0ef41Sopenharmony_ci 1551cb0ef41Sopenharmony_ci const relativeDeps = new URL(url.href); 1561cb0ef41Sopenharmony_ci relativeDeps.searchParams.set('body', ` 1571cb0ef41Sopenharmony_ci import * as http from "./"; 1581cb0ef41Sopenharmony_ci export {http}; 1591cb0ef41Sopenharmony_ci `); 1601cb0ef41Sopenharmony_ci const relativeDepsNS = await import(relativeDeps.href); 1611cb0ef41Sopenharmony_ci assert.strict.deepStrictEqual(Object.keys(relativeDepsNS), ['http']); 1621cb0ef41Sopenharmony_ci assert.strict.equal(relativeDepsNS.http, ns); 1631cb0ef41Sopenharmony_ci const fileDep = new URL(url.href); 1641cb0ef41Sopenharmony_ci const { href } = pathToFileURL(path('/es-modules/message.mjs')); 1651cb0ef41Sopenharmony_ci fileDep.searchParams.set('body', ` 1661cb0ef41Sopenharmony_ci import ${JSON.stringify(href)}; 1671cb0ef41Sopenharmony_ci export default 1;`); 1681cb0ef41Sopenharmony_ci await assert.rejects( 1691cb0ef41Sopenharmony_ci import(fileDep.href), 1701cb0ef41Sopenharmony_ci { code: 'ERR_NETWORK_IMPORT_DISALLOWED' } 1711cb0ef41Sopenharmony_ci ); 1721cb0ef41Sopenharmony_ci 1731cb0ef41Sopenharmony_ci const builtinDep = new URL(url.href); 1741cb0ef41Sopenharmony_ci builtinDep.searchParams.set('body', ` 1751cb0ef41Sopenharmony_ci import 'node:fs'; 1761cb0ef41Sopenharmony_ci export default 1; 1771cb0ef41Sopenharmony_ci `); 1781cb0ef41Sopenharmony_ci await assert.rejects( 1791cb0ef41Sopenharmony_ci import(builtinDep.href), 1801cb0ef41Sopenharmony_ci { code: 'ERR_NETWORK_IMPORT_DISALLOWED' } 1811cb0ef41Sopenharmony_ci ); 1821cb0ef41Sopenharmony_ci 1831cb0ef41Sopenharmony_ci const unprefixedBuiltinDep = new URL(url.href); 1841cb0ef41Sopenharmony_ci unprefixedBuiltinDep.searchParams.set('body', ` 1851cb0ef41Sopenharmony_ci import 'fs'; 1861cb0ef41Sopenharmony_ci export default 1; 1871cb0ef41Sopenharmony_ci `); 1881cb0ef41Sopenharmony_ci await assert.rejects( 1891cb0ef41Sopenharmony_ci import(unprefixedBuiltinDep.href), 1901cb0ef41Sopenharmony_ci { code: 'ERR_NETWORK_IMPORT_DISALLOWED' } 1911cb0ef41Sopenharmony_ci ); 1921cb0ef41Sopenharmony_ci 1931cb0ef41Sopenharmony_ci const unsupportedMIME = new URL(url.href); 1941cb0ef41Sopenharmony_ci unsupportedMIME.searchParams.set('mime', 'application/node'); 1951cb0ef41Sopenharmony_ci unsupportedMIME.searchParams.set('body', ''); 1961cb0ef41Sopenharmony_ci await assert.rejects( 1971cb0ef41Sopenharmony_ci import(unsupportedMIME.href), 1981cb0ef41Sopenharmony_ci { code: 'ERR_UNKNOWN_MODULE_FORMAT' } 1991cb0ef41Sopenharmony_ci ); 2001cb0ef41Sopenharmony_ci const notFound = new URL(url.href); 2011cb0ef41Sopenharmony_ci notFound.pathname = '/not-found'; 2021cb0ef41Sopenharmony_ci await assert.rejects( 2031cb0ef41Sopenharmony_ci import(notFound.href), 2041cb0ef41Sopenharmony_ci { code: 'ERR_MODULE_NOT_FOUND' }, 2051cb0ef41Sopenharmony_ci ); 2061cb0ef41Sopenharmony_ci 2071cb0ef41Sopenharmony_ci server.close(); 2081cb0ef41Sopenharmony_ci } 2091cb0ef41Sopenharmony_ci} 210