Skip to content

Commit db6dc43

Browse files
author
vhess
committed
fix body streaming and some tests
1 parent 3128888 commit db6dc43

File tree

3 files changed

+25
-10
lines changed

3 files changed

+25
-10
lines changed

lib/http-proxy/passes/web-incoming.ts

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -283,9 +283,14 @@ async function stream2(
283283

284284
const outgoingOptions = common.setupOutgoing(options.ssl || {}, options, req);
285285

286+
// Remove symbols from headers as undici fetch does not like them
286287
const requestOptions: RequestInit = {
287288
method: outgoingOptions.method as Dispatcher.HttpMethod,
288-
headers: outgoingOptions.headers as Record<string, string>,
289+
headers: Object.fromEntries(
290+
Object.entries(outgoingOptions.headers || {}).filter(([key, _value]) => {
291+
return typeof key === "string";
292+
})
293+
) as RequestInit["headers"],
289294
...fetchOptions.requestOptions
290295
};
291296

@@ -314,7 +319,7 @@ async function stream2(
314319
}
315320

316321
try {
317-
const response = await fetch(outgoingOptions.url, requestOptions);
322+
const response = await fetch(new URL(outgoingOptions.path ?? "/", outgoingOptions.url), requestOptions);
318323

319324
// Call onAfterResponse callback after receiving the response
320325
if (fetchOptions.onAfterResponse) {
@@ -331,14 +336,19 @@ async function stream2(
331336
// But since only certain properties are used, we can fake it here
332337
// to avoid having to refactor everything.
333338
const fakeProxyRes = {
334-
...response, rawHeaders: Object.entries(response.headers).flatMap(([key, value]) => {
339+
statusCode: response.status,
340+
statusMessage: response.statusText,
341+
headers: Object.fromEntries(response.headers.entries()),
342+
rawHeaders: Object.entries(response.headers).flatMap(([key, value]) => {
335343
if (Array.isArray(value)) {
336344
return value.flatMap(v => (v != null ? [key, v] : []));
337345
}
338346
return value != null ? [key, value] : [];
339347
}) as string[]
340348
} as unknown as ProxyResponse;
341349

350+
server?.emit("proxyRes", fakeProxyRes, req, res);
351+
342352
if (!res.headersSent && !options.selfHandleResponse) {
343353
for (const pass of web_o) {
344354
// note: none of these return anything
@@ -353,12 +363,19 @@ async function stream2(
353363
: null;
354364

355365
if (nodeStream) {
366+
nodeStream.on("error", (err) => {
367+
handleError(err, options.target);
368+
});
369+
356370
nodeStream.on("end", () => {
357371
server?.emit("end", req, res, fakeProxyRes);
358372
});
373+
359374
// We pipe to the response unless its expected to be handled by the user
360375
if (!options.selfHandleResponse) {
361-
nodeStream.pipe(res);
376+
nodeStream.pipe(res, { end: true });
377+
} else {
378+
nodeStream.resume();
362379
}
363380
} else {
364381
server?.emit("end", req, res, fakeProxyRes);

lib/test/http/proxy-callbacks.test.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ describe("Undici callback functions (onBeforeRequest and onAfterResponse)", () =
4141
it("Test onBeforeRequest and onAfterResponse callbacks", async () => {
4242
let onBeforeRequestCalled = false;
4343
let onAfterResponseCalled = false;
44-
let capturedResponse: unknown = {};
44+
let capturedResponse: Response = {} as Response;
4545

4646
const proxy = httpProxy.createServer({
4747
target: `http://localhost:${ports.target}`,
@@ -83,10 +83,9 @@ describe("Undici callback functions (onBeforeRequest and onAfterResponse)", () =
8383
expect(onAfterResponseCalled).toBe(true);
8484

8585
// Check that we received the full response object
86-
expect(capturedResponse).toHaveProperty('statusCode');
87-
expect((capturedResponse as { statusCode: number }).statusCode).toBe(200);
86+
expect(capturedResponse).toHaveProperty('status');
87+
expect((capturedResponse).status).toBe(200);
8888
expect(capturedResponse).toHaveProperty('headers');
89-
expect((capturedResponse as { headers: Record<string, string> }).headers).toHaveProperty('x-target-header');
90-
expect((capturedResponse as { headers: Record<string, string> }).headers['x-target-header']).toBe('from-target');
89+
expect((capturedResponse).headers.get('x-target-header')).toBe('from-target');
9190
});
9291
});

lib/test/lib/http-proxy-passes-web-incoming.test.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,6 @@ describe("#createProxyServer.web() using own http server", () => {
306306
target: address(8083),
307307
proxyTimeout: 100,
308308
timeout: 150, // so client exits and isn't left handing the test.
309-
fetch: true
310309
});
311310

312311
const server = require("net").createServer().listen(ports["8083"]);

0 commit comments

Comments
 (0)