Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
})
}
return
}
endRequest()
})
this.pipelining = opts.pipelining || 1
this[kQueue].drain = () => {
this.emit('drain')
}
this.parser[HTTPParser.kOnHeaders] = () => {}
this.parser[HTTPParser.kOnHeadersComplete] = ({ statusCode, headers }) => {
// TODO move this[kCallbacks] from being an array. The array allocation
// is showing up in the flamegraph.
const cb = this[kCallbacks].shift()
this._needHeaders--
this._lastBody = new Readable({ read: this[kRead].bind(this) })
this._lastBody.push = this[kRequests].shift().wrapSimple(this._lastBody, this._lastBody.push)
cb(null, {
statusCode,
headers: parseHeaders(headers),
body: this._lastBody
})
if (this.closed && this[kQueue].length() === 0) {
this.destroy()
}
// otherwise, destroy on timeout by default
if (self.timeout)
socket.setTimeout(self.timeout);
socket.on('timeout', function() {
var req = socket.parser && socket.parser.incoming;
var reqTimeout = req && !req.complete && req.emit('timeout', socket);
var res = socket._httpMessage;
var resTimeout = res && res.emit('timeout', socket);
var serverTimeout = self.emit('timeout', socket);
if (!reqTimeout && !resTimeout && !serverTimeout)
socket.destroy();
});
var parser = parsers.alloc();
parser.reinitialize(HTTPParser.REQUEST);
parser.socket = socket;
socket.parser = parser;
parser.incoming = null;
// Propagate headers limit from server instance to parser
if (typeof this.maxHeadersCount === 'number') {
parser.maxHeaderPairs = this.maxHeadersCount << 1;
} else {
// Set default value because parser may be reused from FreeList
parser.maxHeaderPairs = 2000;
}
socket.addListener('error', socketOnError);
socket.addListener('close', serverSocketCloseListener);
parser.onIncoming = parserOnIncoming;
socket.on('end', socketOnEnd);
endRequest()
})
}
return
}
endRequest()
})
this.pipelining = opts.pipelining || 1
this[kQueue].drain = () => {
this.emit('drain')
}
this.parser[HTTPParser.kOnHeaders] = () => {}
this.parser[HTTPParser.kOnHeadersComplete] = ({ statusCode, headers }) => {
// TODO move this[kCallbacks] from being an array. The array allocation
// is showing up in the flamegraph.
const cb = this[kCallbacks].shift()
this._needHeaders--
this._lastBody = new Readable({ read: this[kRead].bind(this) })
this._lastBody.push = this[kRequests].shift().wrapSimple(this._lastBody, this._lastBody.push)
cb(null, {
statusCode,
headers: parseHeaders(headers),
body: this._lastBody
})
if (this.closed && this[kQueue].length() === 0) {
this.destroy()
// timeout has already occured, need to set a new timeoutTicker
this.timeoutTicker = retimer(handleTimeout, this.timeout)
this._connect()
}
if (this.rate) {
this.rateInterval = setInterval(() => {
this.reqsMadeThisSecond = 0
if (this.paused) this._doRequest(this.cer)
this.paused = false
}, 1000)
}
this.timeoutTicker = retimer(handleTimeout, this.timeout)
this.parser[HTTPParser.kOnHeaders] = () => {}
this.parser[HTTPParser.kOnHeadersComplete] = (opts) => {
this.emit('headers', opts)
this.resData[this.cer].headers = opts
}
this.parser[HTTPParser.kOnBody] = (body) => {
this.emit('body', body)
}
this.parser[HTTPParser.kOnMessageComplete] = () => {
const end = process.hrtime(this.resData[this.cer].startTime)
const responseTime = end[0] * 1e3 + end[1] / 1e6
this.emit('response', this.resData[this.cer].headers.statusCode, this.resData[this.cer].bytes, responseTime)
this.resData[this.cer].bytes = 0
if (!this.destroyed && this.reconnectRate && this.reqsMade % this.reconnectRate === 0) {
451: 'Unavailable For Legal Reasons',
500: 'Internal Server Error',
501: 'Not Implemented',
502: 'Bad Gateway',
503: 'Service Unavailable',
504: 'Gateway Timeout',
505: 'HTTP Version Not Supported',
506: 'Variant Also Negotiates', // RFC 2295
507: 'Insufficient Storage', // RFC 4918
508: 'Loop Detected',
509: 'Bandwidth Limit Exceeded',
510: 'Not Extended', // RFC 2774
511: 'Network Authentication Required' // RFC 6585
};
const kOnExecute = HTTPParser.kOnExecute | 0;
function ServerResponse(req) {
OutgoingMessage.call(this);
if (req.method === 'HEAD') this._hasBody = false;
this.sendDate = true;
if (req.httpVersionMajor < 1 || req.httpVersionMinor < 1) {
this.useChunkedEncodingByDefault = chunkExpression.test(req.headers.te);
this.shouldKeepAlive = false;
}
}
util.inherits(ServerResponse, OutgoingMessage);
module.exports = function getHttpResponseData (httpContentBuffer) {
const parser = new HTTPParser(HTTPParser.RESPONSE);
let httpData = {};
parser[HTTPParser.kOnMessageComplete] = noop;
parser[HTTPParser.kOnHeaders] = noop;
// Get headers and parse them to an object format for easier use
parser[HTTPParser.kOnHeadersComplete] = function (meta) {
const headerObject = {};
for (let i = 0; i < meta.headers.length; i += 2) {
headerObject[meta.headers[i]] = meta.headers[i + 1];
}
httpData = xtend(httpData, meta, {
headers: headerObject
});
this.opts = clone(opts)
this.opts.setupClient = this.opts.setupClient || noop
this.opts.pipelining = this.opts.pipelining || 1
this.opts.port = this.opts.port || 80
this.timeout = (this.opts.timeout || 10) * 1000
this.ipc = !!this.opts.socketPath
this.secure = this.opts.protocol === 'https:'
this.auth = this.opts.auth || null
if (this.secure && this.opts.port === 80) {
this.opts.port = 443
}
this.parser = new HTTPParser(HTTPParser.RESPONSE)
this.requestIterator = new RequestIterator(this.opts)
this.reqsMade = 0
// used for request limiting
this.responseMax = this.opts.responseMax
// used for rate limiting
this.reqsMadeThisSecond = 0
this.rate = this.opts.rate
// used for forcing reconnects
this.reconnectRate = this.opts.reconnectRate
this.resData = new Array(this.opts.pipelining)
for (let i = 0; i < this.opts.pipelining; i++) {
constructor (url, opts = {}) {
super()
if (!(url instanceof URL)) {
url = new URL(url)
}
this.url = url
// state machine, might need more states
this.closed = false
this.parser = new HTTPParser(HTTPParser.RESPONSE)
this[kTLSOpts] = opts.tls || opts.https
const endRequest = () => {
this.socket.write('\r\n', 'ascii')
this.socket.uncork()
this._needHeaders++
this[kRead]()
}
this.timeout = opts.timeout || 30000 // 30 seconds
this[kCallbacks] = []
this[kRequests] = []
const timerCb = () => {
if (this[kCallbacks].length > 0) {
function tickOnSocket(req, socket) {
var parser = parsers.alloc();
req.socket = socket;
req.connection = socket;
parser.reinitialize(HTTPParser.RESPONSE);
parser.socket = socket;
parser.incoming = null;
parser.outgoing = req;
req.parser = parser;
socket.parser = parser;
socket._httpMessage = req;
// Setup "drain" propagation.
httpSocketSetup(socket);
// Propagate headers limit from request object to parser
if (typeof req.maxHeadersCount === 'number') {
parser.maxHeaderPairs = req.maxHeadersCount << 1;
} else {
// Set default value because parser may be reused from FreeList
module.exports = function getHttpResponseData (httpContentBuffer) {
const parser = new HTTPParser(HTTPParser.RESPONSE);
let httpData = {};
parser[HTTPParser.kOnMessageComplete] = noop;
parser[HTTPParser.kOnHeaders] = noop;
// Get headers and parse them to an object format for easier use
parser[HTTPParser.kOnHeadersComplete] = function (meta) {
const headerObject = {};
for (let i = 0; i < meta.headers.length; i += 2) {
headerObject[meta.headers[i]] = meta.headers[i + 1];
}
httpData = xtend(httpData, meta, {
headers: headerObject
});
};
// The below function can fire multiple times for "transfer-encoding: chunked"
// We need to build up the body in a buffer to ensure we capture it entirely
let completeBody = '';
parser[HTTPParser.kOnBody] = function (body, contentOffset, len) {
completeBody += body.slice(contentOffset, contentOffset + len).toString();