Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion lib/response.js
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,11 @@ res.send = function send(body) {
len = chunk.length
}

this.set('Content-Length', len);
// Because Content-Length and Transfer-Encoding can't be present in the response headers together,
// Content-Length should be added only if there is no Transfer-Encoding header
if (!this.get('Transfer-Encoding')) {
this.set('Content-Length', len);
}
}

// populate ETag
Expand Down
33 changes: 33 additions & 0 deletions test/res.send.js
Original file line number Diff line number Diff line change
Expand Up @@ -597,5 +597,38 @@ describe('res', function(){
.expect(200, done);
})
})

describe('when Transfer-Encoding is set', function () {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this also carry over the tests from #4893? They cover an empty body (send('')) and the other Transfer-Encoding values (compress, deflate, gzip), which this test doesn't:

describe('when Transfer-Encoding header is present', function(){
  ['chunked', 'compress', 'deflate', 'gzip'].forEach(function(encoding){
    it('should not add Content-Length header if Transfer-Encoding header is equal to ' + encoding, function(done){
      var app = express();
      app.use(function(_, res){
        res.status(200).set('Transfer-Encoding', encoding).send('');
      });
      request(app)
        .get('/')
        .expect(utils.shouldNotHaveHeader('Content-Length'))
        .expect(utils.shouldHaveHeader('Transfer-Encoding'))
        .expect(200, '', done);
    })
  });
})

I ran them against this branch unchanged and all 4 pass, so it's just for coverage parity with master.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good idea @kgeminicdev, i ported the four encoding cases from #4893 so chunked, compress, deflate and gzip are all covered now, and i reverted lib/response.js on the branch to be sure they bite, all five fail with the same Content-Length and Transfer-Encoding parse error without the fix, then pass with it, full test/res.send.js run is 76 passing and the whole test folder is 1222 passing, pushed as a separate commit a308170 so the sha you reviewed is still the one you tested

['chunked', 'compress', 'deflate', 'gzip'].forEach(function (encoding) {
it('should not add Content-Length header if Transfer-Encoding header is equal to ' + encoding, function (done) {
var app = express();

app.use(function (_, res) {
res.status(200).set('Transfer-Encoding', encoding).send('');
});

request(app)
.get('/')
.expect(utils.shouldNotHaveHeader('Content-Length'))
.expect(utils.shouldHaveHeader('Transfer-Encoding'))
.expect(200, '', done);
})
})

it('should not set Content-Length and still generate an ETag', function (done) {
var app = express();

app.use(function (req, res) {
res.set('Transfer-Encoding', 'chunked').send('hello');
});

request(app)
.get('/')
.expect(utils.shouldNotHaveHeader('Content-Length'))
.expect(utils.shouldHaveHeader('Transfer-Encoding'))
.expect('ETag', 'W/"5-qvTGHdzF6KLavt4PO0gs2a6pQ00"')
.expect(200, 'hello', done);
})
})
})
})