mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-27 06:43:19 +08:00
http.request, https.request and get now accept options the compiler
cannot see as an object literal: a RequestOptions variable, a literal
that spreads one, or a literal that sets socketPath. The runtime reads
the record in the ClientRequest constructor's order with Node's errors;
documented options it does not implement throw the runtime fence when
they carry a value. https adds rejectUnauthorized, ca and servername.
socketPath dials a Unix domain socket in the net unit; the agent keys
its sockets by the path as Node's getName does, and the Host header
defaults to localhost. server.listen(path[, cb]) binds a Unix socket and
removes the socket file when the server closes; a numeric string is
still a port. Errors name the path ("connect ENOENT /path", "listen
EADDRINUSE: address already in use /path"). Windows reports ENOTSUP.
A TypeScript object literal with no contextual type that spreads a
checked-dynamic value maps to the checked dynamic, so
`const options = { ...location, path, timeout }` compiles.
A socket's 'lookup' event reaches its listeners with (err, address,
family, host) for each address a host name resolves to, or once with
the lookup error, before 'connect'. Only programs that listen for
'lookup' install the lookup records; elsewhere the hook sites are a NULL
check.
server.close((err) => ...) runs the callback with undefined at 'close',
or with ERR_SERVER_NOT_RUNNING when the server was not listening; a
server that never listened now emits 'close'. IncomingMessage 'data'
listeners may take string chunks after setEncoding, and res.end()
accepts a string-or-undefined chunk.
fetch's BodyInit and HeadersInit unions, as RequestInit-derived option
types spell them under @types/node, map to the checked dynamic, and a
URLSearchParams body is sent form-encoded, as by Node.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
62 lines
2.2 KiB
TypeScript
62 lines
2.2 KiB
TypeScript
// https.request with options read at run time: a RequestOptions value
|
|
// spread with the CA, over TCP and over a Unix socket, an unverifiable
|
|
// certificate with and without rejectUnauthorized, and the protocol check.
|
|
import * as https from "node:https";
|
|
import { readFileSync } from "node:fs";
|
|
import { tmpdir } from "node:os";
|
|
import { join } from "node:path";
|
|
|
|
const ca = readFileSync("tests/fixtures/server/certs/ca.pem");
|
|
const sock = join(tmpdir(), `scriptc-https-${process.pid}.sock`);
|
|
|
|
const server = https.createServer(
|
|
{
|
|
cert: readFileSync("tests/fixtures/server/certs/localhost.pem"),
|
|
key: readFileSync("tests/fixtures/server/certs/localhost-key.pem"),
|
|
},
|
|
(req, res) => res.end(`${req.method} ${req.url} host=${(req.headers.host ?? "").replace(/:\d+$/, ":<port>")}`),
|
|
);
|
|
const unix = https.createServer(
|
|
{
|
|
cert: readFileSync("tests/fixtures/server/certs/localhost.pem"),
|
|
key: readFileSync("tests/fixtures/server/certs/localhost-key.pem"),
|
|
},
|
|
(req, res) => res.end(`unix ${req.method} ${req.url} host=${req.headers.host}`),
|
|
);
|
|
|
|
function send(label: string, options: https.RequestOptions): Promise<void> {
|
|
return new Promise<void>((resolve) => {
|
|
const req = https.request(options, (res) => {
|
|
let body = "";
|
|
res.on("data", (c: Buffer) => (body += c.toString()));
|
|
res.on("end", () => {
|
|
console.log(label, res.statusCode, body);
|
|
resolve();
|
|
});
|
|
});
|
|
req.on("error", (err: NodeJS.ErrnoException) => {
|
|
console.log(label, "error", err.code);
|
|
resolve();
|
|
});
|
|
req.end();
|
|
});
|
|
}
|
|
|
|
server.listen(0, () => {
|
|
const port = (server.address() as { port: number }).port;
|
|
unix.listen(sock, async () => {
|
|
const tcp: https.RequestOptions = { host: "localhost", port };
|
|
await send("tcp", { ...tcp, path: "/a", ca, agent: false });
|
|
await send("unix", { socketPath: sock, path: "/b", ca, agent: false });
|
|
await send("unverified", { ...tcp, path: "/c", agent: false });
|
|
await send("unchecked", { ...tcp, path: "/d", rejectUnauthorized: false, agent: false });
|
|
try {
|
|
https.request({ ...tcp, protocol: "http:" });
|
|
} catch (err) {
|
|
console.log("protocol", (err as NodeJS.ErrnoException).code, (err as Error).message);
|
|
}
|
|
server.close();
|
|
unix.close();
|
|
});
|
|
});
|