diff --git a/lib/_http_common.js b/lib/_http_common.js index 312c2d7c569491..019b73a1ff225e 100644 --- a/lib/_http_common.js +++ b/lib/_http_common.js @@ -59,9 +59,11 @@ const MAX_HEADER_PAIRS = 2000; // called to process trailing HTTP headers. function parserOnHeaders(headers, url) { // Once we exceeded headers limit - stop collecting them - if (this.maxHeaderPairs <= 0 || - this._headers.length < this.maxHeaderPairs) { + const capacity = this.maxHeaderPairs - this._headers.length; + if (this.maxHeaderPairs <= 0 || capacity >= headers.length) { this._headers.push(...headers); + } else if (capacity > 0) { + this._headers.push(...headers.slice(0, capacity)); } this._url += url; } diff --git a/test/parallel/test-http-rawheaders-limit.js b/test/parallel/test-http-rawheaders-limit.js new file mode 100644 index 00000000000000..2adf6c7e527f5a --- /dev/null +++ b/test/parallel/test-http-rawheaders-limit.js @@ -0,0 +1,26 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); +const net = require('net'); + +const server = http.createServer(common.mustCall((req, res) => { + const limit = server.maxHeadersCount * 2; + assert.ok(req.rawHeaders.length <= limit, + `rawHeaders.length (${req.rawHeaders.length}) exceeds limit (${limit})`); + res.end(); + server.close(); +})); + +server.maxHeadersCount = 50; + +server.listen(0, common.mustCall(() => { + const port = server.address().port; + const headers = Array.from({ length: 65 }, (_, i) => `X-${i}:v`).join('\r\n'); + const req = `GET / HTTP/1.1\r\nHost: localhost\r\n${headers}\r\n\r\n`; + + net.createConnection(port, 'localhost', function() { + this.write(req); + this.once('data', () => this.end()); + }); +}));