@@ -82,6 +82,8 @@ let debug = require('internal/util/debuglog').debuglog('http', (fn) => {
82
82
} ) ;
83
83
84
84
const kCorked = Symbol ( 'corked' ) ;
85
+ const kChunkedBuffer = Symbol ( 'kChunkedBuffer' ) ;
86
+ const kChunkedLength = Symbol ( 'kChunkedLength' ) ;
85
87
const kUniqueHeaders = Symbol ( 'kUniqueHeaders' ) ;
86
88
const kBytesWritten = Symbol ( 'kBytesWritten' ) ;
87
89
const kErrored = Symbol ( 'errored' ) ;
@@ -140,6 +142,8 @@ function OutgoingMessage(options) {
140
142
this . finished = false ;
141
143
this . _headerSent = false ;
142
144
this [ kCorked ] = 0 ;
145
+ this [ kChunkedBuffer ] = [ ] ;
146
+ this [ kChunkedLength ] = 0 ;
143
147
this . _closed = false ;
144
148
145
149
this . socket = null ;
@@ -206,8 +210,7 @@ ObjectDefineProperty(OutgoingMessage.prototype, 'writableHighWaterMark', {
206
210
ObjectDefineProperty ( OutgoingMessage . prototype , 'writableCorked' , {
207
211
__proto__ : null ,
208
212
get ( ) {
209
- const corked = this . socket ? this . socket . writableCorked : 0 ;
210
- return corked + this [ kCorked ] ;
213
+ return this [ kCorked ] ;
211
214
} ,
212
215
} ) ;
213
216
@@ -299,19 +302,49 @@ OutgoingMessage.prototype._renderHeaders = function _renderHeaders() {
299
302
} ;
300
303
301
304
OutgoingMessage . prototype . cork = function ( ) {
305
+ this [ kCorked ] ++ ;
302
306
if ( this . socket ) {
303
307
this . socket . cork ( ) ;
304
- } else {
305
- this [ kCorked ] ++ ;
306
308
}
307
309
} ;
308
310
309
311
OutgoingMessage . prototype . uncork = function ( ) {
312
+ this [ kCorked ] -- ;
310
313
if ( this . socket ) {
311
314
this . socket . uncork ( ) ;
312
- } else if ( this [ kCorked ] ) {
313
- this [ kCorked ] -- ;
314
315
}
316
+
317
+ if ( this [ kCorked ] || this [ kChunkedBuffer ] . length === 0 ) {
318
+ return ;
319
+ }
320
+
321
+ const len = this [ kChunkedLength ] ;
322
+ const buf = this [ kChunkedBuffer ] ;
323
+
324
+ if ( this . chunkedEncoding ) {
325
+ let callbacks ;
326
+ this . _send ( NumberPrototypeToString ( len , 16 ) , 'latin1' , null ) ;
327
+ this . _send ( crlf_buf , null , null ) ;
328
+ for ( let n = 0 ; n < buf . length ; n += 3 ) {
329
+ this . _send ( buf [ n + 0 ] , buf [ n + 1 ] , null ) ;
330
+ if ( buf [ n + 2 ] ) {
331
+ callbacks ??= [ ] ;
332
+ callbacks . push ( buf [ n + 2 ] ) ;
333
+ }
334
+ }
335
+ this . _send ( crlf_buf , null , callbacks . length ? ( err ) => {
336
+ for ( const callback of callbacks ) {
337
+ callback ( err ) ;
338
+ }
339
+ } : null ) ;
340
+ } else {
341
+ for ( let n = 0 ; n < buf . length ; n += 3 ) {
342
+ this . _send ( buf [ n + 0 ] , buf [ n + 1 ] , buf [ n + 2 ] ) ;
343
+ }
344
+ }
345
+
346
+ this [ kChunkedBuffer ] . length = 0 ;
347
+ this [ kChunkedLength ] = 0 ;
315
348
} ;
316
349
317
350
OutgoingMessage . prototype . setTimeout = function setTimeout ( msecs , callback ) {
@@ -936,14 +969,19 @@ function write_(msg, chunk, encoding, callback, fromEnd) {
936
969
}
937
970
938
971
let ret ;
939
- if ( msg . chunkedEncoding && chunk . length !== 0 ) {
972
+ if ( msg [ kCorked ] && msg . _headerSent ) {
973
+ len ??= typeof chunk === 'string' ? Buffer . byteLength ( chunk , encoding ) : chunk . byteLength ;
974
+ msg [ kChunkedBuffer ] . push ( chunk , encoding , callback ) ;
975
+ msg [ kChunkedLength ] += len ;
976
+ ret = msg [ kChunkedLength ] < msg [ kHighWaterMark ] ;
977
+ } else if ( msg . chunkedEncoding && chunk . length !== 0 ) {
940
978
len ??= typeof chunk === 'string' ? Buffer . byteLength ( chunk , encoding ) : chunk . byteLength ;
941
979
msg . _send ( NumberPrototypeToString ( len , 16 ) , 'latin1' , null ) ;
942
980
msg . _send ( crlf_buf , null , null ) ;
943
- msg . _send ( chunk , encoding , null , len ) ;
981
+ msg . _send ( chunk , encoding , null ) ;
944
982
ret = msg . _send ( crlf_buf , null , callback ) ;
945
983
} else {
946
- ret = msg . _send ( chunk , encoding , callback , len ) ;
984
+ ret = msg . _send ( chunk , encoding , callback ) ;
947
985
}
948
986
949
987
debug ( 'write ret = ' + ret ) ;
@@ -1068,7 +1106,8 @@ OutgoingMessage.prototype.end = function end(chunk, encoding, callback) {
1068
1106
this . socket . _writableState . corked = 1 ;
1069
1107
this . socket . uncork ( ) ;
1070
1108
}
1071
- this [ kCorked ] = 0 ;
1109
+ this [ kCorked ] = 1 ;
1110
+ this . uncork ( ) ;
1072
1111
1073
1112
this . finished = true ;
1074
1113
0 commit comments