Files
scriptc/tests/corpus/2644-http-client-url-argument.ts
Chris Tate a7538fd87d URL-string and URL-object arguments to the http and https clients
- `http.get("http://host/path")` and its https spelling now compile. The declarations only described the options-record form, so the first thing a from-scratch client writes was a type error — the shape worked under --dynamic, where the engine does not consult our declarations, which is how it read as a hello-world failure.
- A URL object is accepted the same way, as its href through the same parse. An unparsable input is the WHATWG "Invalid URL" TypeError and a scheme that is not the calling module's is ERR_INVALID_PROTOCOL, both catchable, matching Node rather than silently upgrading the dial.
- `request` and `get` take one signature with a union first parameter instead of Node's two overloads: `tls ? https.request : http.request` unions two function types, and resolving a call on that union collapses each side to a single signature, so an overload set misresolves in either declaration order. The lowering dispatches on the argument's own type.
- Both rows run on the LLVM backend, and the tls CA-store entries joined it too — the omission there was stale, so 2557-tls-ca-store moved off the C lane with identical output.
- Corpus 2644 and 2645 cover both schemes against loopback servers, so neither needs the network.
2026-07-24 23:24:53 -05:00

61 lines
2.1 KiB
TypeScript

// The URL-string first argument to the http/https clients — Node's other
// client spelling, and the one a from-scratch client reaches for before
// it learns the options object. Both modules accept a string or a URL
// object; the scheme is checked against the MODULE, so http.get of an
// https URL is ERR_INVALID_PROTOCOL rather than a silent upgrade, and an
// unparsable input is the WHATWG "Invalid URL" TypeError. Both throws are
// catchable. Everything here dials 127.0.0.1, so the test needs no
// network — the DNS story is the same code path either way.
import * as http from "node:http";
const server = http.createServer((req, res) => {
res.end(`hi ${req.url}`);
});
server.listen(0, () => {
const port = server.address().port;
// the plain string form, with a query the parse must keep
http.get(`http://127.0.0.1:${port}/one?q=1`, (res) => {
console.log("string", res.statusCode);
let body = "";
res.on("data", (c) => { body += c; });
res.on("end", () => {
console.log("body", body);
// a URL OBJECT reads as its href through the same parse
const u = new URL(`http://127.0.0.1:${port}/two`);
http.get(u, (res2) => {
let b2 = "";
res2.on("data", (c) => { b2 += c; });
res2.on("end", () => {
console.log("url object", b2);
// request() is get() without the eager end()
const req = http.request(`http://127.0.0.1:${port}/three`, (res3) => {
let b3 = "";
res3.on("data", (c) => { b3 += c; });
res3.on("end", () => {
console.log("request", b3);
// the scheme is the calling module's, not the URL's
try {
http.get("https://127.0.0.1/nope", () => {});
} catch (e) {
console.log("scheme", (e as Error).message);
}
try {
http.get("not a url", () => {});
} catch (e) {
console.log("parse", (e as Error).message);
}
server.close();
});
});
req.end();
});
});
});
});
});