import * as http from 'node:http'; import tls from 'node:tls'; const TLS_SERVER_OPTION_KEYS = [ 'ALPNProtocols', 'SNICallback', 'allowPartialChain', 'ca', 'cert', 'ciphers', 'clientCertEngine', 'crl', 'dhparam', 'ecdhCurve', 'honorCipherOrder', 'key', 'maxVersion', 'minVersion', 'passphrase', 'pfx', 'rejectUnauthorized', 'requestCert', 'secureOptions', 'secureContext', 'secureProtocol', 'sessionIdContext', 'sigalgs', 'ticketKeys' ]; function createPlainObject() { return Object.create(null); } function splitServerOptions(options) { const httpOptions = createPlainObject(); const tlsOptions = createPlainObject(); let hasTlsOptions = false; if (!options || typeof options !== 'object') { return { httpOptions: undefined, tlsOptions: undefined, hasTlsOptions: false }; } Object.keys(options).forEach(key => { if (TLS_SERVER_OPTION_KEYS.includes(key)) { tlsOptions[key] = options[key]; hasTlsOptions = true; return; } httpOptions[key] = options[key]; }); return { httpOptions, tlsOptions: hasTlsOptions ? tlsOptions : undefined, hasTlsOptions }; } function normalizeCreateServerArgs(options, requestListener) { if (typeof options === 'function') { return { serverOptions: undefined, requestListener: options }; } return { serverOptions: options, requestListener }; } function createInvalidProtocolError(protocol) { const error = new TypeError(`Protocol "${protocol}" not supported. Expected "https:"`); error.code = 'ERR_INVALID_PROTOCOL'; return error; } function getProtocolFromInput(input) { if (typeof input === 'string') return new URL(input).protocol; if (!input || typeof input !== 'object') return undefined; if (typeof input.href === 'string') return new URL(String(input)).protocol; if (input.protocol === undefined || input.protocol === null) return undefined; return String(input.protocol); } function assertHttpsProtocol(protocol) { if (protocol === undefined || protocol === null || protocol === '') return; if (String(protocol) !== 'https:') throw createInvalidProtocolError(String(protocol)); } function applyDefaultHttpsProtocol(input, options) { const optionProtocol = options && typeof options === 'object' ? options.protocol : undefined; assertHttpsProtocol(optionProtocol); if (typeof input === 'string' || (input && typeof input === 'object' && typeof input.href === 'string')) { if (optionProtocol === undefined) assertHttpsProtocol(getProtocolFromInput(input)); return [input, options]; } if (typeof input === 'function' || input === undefined || input === null) { return [{ protocol: 'https:' }, options]; } assertHttpsProtocol(getProtocolFromInput(input)); return [{ ...input, protocol: input.protocol ?? 'https:' }, options]; } const HTTP_SERVER_METHODS = ['_attachSocket', '_drainSocket', 'closeAllConnections', 'closeIdleConnections', 'setTimeout']; export class Server extends tls.Server { constructor(options, requestListener) { const normalized = normalizeCreateServerArgs(options, requestListener); const split = splitServerOptions(normalized.serverOptions); super(split.tlsOptions); this.timeout = 0; this.headersTimeout = 60000; this.requestTimeout = 300000; this.keepAliveTimeout = 5000; this.maxHeadersCount = 2000; this._socketStates = new Set(); this._closing = false; this.on('secureConnection', socket => { this.emit('connection', socket); this._attachSocket(socket); }); if (typeof normalized.requestListener === 'function') this.on('request', normalized.requestListener); } listen(...args) { this._closing = false; return super.listen(...args); } close(callback) { this._closing = true; this.closeIdleConnections(); return super.close(callback); } } for (const name of HTTP_SERVER_METHODS) { Object.defineProperty(Server.prototype, name, { value: http.Server.prototype[name], writable: true, configurable: true }); } export class Agent extends http.Agent { constructor(options) { super(options); this.defaultPort = 443; this.protocol = 'https:'; this.maxCachedSessions = this.options.maxCachedSessions ?? 100; this._sessionCache = { map: Object.create(null), list: [] }; } } export const globalAgent = new Agent(); export function createSecureContext(options) { return tls.createSecureContext(options); } export function isSecureContext(value) { return tls.isSecureContext(value); } export function setConfigPath(path) { return tls.setConfigPath(path); } export function createServer(options, requestListener) { return new Server(options, requestListener); } export function request(input, options, callback) { const [resolvedInput, resolvedOptions] = applyDefaultHttpsProtocol(input, options); return http.request(resolvedInput, resolvedOptions, callback); } export function get(input, options, callback) { const [resolvedInput, resolvedOptions] = applyDefaultHttpsProtocol(input, options); return http.get(resolvedInput, resolvedOptions, callback); } export { METHODS, STATUS_CODES } from 'ant:internal/http_metadata';