Files
bun.sh/test/regression/issue/https-request-url-property.test.ts
Claude Bot e20e2a6bd4 fix: Set IncomingMessage.url to empty string for HTTPS requests to match Node.js
Fixes issue #13820 where https.request() returned "/" for response.url
instead of an empty string like Node.js. The issue was that for
FetchResponse type IncomingMessage objects, the url property was
inheriting from the fetch Response.url which returns the pathname.

Changes:
- Modified IncomingMessage constructor to explicitly set url to "" for FetchResponse type
- Added comprehensive tests covering various request scenarios
- Ensures Node.js compatibility for response.url property

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-14 03:23:57 +00:00

130 lines
3.9 KiB
TypeScript

import { test, expect } from "bun:test";
import { request as httpsRequest } from "https";
import { request as httpRequest } from "http";
test("https.request URL property should be empty string like Node.js - issue #13820", async () => {
const url = await new Promise<string>((resolve, reject) => {
const req = httpsRequest("https://google.com", (res) => {
resolve(res.url);
res.resume(); // Drain response to avoid hanging
});
req.on("error", reject);
req.setTimeout(5000, () => reject(new Error("Timeout")));
req.end();
});
// Node.js returns empty string, not "/"
expect(url).toBe("");
});
test("https.request URL property for root path with explicit slash", async () => {
const url = await new Promise<string>((resolve, reject) => {
const req = httpsRequest("https://google.com/", (res) => {
resolve(res.url);
res.resume();
});
req.on("error", reject);
req.setTimeout(5000, () => reject(new Error("Timeout")));
req.end();
});
expect(url).toBe("");
});
test("https.request URL property for path", async () => {
const url = await new Promise<string>((resolve, reject) => {
const req = httpsRequest("https://httpbin.org/json", (res) => {
resolve(res.url);
res.resume();
});
req.on("error", reject);
req.setTimeout(5000, () => reject(new Error("Timeout")));
req.end();
});
expect(url).toBe("");
});
test("http.request URL property should also be empty string", async () => {
const url = await new Promise<string>((resolve, reject) => {
const req = httpRequest("http://httpbin.org/json", (res) => {
resolve(res.url);
res.resume();
});
req.on("error", reject);
req.setTimeout(5000, () => reject(new Error("Timeout")));
req.end();
});
expect(url).toBe("");
});
test("https.request URL property with redirect", async () => {
const url = await new Promise<string>((resolve, reject) => {
const req = httpsRequest("https://httpbin.org/redirect/1", (res) => {
resolve(res.url);
res.resume();
});
req.on("error", reject);
req.setTimeout(5000, () => reject(new Error("Timeout")));
req.end();
});
// Even after redirect, URL should still be empty string (Node.js behavior)
expect(url).toBe("");
});
test("https.request URL property consistency across multiple requests", async () => {
const urls = await Promise.all([
new Promise<string>((resolve, reject) => {
const req = httpsRequest("https://httpbin.org/status/200", (res) => {
resolve(res.url);
res.resume();
});
req.on("error", reject);
req.setTimeout(5000, () => reject(new Error("Timeout")));
req.end();
}),
new Promise<string>((resolve, reject) => {
const req = httpsRequest("https://httpbin.org/status/404", (res) => {
resolve(res.url);
res.resume();
});
req.on("error", reject);
req.setTimeout(5000, () => reject(new Error("Timeout")));
req.end();
}),
]);
expect(urls[0]).toBe("");
expect(urls[1]).toBe("");
});
test("https.request URL property type should be string", async () => {
const url = await new Promise<any>((resolve, reject) => {
const req = httpsRequest("https://httpbin.org/json", (res) => {
resolve(res.url);
res.resume();
});
req.on("error", reject);
req.setTimeout(5000, () => reject(new Error("Timeout")));
req.end();
});
expect(typeof url).toBe("string");
expect(url).toBe("");
});
test("https.request response object should have url property", async () => {
const hasUrlProperty = await new Promise<boolean>((resolve, reject) => {
const req = httpsRequest("https://httpbin.org/json", (res) => {
resolve("url" in res);
res.resume();
});
req.on("error", reject);
req.setTimeout(5000, () => reject(new Error("Timeout")));
req.end();
});
expect(hasUrlProperty).toBe(true);
});