Skip to content

Commit 9e82b00

Browse files
authored
fix(server): if res was piped, res should be treated as sent (#6123)
1 parent e0cb246 commit 9e82b00

File tree

3 files changed

+30
-10
lines changed

3 files changed

+30
-10
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@modern-js/server-core': patch
3+
---
4+
5+
fix(server): if res was piped, res should be treated as sent
6+
fix(server): 如果响应被 pipe,响应应该被当作已经发送

packages/server/core/src/adapters/node/hono.ts

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ type NodeBindings = {
1616
__templates?: Record<string, string>;
1717
__serverManifest?: ServerManifest;
1818
};
19-
res: NodeResponse;
19+
res: NodeResponse & {
20+
_modernBodyPiped?: boolean;
21+
};
2022
};
2123
};
2224

@@ -34,18 +36,26 @@ type Handler = (req: NodeRequest, res: NodeResponse) => void | Promise<void>;
3436
export const httpCallBack2HonoMid = (handler: Handler) => {
3537
return async (context: Context<ServerNodeEnv & ServerEnv>, next: Next) => {
3638
const { req, res } = context.env.node;
39+
const onPipe = () => {
40+
res._modernBodyPiped = true;
41+
};
42+
res.once('pipe', onPipe);
3743
// for bff.enableHandleWeb
3844
req.__honoRequest = context.req;
3945
req.__templates = context.get('templates') || {};
4046
req.__serverManifest = context.get('serverManifest') || {};
41-
await handler(req, res);
42-
// make sure res.headersSent is set, because when using pipe, headersSent is not set immediately
43-
await new Promise(resolve => setTimeout(resolve, 0));
44-
// Avoid memory leaks in node versions 18 and 20
45-
delete req.__honoRequest;
46-
delete req.__templates;
47-
delete req.__serverManifest;
48-
if (res.headersSent) {
47+
48+
try {
49+
await handler(req, res);
50+
} finally {
51+
// Avoid memory leaks in node versions 18 and 20
52+
delete req.__honoRequest;
53+
delete req.__templates;
54+
delete req.__serverManifest;
55+
res.removeListener('pipe', onPipe);
56+
}
57+
58+
if (res.headersSent || res._modernBodyPiped) {
4959
context.finalized = true;
5060
} else {
5161
await next();

packages/server/core/src/adapters/node/node.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,11 @@ const getRequestListener = (handler: RequestHandler) => {
129129
* ```
130130
*/
131131

132-
if (!res.headersSent && !(response as any).res) {
132+
if (
133+
!res.headersSent &&
134+
!(response as any).res &&
135+
!(res as any)._modernBodyPiped
136+
) {
133137
await sendResponse(response, res);
134138
}
135139
} catch (error) {

0 commit comments

Comments
 (0)