Skip to content

Commit 0136851

Browse files
committed
refactor: improve requestWithURL
1 parent d1da262 commit 0136851

File tree

2 files changed

+63
-13
lines changed

2 files changed

+63
-13
lines changed

src/utils/request.ts

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,21 @@ import type { HTTPMethod } from "../types/h3.ts";
1111
import type { H3EventContext } from "../types/context.ts";
1212
import type { ServerRequest } from "srvx";
1313

14-
const _urlOverrides = new WeakMap<Request, string>();
15-
16-
const _proxyHandler: ProxyHandler<Request> = {
17-
get(target, prop, receiver) {
18-
if (prop === "url") return _urlOverrides.get(receiver);
19-
const value = Reflect.get(target, prop);
20-
return typeof value === "function" ? value.bind(target) : value;
21-
},
22-
};
23-
2414
/**
2515
* Create a lightweight request proxy that overrides only the URL.
2616
*
2717
* Avoids cloning the original request (no `new Request()` allocation).
2818
*/
2919
export function requestWithURL(req: ServerRequest, url: string): ServerRequest {
30-
const proxy = new Proxy(req, _proxyHandler);
31-
_urlOverrides.set(proxy, url);
32-
return proxy;
20+
const cache: Record<string | symbol, unknown> = { url };
21+
return new Proxy(req, {
22+
get(target, prop) {
23+
if (prop in cache) return cache[prop];
24+
const value = Reflect.get(target, prop);
25+
cache[prop] = typeof value === "function" ? value.bind(target) : value;
26+
return cache[prop];
27+
},
28+
});
3329
}
3430

3531
/**

test/bench/request-proxy.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import { bench, summary, compact, run } from "mitata";
2+
import { requestWithURL } from "../../src/utils/request.ts";
3+
4+
const req = new Request("http://localhost:3000/base/path?q=1", {
5+
method: "POST",
6+
headers: { "content-type": "application/json", "x-custom": "value" },
7+
body: JSON.stringify({ hello: "world" }),
8+
});
9+
10+
// Pre-warmed proxy (cache populated)
11+
const warmed = requestWithURL(req, "http://localhost:3000/path?q=1");
12+
warmed.method;
13+
warmed.headers;
14+
15+
compact(() => {
16+
summary(() => {
17+
bench("new Request(url, req)", () => {
18+
const url = new URL(req.url);
19+
url.pathname = url.pathname.slice("/base".length) || "/";
20+
return new Request(url, req);
21+
});
22+
23+
bench("requestWithURL(req, url)", () => {
24+
return requestWithURL(req, "http://localhost:3000/path?q=1");
25+
});
26+
});
27+
28+
summary(() => {
29+
bench("req.url", () => req.url);
30+
bench("proxied.url (cached)", () => warmed.url);
31+
});
32+
33+
summary(() => {
34+
bench("req.method", () => req.method);
35+
bench("proxied.method (cold)", () => {
36+
const p = requestWithURL(req, "http://localhost:3000/path?q=1");
37+
return p.method;
38+
});
39+
bench("proxied.method (cached)", () => warmed.method);
40+
});
41+
42+
summary(() => {
43+
bench("req.headers.get()", () => req.headers.get("content-type"));
44+
bench("proxied.headers.get() (cold)", () => {
45+
const p = requestWithURL(req, "http://localhost:3000/path?q=1");
46+
return p.headers.get("content-type");
47+
});
48+
bench("proxied.headers.get() (cached)", () =>
49+
warmed.headers.get("content-type"),
50+
);
51+
});
52+
});
53+
54+
await run({ throw: true });

0 commit comments

Comments
 (0)