diff --git a/lib/_http_agent.js b/lib/_http_agent.js index 686d561b283d89..fb97b6e6534362 100644 --- a/lib/_http_agent.js +++ b/lib/_http_agent.js @@ -22,10 +22,21 @@ 'use strict'; const { + ArrayPrototypeIncludes, + ArrayPrototypeIndexOf, + ArrayPrototypePop, + ArrayPrototypePush, + ArrayPrototypeShift, + ArrayPrototypeSplice, + FunctionPrototypeCall, NumberIsNaN, ObjectKeys, ObjectSetPrototypeOf, ObjectValues, + StringPrototypeIndexOf, + StringPrototypeSplit, + StringPrototypeStartsWith, + StringPrototypeSubstr, Symbol, } = primordials; @@ -78,7 +89,7 @@ function Agent(options) { if (!(this instanceof Agent)) return new Agent(options); - EventEmitter.call(this); + FunctionPrototypeCall(EventEmitter, this); this.defaultPort = 80; this.protocol = 'http:'; @@ -125,7 +136,7 @@ function Agent(options) { const requests = this.requests[name]; if (requests && requests.length) { - const req = requests.shift(); + const req = ArrayPrototypeShift(requests); const reqAsyncRes = req[kRequestAsyncResource]; if (reqAsyncRes) { // Run request within the original async context. @@ -171,7 +182,7 @@ function Agent(options) { this.removeSocket(socket, options); socket.once('error', freeSocketErrorListener); - freeSockets.push(socket); + ArrayPrototypePush(freeSockets, socket); }); // Don't emit keylog events unless there is a listener for them. @@ -249,11 +260,11 @@ Agent.prototype.addRequest = function addRequest(req, options, port/* legacy */, let socket; if (freeSockets) { while (freeSockets.length && freeSockets[0].destroyed) { - freeSockets.shift(); + ArrayPrototypeShift(freeSockets); } socket = this.scheduling === 'fifo' ? - freeSockets.shift() : - freeSockets.pop(); + ArrayPrototypeShift(freeSockets) : + ArrayPrototypePop(freeSockets); if (!freeSockets.length) delete this.freeSockets[name]; } @@ -265,7 +276,7 @@ Agent.prototype.addRequest = function addRequest(req, options, port/* legacy */, asyncResetHandle(socket); this.reuseSocket(socket, req); setRequestSocket(this, req, socket); - this.sockets[name].push(socket); + ArrayPrototypePush(this.sockets[name], socket); this.totalSocketCount++; } else if (sockLen < this.maxSockets && this.totalSocketCount < this.maxTotalSockets) { @@ -289,7 +300,7 @@ Agent.prototype.addRequest = function addRequest(req, options, port/* legacy */, // Used to capture the original async context. req[kRequestAsyncResource] = new AsyncResource('QueuedRequest'); - this.requests[name].push(req); + ArrayPrototypePush(this.requests[name], req); } }; @@ -313,7 +324,7 @@ Agent.prototype.createSocket = function createSocket(req, options, cb) { if (!this.sockets[name]) { this.sockets[name] = []; } - this.sockets[name].push(s); + ArrayPrototypePush(this.sockets[name], s); this.totalSocketCount++; debug('sockets', name, this.sockets[name].length, this.totalSocketCount); installListeners(this, s, options); @@ -338,16 +349,16 @@ function calculateServerName(options, req) { // abc:123 => abc // [::1] => ::1 // [::1]:123 => ::1 - if (hostHeader.startsWith('[')) { - const index = hostHeader.indexOf(']'); + if (StringPrototypeStartsWith(hostHeader, '[')) { + const index = StringPrototypeIndexOf(hostHeader, ']'); if (index === -1) { // Leading '[', but no ']'. Need to do something... servername = hostHeader; } else { - servername = hostHeader.substr(1, index - 1); + servername = StringPrototypeSubstr(hostHeader, 1, index - 1); } } else { - servername = hostHeader.split(':', 1)[0]; + servername = StringPrototypeSplit(hostHeader, ':', 1)[0]; } } // Don't implicitly set invalid (IP) servernames. @@ -379,7 +390,7 @@ function installListeners(agent, s, options) { // TODO(ronag): Always destroy, even if not in free list. const sockets = agent.freeSockets; for (const name of ObjectKeys(sockets)) { - if (sockets[name].includes(s)) { + if (ArrayPrototypeIncludes(sockets[name], s)) { return s.destroy(); } } @@ -411,13 +422,13 @@ Agent.prototype.removeSocket = function removeSocket(s, options) { // If the socket was destroyed, remove it from the free buffers too. if (!s.writable) - sets.push(this.freeSockets); + ArrayPrototypePush(sets, this.freeSockets); for (const sockets of sets) { if (sockets[name]) { - const index = sockets[name].indexOf(s); + const index = ArrayPrototypeIndexOf(sockets[name], s); if (index !== -1) { - sockets[name].splice(index, 1); + ArrayPrototypeSplice(sockets[name], index, 1); // Don't leak if (sockets[name].length === 0) delete sockets[name]; diff --git a/lib/_http_client.js b/lib/_http_client.js index 6fb5dd65cb368c..6bae982eb1c97b 100644 --- a/lib/_http_client.js +++ b/lib/_http_client.js @@ -25,12 +25,20 @@ const { ArrayIsArray, Boolean, Error, + FunctionPrototypeCall, NumberIsFinite, ObjectAssign, ObjectKeys, ObjectSetPrototypeOf, + ReflectApply, + RegExpPrototypeTest, String, - Symbol + StringPrototypeCharCodeAt, + StringPrototypeIncludes, + StringPrototypeIndexOf, + StringPrototypeToUpperCase, + Symbol, + TypedArrayPrototypeSlice, } = primordials; const net = require('net'); @@ -91,7 +99,7 @@ class HTTPClientAsyncResource { let urlWarningEmitted = false; function ClientRequest(input, options, cb) { - OutgoingMessage.call(this); + FunctionPrototypeCall(OutgoingMessage, this); if (typeof input === 'string') { const urlStr = input; @@ -151,7 +159,7 @@ function ClientRequest(input, options, cb) { if (options.path) { const path = String(options.path); - if (INVALID_PATH_REGEX.test(path)) + if (RegExpPrototypeTest(INVALID_PATH_REGEX, path)) throw new ERR_UNESCAPED_CHARACTERS('Request path'); } @@ -187,7 +195,7 @@ function ClientRequest(input, options, cb) { if (!checkIsHttpToken(method)) { throw new ERR_INVALID_HTTP_TOKEN('Method', method); } - method = this.method = method.toUpperCase(); + method = this.method = StringPrototypeToUpperCase(method); } else { method = this.method = 'GET'; } @@ -266,10 +274,10 @@ function ClientRequest(input, options, cb) { // For the Host header, ensure that IPv6 addresses are enclosed // in square brackets, as defined by URI formatting // https://tools.ietf.org/html/rfc3986#section-3.2.2 - const posColon = hostHeader.indexOf(':'); + const posColon = StringPrototypeIndexOf(hostHeader, ':'); if (posColon !== -1 && - hostHeader.includes(':', posColon + 1) && - hostHeader.charCodeAt(0) !== 91/* '[' */) { + StringPrototypeIncludes(hostHeader, ':', posColon + 1) && + StringPrototypeCharCodeAt(hostHeader, 0) !== 91/* '[' */) { hostHeader = `[${hostHeader}]`; } @@ -337,7 +345,7 @@ ObjectSetPrototypeOf(ClientRequest, OutgoingMessage); ClientRequest.prototype._finish = function _finish() { DTRACE_HTTP_CLIENT_REQUEST(this, this.socket); - OutgoingMessage.prototype._finish.call(this); + FunctionPrototypeCall(OutgoingMessage.prototype._finish, this); }; ClientRequest.prototype._implicitHeader = function _implicitHeader() { @@ -547,7 +555,7 @@ function socketOnData(d) { parser.finish(); freeParser(parser, req, socket); - const bodyHead = d.slice(bytesParsed, d.length); + const bodyHead = TypedArrayPrototypeSlice(d, bytesParsed, d.length); const eventName = req.method === 'CONNECT' ? 'connect' : 'upgrade'; if (req.listenerCount(eventName) > 0) { @@ -848,7 +856,7 @@ function _deferToConnect(method, arguments_, cb) { const callSocketMethod = () => { if (method) - this.socket[method].apply(this.socket, arguments_); + ReflectApply(this.socket[method], this.socket, arguments_); if (typeof cb === 'function') cb(); diff --git a/lib/_http_common.js b/lib/_http_common.js index e97670f0acaf11..f249a86776b580 100644 --- a/lib/_http_common.js +++ b/lib/_http_common.js @@ -22,8 +22,11 @@ 'use strict'; const { + ArrayPrototypeConcat, MathMin, Symbol, + RegExpPrototypeTest, + TypedArrayPrototypeSlice, } = primordials; const { setImmediate } = require('timers'); @@ -63,7 +66,7 @@ function parserOnHeaders(headers, url) { // Once we exceeded headers limit - stop collecting them if (this.maxHeaderPairs <= 0 || this._headers.length < this.maxHeaderPairs) { - this._headers = this._headers.concat(headers); + this._headers = ArrayPrototypeConcat(this._headers, headers); } this._url += url; } @@ -135,7 +138,7 @@ function parserOnBody(b, start, len) { // Pretend this was the result of a stream._read call. if (len > 0 && !stream._dumped) { - const slice = b.slice(start, start + len); + const slice = TypedArrayPrototypeSlice(b, start, start + len); const ret = stream.push(slice); if (!ret) readStop(this.socket); @@ -217,7 +220,7 @@ const tokenRegExp = /^[\^_`a-zA-Z\-0-9!#$%&'*+.|~]+$/; * See https://tools.ietf.org/html/rfc7230#section-3.2.6 */ function checkIsHttpToken(val) { - return tokenRegExp.test(val); + return RegExpPrototypeTest(tokenRegExp, val); } const headerCharRegex = /[^\t\x20-\x7e\x80-\xff]/; @@ -228,7 +231,7 @@ const headerCharRegex = /[^\t\x20-\x7e\x80-\xff]/; * field-vchar = VCHAR / obs-text */ function checkInvalidHeaderChar(val) { - return headerCharRegex.test(val); + return RegExpPrototypeTest(headerCharRegex, val); } function cleanParser(parser) { diff --git a/lib/_http_incoming.js b/lib/_http_incoming.js index 7943c69f54d911..e166177e0d4947 100644 --- a/lib/_http_incoming.js +++ b/lib/_http_incoming.js @@ -22,8 +22,13 @@ 'use strict'; const { + ArrayPrototypePush, + FunctionPrototypeCall, ObjectDefineProperty, ObjectSetPrototypeOf, + StringPrototypeCharCodeAt, + StringPrototypeSlice, + StringPrototypeToLowerCase, Symbol } = primordials; @@ -54,7 +59,8 @@ function IncomingMessage(socket) { }; } - Stream.Readable.call(this, { autoDestroy: false, ...streamOptions }); + FunctionPrototypeCall(Stream.Readable, this, + { autoDestroy: false, ...streamOptions }); this._readableState.readingMore = true; @@ -300,7 +306,7 @@ function matchKnownFields(field, lowercased) { if (lowercased) { return '\u0000' + field; } - return matchKnownFields(field.toLowerCase(), true); + return matchKnownFields(StringPrototypeToLowerCase(field), true); } // Add the given (field, value) pair to the message // @@ -314,9 +320,9 @@ function matchKnownFields(field, lowercased) { IncomingMessage.prototype._addHeaderLine = _addHeaderLine; function _addHeaderLine(field, value, dest) { field = matchKnownFields(field); - const flag = field.charCodeAt(0); + const flag = StringPrototypeCharCodeAt(field, 0); if (flag === 0 || flag === 2) { - field = field.slice(1); + field = StringPrototypeSlice(field, 1); // Make a delimited list if (typeof dest[field] === 'string') { dest[field] += (flag === 0 ? ', ' : '; ') + value; @@ -326,7 +332,7 @@ function _addHeaderLine(field, value, dest) { } else if (flag === 1) { // Array header -- only Set-Cookie at the moment if (dest['set-cookie'] !== undefined) { - dest['set-cookie'].push(value); + ArrayPrototypePush(dest['set-cookie'], value); } else { dest['set-cookie'] = [value]; } diff --git a/lib/_http_outgoing.js b/lib/_http_outgoing.js index 8fb64ab82efceb..8b2959986af8e0 100644 --- a/lib/_http_outgoing.js +++ b/lib/_http_outgoing.js @@ -23,12 +23,21 @@ const { ArrayIsArray, + ArrayPrototypeJoin, + ArrayPrototypePush, + ArrayPrototypeUnshift, + FunctionPrototype, + FunctionPrototypeBind, + FunctionPrototypeCall, + MathFloor, + NumberPrototypeToString, ObjectCreate, ObjectDefineProperty, ObjectKeys, ObjectPrototypeHasOwnProperty, ObjectSetPrototypeOf, - MathFloor, + RegExpPrototypeTest, + StringPrototypeToLowerCase, Symbol, } = primordials; @@ -72,7 +81,7 @@ const { CRLF, debug } = common; const kCorked = Symbol('corked'); -function nop() {} +const nop = FunctionPrototype; const RE_CONN_CLOSE = /(?:^|\W)close(?:$|\W)/i; const RE_TE_CHUNKED = common.chunkExpression; @@ -81,13 +90,11 @@ const RE_TE_CHUNKED = common.chunkExpression; // against the word "cookie." As of V8 6.6 this is faster than handrolling or // using a case-insensitive RegExp. function isCookieField(s) { - return s.length === 6 && s.toLowerCase() === 'cookie'; + return s.length === 6 && StringPrototypeToLowerCase(s) === 'cookie'; } -function noopPendingOutput(amount) {} - function OutgoingMessage() { - Stream.call(this); + FunctionPrototypeCall(Stream, this); // Queue that holds all currently pending data, until the response will be // assigned to the socket (until it will its turn in the HTTP pipeline). @@ -128,7 +135,7 @@ function OutgoingMessage() { this._keepAliveTimeout = 0; - this._onPendingData = noopPendingOutput; + this._onPendingData = nop; } ObjectSetPrototypeOf(OutgoingMessage.prototype, Stream.prototype); ObjectSetPrototypeOf(OutgoingMessage, Stream); @@ -182,7 +189,7 @@ ObjectDefineProperty(OutgoingMessage.prototype, '_headers', { // Refs: https://github.com/nodejs/node/pull/30958 for (let i = 0; i < keys.length; ++i) { const name = keys[i]; - headers[name.toLowerCase()] = [name, val[name]]; + headers[StringPrototypeToLowerCase(name)] = [name, val[name]]; } } }, 'OutgoingMessage.prototype._headers is deprecated', 'DEP0066') @@ -317,7 +324,7 @@ OutgoingMessage.prototype._send = function _send(data, encoding, callback) { data = this._header + data; } else { const header = this._header; - this.outputData.unshift({ + ArrayPrototypeUnshift(this.outputData, { data: header, encoding: 'latin1', callback: null @@ -354,7 +361,7 @@ function _writeRaw(data, encoding, callback) { return conn.write(data, encoding, callback); } // Buffer, as long as we're not destroyed. - this.outputData.push({ data, encoding, callback }); + ArrayPrototypePush(this.outputData, { data, encoding, callback }); this.outputSize += data.length; this._onPendingData(data.length); return this.outputSize < HIGH_WATER_MARK; @@ -497,7 +504,7 @@ function processHeader(self, state, key, value, validate) { storeHeader(self, state, key, value[i], validate); return; } - value = value.join('; '); + value = ArrayPrototypeJoin(value, '; '); } storeHeader(self, state, key, value, validate); } @@ -512,12 +519,12 @@ function storeHeader(self, state, key, value, validate) { function matchHeader(self, state, field, value) { if (field.length < 4 || field.length > 17) return; - field = field.toLowerCase(); + field = StringPrototypeToLowerCase(field); switch (field) { case 'connection': state.connection = true; self._removedConnection = false; - if (RE_CONN_CLOSE.test(value)) + if (RegExpPrototypeTest(RE_CONN_CLOSE, value)) self._last = true; else self.shouldKeepAlive = true; @@ -525,7 +532,8 @@ function matchHeader(self, state, field, value) { case 'transfer-encoding': state.te = true; self._removedTE = false; - if (RE_TE_CHUNKED.test(value)) self.chunkedEncoding = true; + if (RegExpPrototypeTest(RE_TE_CHUNKED, value)) + self.chunkedEncoding = true; break; case 'content-length': state.contLen = true; @@ -569,7 +577,7 @@ OutgoingMessage.prototype.setHeader = function setHeader(name, value) { if (headers === null) this[kOutHeaders] = headers = ObjectCreate(null); - headers[name.toLowerCase()] = [name, value]; + headers[StringPrototypeToLowerCase(name)] = [name, value]; return this; }; @@ -581,7 +589,7 @@ OutgoingMessage.prototype.getHeader = function getHeader(name) { if (headers === null) return; - const entry = headers[name.toLowerCase()]; + const entry = headers[StringPrototypeToLowerCase(name)]; return entry && entry[1]; }; @@ -613,7 +621,7 @@ OutgoingMessage.prototype.getHeaders = function getHeaders() { OutgoingMessage.prototype.hasHeader = function hasHeader(name) { validateString(name, 'name'); return this[kOutHeaders] !== null && - !!this[kOutHeaders][name.toLowerCase()]; + !!this[kOutHeaders][StringPrototypeToLowerCase(name)]; }; @@ -624,7 +632,7 @@ OutgoingMessage.prototype.removeHeader = function removeHeader(name) { throw new ERR_HTTP_HEADERS_SENT('remove'); } - const key = name.toLowerCase(); + const key = StringPrototypeToLowerCase(name); switch (key) { case 'connection': @@ -750,7 +758,7 @@ function write_(msg, chunk, encoding, callback, fromEnd) { let ret; if (msg.chunkedEncoding && chunk.length !== 0) { - msg._send(len.toString(16), 'latin1', null); + msg._send(NumberPrototypeToString(len, 16), 'latin1', null); msg._send(crlf_buf, null, null); msg._send(chunk, encoding, null); ret = msg._send(crlf_buf, null, callback); @@ -839,7 +847,7 @@ OutgoingMessage.prototype.end = function end(chunk, encoding, callback) { if (typeof callback === 'function') this.once('finish', callback); - const finish = onFinish.bind(undefined, this); + const finish = FunctionPrototypeBind(onFinish, undefined, this); if (this._hasBody && this.chunkedEncoding) { this._send('0\r\n' + this._trailer + '\r\n', 'latin1', finish); diff --git a/lib/_http_server.js b/lib/_http_server.js index 419b08a7a0986d..f1372b56dc6c1b 100644 --- a/lib/_http_server.js +++ b/lib/_http_server.js @@ -23,11 +23,19 @@ const { ArrayIsArray, + ArrayPrototypePush, + ArrayPrototypeShift, Error, + FunctionPrototype, + FunctionPrototypeBind, + FunctionPrototypeCall, ObjectKeys, ObjectSetPrototypeOf, + ReflectApply, + RegExpPrototypeTest, Symbol, SymbolFor, + TypedArrayPrototypeSlice, } = primordials; const net = require('net'); @@ -169,7 +177,7 @@ class HTTPServerAsyncResource { } function ServerResponse(req) { - OutgoingMessage.call(this); + FunctionPrototypeCall(OutgoingMessage, this); if (req.method === 'HEAD') this._hasBody = false; @@ -178,7 +186,8 @@ function ServerResponse(req) { this._expect_continue = false; if (req.httpVersionMajor < 1 || req.httpVersionMinor < 1) { - this.useChunkedEncodingByDefault = chunkExpression.test(req.headers.te); + this.useChunkedEncodingByDefault = RegExpPrototypeTest(chunkExpression, + req.headers.te); this.shouldKeepAlive = false; } @@ -197,7 +206,7 @@ ServerResponse.prototype._finish = function _finish() { if (this[kServerResponseStatistics] !== undefined) { emitStatistics(this[kServerResponseStatistics]); } - OutgoingMessage.prototype._finish.call(this); + FunctionPrototypeCall(OutgoingMessage.prototype._finish, this); }; @@ -371,7 +380,7 @@ function Server(options, requestListener) { validateBoolean(insecureHTTPParser, 'options.insecureHTTPParser'); this.insecureHTTPParser = insecureHTTPParser; - net.Server.call(this, { allowHalfOpen: true }); + FunctionPrototypeCall(net.Server, this, { allowHalfOpen: true }); if (requestListener) { this.on('request', requestListener); @@ -417,8 +426,8 @@ Server.prototype[EE.captureRejectionSymbol] = function(err, event, ...args) { } break; default: - net.Server.prototype[SymbolFor('nodejs.rejection')] - .call(this, err, event, ...args); + ReflectApply(net.Server.prototype[SymbolFor('nodejs.rejection')], + this, arguments); } }; @@ -477,16 +486,21 @@ function connectionListenerInternal(server, socket) { outgoingData: 0, keepAliveTimeoutSet: false }; - state.onData = socketOnData.bind(undefined, server, socket, parser, state); - state.onEnd = socketOnEnd.bind(undefined, server, socket, parser, state); - state.onClose = socketOnClose.bind(undefined, socket, state); - state.onDrain = socketOnDrain.bind(undefined, socket, state); + state.onData = FunctionPrototypeBind(socketOnData, undefined, + server, socket, parser, state); + state.onEnd = FunctionPrototypeBind(socketOnEnd, undefined, + server, socket, parser, state); + state.onClose = FunctionPrototypeBind(socketOnClose, undefined, + socket, state); + state.onDrain = FunctionPrototypeBind(socketOnDrain, undefined, + socket, state); socket.on('data', state.onData); socket.on('error', socketOnError); socket.on('end', state.onEnd); socket.on('close', state.onClose); socket.on('drain', state.onDrain); - parser.onIncoming = parserOnIncoming.bind(undefined, server, socket, state); + parser.onIncoming = FunctionPrototypeBind(parserOnIncoming, undefined, + server, socket, state); // We are consuming socket, so it won't get any actual data socket.on('resume', onSocketResume); @@ -506,15 +520,18 @@ function connectionListenerInternal(server, socket) { parser.consume(socket._handle); } parser[kOnExecute] = - onParserExecute.bind(undefined, server, socket, parser, state); + FunctionPrototypeBind(onParserExecute, undefined, + server, socket, parser, state); parser[kOnTimeout] = - onParserTimeout.bind(undefined, server, socket); + FunctionPrototypeBind(onParserTimeout, undefined, + server, socket); // When receiving new requests on the same socket (pipelining or keep alive) // make sure the requestTimeout is active. parser[kOnMessageBegin] = - setRequestTimeout.bind(undefined, server, socket); + FunctionPrototypeBind(setRequestTimeout, undefined, + server, socket); // This protects from DOS attack where an attacker establish the connection // without sending any data on applications where server.timeout is left to @@ -574,7 +591,7 @@ function socketOnClose(socket, state) { function abortIncoming(incoming) { while (incoming.length) { - const req = incoming.shift(); + const req = ArrayPrototypeShift(incoming); // TODO(ronag): req.destroy(err) req.aborted = true; req.destroyed = true; @@ -592,7 +609,7 @@ function socketOnEnd(server, socket, parser, state) { if (ret instanceof Error) { debug('parse error'); - socketOnError.call(socket, ret); + FunctionPrototypeCall(socketOnError, socket, ret); return; } @@ -618,7 +635,7 @@ function socketOnData(server, socket, parser, state, d) { function onRequestTimeout(socket) { socket[kRequestTimeout] = undefined; - socketOnError.call(socket, new ERR_HTTP_REQUEST_TIMEOUT()); + ReflectApply(socketOnError, socket, [new ERR_HTTP_REQUEST_TIMEOUT()]); } function onParserExecute(server, socket, parser, state, ret) { @@ -638,7 +655,7 @@ function onParserTimeout(server, socket) { socket.destroy(); } -const noop = () => {}; +const noop = FunctionPrototype; const badRequestResponse = Buffer.from( `HTTP/1.1 400 ${STATUS_CODES[400]}${CRLF}` + `Connection: close${CRLF}${CRLF}`, 'ascii' @@ -685,7 +702,7 @@ function onParserExecuteCommon(server, socket, parser, state, ret, d) { prepareError(ret, parser, d); ret.rawPacket = d || parser.getCurrentBuffer(); debug('parse error', ret); - socketOnError.call(socket, ret); + FunctionPrototypeCall(socketOnError, socket, ret); } else if (parser.incoming && parser.incoming.upgrade) { // Upgrade or CONNECT const req = parser.incoming; @@ -708,7 +725,7 @@ function onParserExecuteCommon(server, socket, parser, state, ret, d) { const eventName = req.method === 'CONNECT' ? 'connect' : 'upgrade'; if (eventName === 'upgrade' || server.listenerCount(eventName) > 0) { debug('SERVER have listener for %s', eventName); - const bodyHead = d.slice(ret, d.length); + const bodyHead = TypedArrayPrototypeSlice(d, ret, d.length); socket.readableFlowing = null; @@ -724,7 +741,7 @@ function onParserExecuteCommon(server, socket, parser, state, ret, d) { // When receiving new requests on the same socket (pipelining or keep alive) // make sure the requestTimeout is active. parser[kOnMessageBegin] = - setRequestTimeout.bind(undefined, server, socket); + FunctionPrototypeBind(setRequestTimeout, undefined, server, socket); } if (socket._paused && socket.parser) { @@ -793,7 +810,7 @@ function resOnFinish(req, res, socket, state, server) { // array will be empty. assert(state.incoming.length === 0 || state.incoming[0] === req); - state.incoming.shift(); + ArrayPrototypeShift(state.incoming); // If the user never called req.read(), and didn't pipe() or // .resume() or .on('data'), then we call req._dump() so that the @@ -826,7 +843,7 @@ function resOnFinish(req, res, socket, state, server) { } } else { // Start sending the next message - const m = state.outgoing.shift(); + const m = ArrayPrototypeShift(state.outgoing); if (m) { m.assignSocket(socket); } @@ -852,7 +869,7 @@ function parserOnIncoming(server, socket, state, req, keepAlive) { return 2; } - state.incoming.push(req); + ArrayPrototypePush(state.incoming, req); // If the writable end isn't consuming, then stop reading // so that we don't become overwhelmed by a flood of @@ -870,7 +887,8 @@ function parserOnIncoming(server, socket, state, req, keepAlive) { const res = new server[kServerResponse](req); res._keepAliveTimeout = server.keepAliveTimeout; - res._onPendingData = updateOutgoingData.bind(undefined, socket, state); + res._onPendingData = FunctionPrototypeBind(updateOutgoingData, undefined, + socket, state); res.shouldKeepAlive = keepAlive; DTRACE_HTTP_SERVER_REQUEST(req, socket); @@ -886,7 +904,7 @@ function parserOnIncoming(server, socket, state, req, keepAlive) { if (socket._httpMessage) { // There are already pending outgoing res, append. - state.outgoing.push(res); + ArrayPrototypePush(state.outgoing, res); } else { res.assignSocket(socket); } @@ -894,11 +912,12 @@ function parserOnIncoming(server, socket, state, req, keepAlive) { // When we're finished writing the response, check if this is the last // response, if so destroy the socket. res.on('finish', - resOnFinish.bind(undefined, req, res, socket, state, server)); + FunctionPrototypeBind(resOnFinish, undefined, + req, res, socket, state, server)); if (req.headers.expect !== undefined && (req.httpVersionMajor === 1 && req.httpVersionMinor === 1)) { - if (continueExpression.test(req.headers.expect)) { + if (RegExpPrototypeTest(continueExpression, req.headers.expect)) { res._expect_continue = true; if (server.listenerCount('checkContinue') > 0) { @@ -966,7 +985,8 @@ function unconsume(parser, socket) { function generateSocketListenerWrapper(originalFnName) { return function socketListenerWrap(ev, fn) { - const res = net.Socket.prototype[originalFnName].call(this, ev, fn); + const res = ReflectApply(net.Socket.prototype[originalFnName], this, + [ev, fn]); if (!this.parser) { this.on = net.Socket.prototype.on; this.addListener = net.Socket.prototype.addListener; diff --git a/lib/http.js b/lib/http.js index 4bbe42e652c24e..491162f9c4a172 100644 --- a/lib/http.js +++ b/lib/http.js @@ -22,6 +22,8 @@ 'use strict'; const { + ArrayPrototypeSlice, + ArrayPrototypeSort, ObjectDefineProperty, } = primordials; @@ -58,7 +60,7 @@ function get(url, options, cb) { module.exports = { _connectionListener, - METHODS: methods.slice().sort(), + METHODS: ArrayPrototypeSort(ArrayPrototypeSlice(methods)), STATUS_CODES, Agent: httpAgent.Agent, ClientRequest, diff --git a/lib/internal/http.js b/lib/internal/http.js index 1d5973593e9ada..0065f93fd896f0 100644 --- a/lib/internal/http.js +++ b/lib/internal/http.js @@ -3,6 +3,9 @@ const { Symbol, Date, + DatePrototypeGetMilliseconds, + DatePrototypeToUTCString, + DatePrototypeValueOf, } = primordials; const { setUnrefTimeout } = require('internal/timers'); @@ -23,9 +26,9 @@ function utcDate() { function cache() { const d = new Date(); - nowCache = d.valueOf(); - utcCache = d.toUTCString(); - setUnrefTimeout(resetCache, 1000 - d.getMilliseconds()); + nowCache = DatePrototypeValueOf(d); + utcCache = DatePrototypeToUTCString(d); + setUnrefTimeout(resetCache, 1000 - DatePrototypeGetMilliseconds(d)); } function resetCache() {