@@ -74,6 +74,7 @@ const responseViaCache = async (
74
74
header = buildOutgoingHttpHeaders ( header )
75
75
}
76
76
77
+ // in `responseViaCache`, if body is not stream, Transfer-Encoding is considered not chunked
77
78
if ( typeof body === 'string' ) {
78
79
header [ 'Content-Length' ] = Buffer . byteLength ( body )
79
80
} else if ( body instanceof Uint8Array ) {
@@ -131,43 +132,45 @@ const responseViaResponseObject = async (
131
132
let done = false
132
133
let currentReadPromise : Promise < ReadableStreamReadResult < Uint8Array > > | undefined = undefined
133
134
134
- // In the case of synchronous responses, usually a maximum of two (or three in special cases) readings is done
135
- let maxReadCount = 2
136
- for ( let i = 0 ; i < maxReadCount ; i ++ ) {
137
- currentReadPromise ||= reader . read ( )
138
- const chunk = await readWithoutBlocking ( currentReadPromise ) . catch ( ( e ) => {
139
- console . error ( e )
140
- done = true
141
- } )
142
- if ( ! chunk ) {
143
- if ( i === 1 && resHeaderRecord [ 'transfer-encoding' ] !== 'chunked' ) {
144
- // XXX: In Node.js v24, some response bodies are not read all the way through until the next task queue,
145
- // so wait a moment and retry. (e.g. new Blob([new Uint8Array(contents)]) )
146
- await new Promise ( ( resolve ) => setTimeout ( resolve ) )
147
- maxReadCount = 3
148
- continue
135
+ if ( resHeaderRecord [ 'transfer-encoding' ] !== 'chunked' ) {
136
+ // In the case of synchronous responses, usually a maximum of two (or three in special cases) readings is done
137
+ let maxReadCount = 2
138
+ for ( let i = 0 ; i < maxReadCount ; i ++ ) {
139
+ currentReadPromise ||= reader . read ( )
140
+ const chunk = await readWithoutBlocking ( currentReadPromise ) . catch ( ( e ) => {
141
+ console . error ( e )
142
+ done = true
143
+ } )
144
+ if ( ! chunk ) {
145
+ if ( i === 1 ) {
146
+ // XXX: In Node.js v24, some response bodies are not read all the way through until the next task queue,
147
+ // so wait a moment and retry. (e.g. new Blob([new Uint8Array(contents)]) )
148
+ await new Promise ( ( resolve ) => setTimeout ( resolve ) )
149
+ maxReadCount = 3
150
+ continue
151
+ }
152
+
153
+ // Error occurred or currentReadPromise is not yet resolved.
154
+ // If an error occurs, immediately break the loop.
155
+ // If currentReadPromise is not yet resolved, pass it to writeFromReadableStreamDefaultReader.
156
+ break
149
157
}
158
+ currentReadPromise = undefined
150
159
151
- // Error occurred or currentReadPromise is not yet resolved.
152
- // If an error occurs, immediately break the loop.
153
- // If currentReadPromise is not yet resolved, pass it to writeFromReadableStreamDefaultReader.
154
- break
160
+ if ( chunk . value ) {
161
+ values . push ( chunk . value )
162
+ }
163
+ if ( chunk . done ) {
164
+ done = true
165
+ break
166
+ }
155
167
}
156
- currentReadPromise = undefined
157
168
158
- if ( chunk . value ) {
159
- values . push ( chunk . value )
160
- }
161
- if ( chunk . done ) {
162
- done = true
163
- break
169
+ if ( done && ! ( 'content-length' in resHeaderRecord ) ) {
170
+ resHeaderRecord [ 'content-length' ] = values . reduce ( ( acc , value ) => acc + value . length , 0 )
164
171
}
165
172
}
166
173
167
- if ( done && ! ( 'content-length' in resHeaderRecord ) ) {
168
- resHeaderRecord [ 'content-length' ] = values . reduce ( ( acc , value ) => acc + value . length , 0 )
169
- }
170
-
171
174
outgoing . writeHead ( res . status , resHeaderRecord )
172
175
values . forEach ( ( value ) => {
173
176
; ( outgoing as Writable ) . write ( value )
0 commit comments