@@ -16,6 +16,7 @@ const closeExpression = /close/i;
16
16
const contentLengthExpression = / ^ C o n t e n t - L e n g t h $ / i;
17
17
const dateExpression = / ^ D a t e $ / i;
18
18
const expectExpression = / ^ E x p e c t $ / i;
19
+ const trailerExpression = / ^ T r a i l e r $ / i;
19
20
20
21
const automaticHeaders = {
21
22
connection : true ,
@@ -56,6 +57,7 @@ function OutgoingMessage() {
56
57
this . sendDate = false ;
57
58
this . _removedHeader = { } ;
58
59
60
+ this . _contentLength = null ;
59
61
this . _hasBody = true ;
60
62
this . _trailer = '' ;
61
63
@@ -185,6 +187,7 @@ OutgoingMessage.prototype._storeHeader = function(firstLine, headers) {
185
187
sentTransferEncodingHeader : false ,
186
188
sentDateHeader : false ,
187
189
sentExpect : false ,
190
+ sentTrailer : false ,
188
191
messageHeader : firstLine
189
192
} ;
190
193
@@ -257,16 +260,26 @@ OutgoingMessage.prototype._storeHeader = function(firstLine, headers) {
257
260
258
261
if ( state . sentContentLengthHeader === false &&
259
262
state . sentTransferEncodingHeader === false ) {
260
- if ( this . _hasBody && ! this . _removedHeader [ 'transfer-encoding' ] ) {
261
- if ( this . useChunkedEncodingByDefault ) {
263
+ if ( ! this . _hasBody ) {
264
+ // Make sure we don't end the 0\r\n\r\n at the end of the message.
265
+ this . chunkedEncoding = false ;
266
+ } else if ( ! this . useChunkedEncodingByDefault ) {
267
+ this . _last = true ;
268
+ } else {
269
+ if ( ! state . sentTrailer &&
270
+ ! this . _removedHeader [ 'content-length' ] &&
271
+ typeof this . _contentLength === 'number' ) {
272
+ state . messageHeader += 'Content-Length: ' + this . _contentLength +
273
+ '\r\n' ;
274
+ } else if ( ! this . _removedHeader [ 'transfer-encoding' ] ) {
262
275
state . messageHeader += 'Transfer-Encoding: chunked\r\n' ;
263
276
this . chunkedEncoding = true ;
264
277
} else {
265
- this . _last = true ;
278
+ // We should only be able to get here if both Content-Length and
279
+ // Transfer-Encoding are removed by the user.
280
+ // See: test/parallel/test-http-remove-header-stays-removed.js
281
+ debug ( 'Both Content-Length and Transfer-Encoding are removed' ) ;
266
282
}
267
- } else {
268
- // Make sure we don't end the 0\r\n\r\n at the end of the message.
269
- this . chunkedEncoding = false ;
270
283
}
271
284
}
272
285
@@ -304,6 +317,8 @@ function storeHeader(self, state, field, value) {
304
317
state . sentDateHeader = true ;
305
318
} else if ( expectExpression . test ( field ) ) {
306
319
state . sentExpect = true ;
320
+ } else if ( trailerExpression . test ( field ) ) {
321
+ state . sentTrailer = true ;
307
322
}
308
323
}
309
324
@@ -509,6 +524,14 @@ OutgoingMessage.prototype.end = function(data, encoding, callback) {
509
524
this . once ( 'finish' , callback ) ;
510
525
511
526
if ( ! this . _header ) {
527
+ if ( data ) {
528
+ if ( typeof data === 'string' )
529
+ this . _contentLength = Buffer . byteLength ( data , encoding ) ;
530
+ else
531
+ this . _contentLength = data . length ;
532
+ } else {
533
+ this . _contentLength = 0 ;
534
+ }
512
535
this . _implicitHeader ( ) ;
513
536
}
514
537
0 commit comments