@@ -16,6 +16,7 @@ const closeExpression = /close/i;
1616const contentLengthExpression = / ^ C o n t e n t - L e n g t h $ / i;
1717const dateExpression = / ^ D a t e $ / i;
1818const expectExpression = / ^ E x p e c t $ / i;
19+ const trailerExpression = / ^ T r a i l e r $ / i;
1920
2021const automaticHeaders = {
2122 connection : true ,
@@ -56,6 +57,7 @@ function OutgoingMessage() {
5657 this . sendDate = false ;
5758 this . _removedHeader = { } ;
5859
60+ this . _contentLength = null ;
5961 this . _hasBody = true ;
6062 this . _trailer = '' ;
6163
@@ -185,6 +187,7 @@ OutgoingMessage.prototype._storeHeader = function(firstLine, headers) {
185187 sentTransferEncodingHeader : false ,
186188 sentDateHeader : false ,
187189 sentExpect : false ,
190+ sentTrailer : false ,
188191 messageHeader : firstLine
189192 } ;
190193
@@ -257,16 +260,26 @@ OutgoingMessage.prototype._storeHeader = function(firstLine, headers) {
257260
258261 if ( state . sentContentLengthHeader === false &&
259262 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' ] ) {
262275 state . messageHeader += 'Transfer-Encoding: chunked\r\n' ;
263276 this . chunkedEncoding = true ;
264277 } 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' ) ;
266282 }
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 ;
270283 }
271284 }
272285
@@ -304,6 +317,8 @@ function storeHeader(self, state, field, value) {
304317 state . sentDateHeader = true ;
305318 } else if ( expectExpression . test ( field ) ) {
306319 state . sentExpect = true ;
320+ } else if ( trailerExpression . test ( field ) ) {
321+ state . sentTrailer = true ;
307322 }
308323}
309324
@@ -509,6 +524,14 @@ OutgoingMessage.prototype.end = function(data, encoding, callback) {
509524 this . once ( 'finish' , callback ) ;
510525
511526 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+ }
512535 this . _implicitHeader ( ) ;
513536 }
514537
0 commit comments