Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

http: refactor to use more primordials #36194

Merged
merged 1 commit into from
Dec 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 28 additions & 17 deletions lib/_http_agent.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,22 @@
'use strict';

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

Expand Down Expand Up @@ -79,7 +90,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 @@ -126,7 +137,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 @@ -172,7 +183,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 @@ -251,11 +262,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 @@ -267,7 +278,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 @@ -291,7 +302,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 @@ -315,7 +326,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 @@ -340,16 +351,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 @@ -381,7 +392,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 @@ -413,13 +424,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 @@ -535,7 +543,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 @@ -831,7 +839,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
15 changes: 10 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,7 @@ function IncomingMessage(socket) {
};
}

Readable.call(this, streamOptions);
FunctionPrototypeCall(Readable, this, streamOptions);

this._readableState.readingMore = true;

Expand Down Expand Up @@ -312,7 +317,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 @@ -326,9 +331,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 @@ -338,7 +343,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