@@ -16,7 +16,9 @@ type NodeBindings = {
16
16
__templates ?: Record < string , string > ;
17
17
__serverManifest ?: ServerManifest ;
18
18
} ;
19
- res : NodeResponse ;
19
+ res : NodeResponse & {
20
+ _modernBodyPiped ?: boolean ;
21
+ } ;
20
22
} ;
21
23
} ;
22
24
@@ -34,18 +36,26 @@ type Handler = (req: NodeRequest, res: NodeResponse) => void | Promise<void>;
34
36
export const httpCallBack2HonoMid = ( handler : Handler ) => {
35
37
return async ( context : Context < ServerNodeEnv & ServerEnv > , next : Next ) => {
36
38
const { req, res } = context . env . node ;
39
+ const onPipe = ( ) => {
40
+ res . _modernBodyPiped = true ;
41
+ } ;
42
+ res . once ( 'pipe' , onPipe ) ;
37
43
// for bff.enableHandleWeb
38
44
req . __honoRequest = context . req ;
39
45
req . __templates = context . get ( 'templates' ) || { } ;
40
46
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 ) {
49
59
context . finalized = true ;
50
60
} else {
51
61
await next ( ) ;
0 commit comments