From 3417e0bb0ed112aa0b15f278c481eaa5d6275d3d Mon Sep 17 00:00:00 2001 From: Robert Nagy Date: Mon, 21 Sep 2020 12:24:35 +0200 Subject: [PATCH 1/3] http: lazy create IncomingMessage.headers When rawHeaders is enough don't create the headers object. --- lib/_http_incoming.js | 56 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 6 deletions(-) diff --git a/lib/_http_incoming.js b/lib/_http_incoming.js index 59136833c6b340..9779edeb810702 100644 --- a/lib/_http_incoming.js +++ b/lib/_http_incoming.js @@ -24,10 +24,14 @@ const { ObjectDefineProperty, ObjectSetPrototypeOf, + Symbol } = primordials; const Stream = require('stream'); +const kHeaders = Symbol('kHeaders'); +const kTrailers = Symbol('kTrailers'); + function readStart(socket) { if (socket && !socket._paused && socket.readable) socket.resume(); @@ -58,9 +62,9 @@ function IncomingMessage(socket) { this.httpVersionMinor = null; this.httpVersion = null; this.complete = false; - this.headers = {}; + this[kHeaders] = null; this.rawHeaders = []; - this.trailers = {}; + this[kTrailers] = null; this.rawTrailers = []; this.aborted = false; @@ -93,6 +97,44 @@ ObjectDefineProperty(IncomingMessage.prototype, 'connection', { } }); +ObjectDefineProperty(IncomingMessage.prototype, 'headers', { + get: function() { + if (!this[kHeaders]) { + this[kHeaders] = {}; + + const src = this.rawHeaders; + const dst = this[kHeaders]; + + for (let n = 0; n < src.length; n += 2) { + this._addHeaderLine(src[n + 0], src[n + 1], dst); + } + } + return this[kHeaders]; + }, + set: function(val) { + this[kHeaders] = val; + } +}); + +ObjectDefineProperty(IncomingMessage.prototype, 'trailers', { + get: function() { + if (!this[kTrailers]) { + this[kTrailers] = {}; + + const src = this.rawTrailers; + const dst = this[kTrailers]; + + for (let n = 0; n < src.length; n += 2) { + this._addHeaderLine(src[n + 0], src[n + 1], dst); + } + } + return this[kTrailers]; + }, + set: function(val) { + this[kTrailers] = val; + } +}); + IncomingMessage.prototype.setTimeout = function setTimeout(msecs, callback) { if (callback) this.on('timeout', callback); @@ -133,14 +175,16 @@ function _addHeaderLines(headers, n) { let dest; if (this.complete) { this.rawTrailers = headers; - dest = this.trailers; + dest = this[kTrailers]; } else { this.rawHeaders = headers; - dest = this.headers; + dest = this[kHeaders]; } - for (let i = 0; i < n; i += 2) { - this._addHeaderLine(headers[i], headers[i + 1], dest); + if (dest) { + for (let i = 0; i < n; i += 2) { + this._addHeaderLine(headers[i], headers[i + 1], dest); + } } } } From a9cc8f8cce823bb8602f8dda87d5c21149d8d48f Mon Sep 17 00:00:00 2001 From: Robert Nagy Date: Mon, 21 Sep 2020 14:06:59 +0200 Subject: [PATCH 2/3] fixup --- lib/_http_incoming.js | 10 ++++++++-- test/parallel/test-http-max-headers-count.js | 8 ++++---- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/lib/_http_incoming.js b/lib/_http_incoming.js index 9779edeb810702..7943c69f54d911 100644 --- a/lib/_http_incoming.js +++ b/lib/_http_incoming.js @@ -30,7 +30,9 @@ const { const Stream = require('stream'); const kHeaders = Symbol('kHeaders'); +const kHeadersCount = Symbol('kHeadersCount'); const kTrailers = Symbol('kTrailers'); +const kTrailersCount = Symbol('kTrailersCount'); function readStart(socket) { if (socket && !socket._paused && socket.readable) @@ -63,8 +65,10 @@ function IncomingMessage(socket) { this.httpVersion = null; this.complete = false; this[kHeaders] = null; + this[kHeadersCount] = 0; this.rawHeaders = []; this[kTrailers] = null; + this[kTrailersCount] = 0; this.rawTrailers = []; this.aborted = false; @@ -105,7 +109,7 @@ ObjectDefineProperty(IncomingMessage.prototype, 'headers', { const src = this.rawHeaders; const dst = this[kHeaders]; - for (let n = 0; n < src.length; n += 2) { + for (let n = 0; n < this[kHeadersCount]; n += 2) { this._addHeaderLine(src[n + 0], src[n + 1], dst); } } @@ -124,7 +128,7 @@ ObjectDefineProperty(IncomingMessage.prototype, 'trailers', { const src = this.rawTrailers; const dst = this[kTrailers]; - for (let n = 0; n < src.length; n += 2) { + for (let n = 0; n < this[kTrailersCount]; n += 2) { this._addHeaderLine(src[n + 0], src[n + 1], dst); } } @@ -175,9 +179,11 @@ function _addHeaderLines(headers, n) { let dest; if (this.complete) { this.rawTrailers = headers; + this[kTrailersCount] = n; dest = this[kTrailers]; } else { this.rawHeaders = headers; + this[kHeadersCount] = n; dest = this[kHeaders]; } diff --git a/test/parallel/test-http-max-headers-count.js b/test/parallel/test-http-max-headers-count.js index 9fcfe316e392ff..de167c8ec15983 100644 --- a/test/parallel/test-http-max-headers-count.js +++ b/test/parallel/test-http-max-headers-count.js @@ -35,8 +35,8 @@ for (let i = 0; i < N; ++i) { const maxAndExpected = [ // for server [50, 50], - [1500, 102], - [0, N + 2] // Host and Connection + // [1500, 102], + // [0, N + 2] // Host and Connection ]; let max = maxAndExpected[requests][0]; let expected = maxAndExpected[requests][1]; @@ -56,8 +56,8 @@ server.maxHeadersCount = max; server.listen(0, function() { const maxAndExpected = [ // for client [20, 20], - [1200, 103], - [0, N + 3] // Connection, Date and Transfer-Encoding + // [1200, 103], + // [0, N + 3] // Connection, Date and Transfer-Encoding ]; doRequest(); From ed409516c160ec60443aa2d1c6b92f7d594556ab Mon Sep 17 00:00:00 2001 From: Robert Nagy Date: Mon, 21 Sep 2020 15:10:51 +0200 Subject: [PATCH 3/3] fixup --- test/parallel/test-http-max-headers-count.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/parallel/test-http-max-headers-count.js b/test/parallel/test-http-max-headers-count.js index de167c8ec15983..9fcfe316e392ff 100644 --- a/test/parallel/test-http-max-headers-count.js +++ b/test/parallel/test-http-max-headers-count.js @@ -35,8 +35,8 @@ for (let i = 0; i < N; ++i) { const maxAndExpected = [ // for server [50, 50], - // [1500, 102], - // [0, N + 2] // Host and Connection + [1500, 102], + [0, N + 2] // Host and Connection ]; let max = maxAndExpected[requests][0]; let expected = maxAndExpected[requests][1]; @@ -56,8 +56,8 @@ server.maxHeadersCount = max; server.listen(0, function() { const maxAndExpected = [ // for client [20, 20], - // [1200, 103], - // [0, N + 3] // Connection, Date and Transfer-Encoding + [1200, 103], + [0, N + 3] // Connection, Date and Transfer-Encoding ]; doRequest();