From b58725c4c014ed24ed89e5452993da486df1601b Mon Sep 17 00:00:00 2001 From: Robert Nagy Date: Mon, 21 Sep 2020 12:24:35 +0200 Subject: [PATCH] http: lazy create IncomingMessage.headers When rawHeaders is enough don't create the headers object. PR-URL: https://github.com/nodejs/node/pull/35281 Reviewed-By: Matteo Collina Reviewed-By: James M Snell --- lib/_http_incoming.js | 62 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 56 insertions(+), 6 deletions(-) diff --git a/lib/_http_incoming.js b/lib/_http_incoming.js index a33d75c3e7900e..05359b9f48b3ef 100644 --- a/lib/_http_incoming.js +++ b/lib/_http_incoming.js @@ -24,10 +24,16 @@ const { ObjectDefineProperty, ObjectSetPrototypeOf, + Symbol } = primordials; 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) socket.resume(); @@ -58,9 +64,11 @@ function IncomingMessage(socket) { this.httpVersionMinor = null; this.httpVersion = null; this.complete = false; - this.headers = {}; + this[kHeaders] = null; + this[kHeadersCount] = 0; this.rawHeaders = []; - this.trailers = {}; + this[kTrailers] = null; + this[kTrailersCount] = 0; this.rawTrailers = []; this.aborted = false; @@ -93,6 +101,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 < this[kHeadersCount]; 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 < this[kTrailersCount]; 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); @@ -131,14 +177,18 @@ function _addHeaderLines(headers, n) { let dest; if (this.complete) { this.rawTrailers = headers; - dest = this.trailers; + this[kTrailersCount] = n; + dest = this[kTrailers]; } else { this.rawHeaders = headers; - dest = this.headers; + this[kHeadersCount] = n; + 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); + } } } }