Skip to content

Commit

Permalink
http: refactor to use more primordials
Browse files Browse the repository at this point in the history
PR-URL: #36194
Backport-PR-URL: #36803
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Rich Trott <[email protected]>
  • Loading branch information
aduh95 authored and danielleadams committed Jan 12, 2021
1 parent c784f15 commit 5e499c4
Show file tree
Hide file tree
Showing 8 changed files with 150 additions and 89 deletions.
45 changes: 28 additions & 17 deletions lib/_http_agent.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,21 @@
'use strict';

const {
ArrayPrototypeIncludes,
ArrayPrototypeIndexOf,
ArrayPrototypePop,
ArrayPrototypePush,
ArrayPrototypeShift,
ArrayPrototypeSplice,
FunctionPrototypeCall,
NumberIsNaN,
ObjectKeys,
ObjectSetPrototypeOf,
ObjectValues,
StringPrototypeIndexOf,
StringPrototypeSplit,
StringPrototypeStartsWith,
StringPrototypeSubstr,
Symbol,
} = primordials;

Expand Down Expand Up @@ -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:';
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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];
}
Expand All @@ -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) {
Expand All @@ -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);
}
};

Expand All @@ -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);
Expand All @@ -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.
Expand Down Expand Up @@ -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();
}
}
Expand Down Expand Up @@ -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];
Expand Down
28 changes: 18 additions & 10 deletions lib/_http_client.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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');
}

Expand Down Expand Up @@ -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';
}
Expand Down Expand Up @@ -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}]`;
}

Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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();
Expand Down
11 changes: 7 additions & 4 deletions lib/_http_common.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,11 @@
'use strict';

const {
ArrayPrototypeConcat,
MathMin,
Symbol,
RegExpPrototypeTest,
TypedArrayPrototypeSlice,
} = primordials;
const { setImmediate } = require('timers');

Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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]/;
Expand All @@ -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) {
Expand Down
16 changes: 11 additions & 5 deletions lib/_http_incoming.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,13 @@
'use strict';

const {
ArrayPrototypePush,
FunctionPrototypeCall,
ObjectDefineProperty,
ObjectSetPrototypeOf,
StringPrototypeCharCodeAt,
StringPrototypeSlice,
StringPrototypeToLowerCase,
Symbol
} = primordials;

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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
//
Expand All @@ -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;
Expand All @@ -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];
}
Expand Down
Loading

0 comments on commit 5e499c4

Please sign in to comment.