f5-conx-core
Version:
F5 SDK for JavaScript with Typescript type definitions
159 lines • 5.33 kB
JavaScript
;
/* eslint-disable @typescript-eslint/no-non-null-assertion */
Object.defineProperty(exports, "__esModule", { value: true });
exports.httpTimer = void 0;
/**
* basically a copy/paste from https://github.com/szmarczak/http-timer
*
* the latest version was pure ESM which was causing problem with this project.
* so, I had to rework some of it's moduleness to match the blend this project has/needs
*/
const events_1 = require("events");
const util_1 = require("util");
function httpTimer(request) {
if (request.timings) {
return request.timings;
}
const timings = {
start: Date.now(),
socket: undefined,
lookup: undefined,
connect: undefined,
secureConnect: undefined,
upload: undefined,
response: undefined,
end: undefined,
error: undefined,
abort: undefined,
phases: {
wait: undefined,
dns: undefined,
tcp: undefined,
tls: undefined,
request: undefined,
firstByte: undefined,
download: undefined,
total: undefined,
},
};
request.timings = timings;
function handleError(origin) {
origin.once(events_1.errorMonitor, () => {
timings.error = Date.now();
timings.phases.total = timings.error - timings.start;
});
}
handleError(request);
function onAbort() {
timings.abort = Date.now();
timings.phases.total = timings.abort - timings.start;
}
request.prependOnceListener('abort', onAbort);
function onSocket(socket) {
timings.socket = Date.now();
timings.phases.wait = timings.socket - timings.start;
if (util_1.types.isProxy(socket)) {
return;
}
const lookupListener = () => {
timings.lookup = Date.now();
timings.phases.dns = timings.lookup - timings.socket;
};
socket.prependOnceListener('lookup', lookupListener);
deferToConnect(socket, {
connect: () => {
timings.connect = Date.now();
if (timings.lookup === undefined) {
socket.removeListener('lookup', lookupListener);
timings.lookup = timings.connect;
timings.phases.dns = timings.lookup - timings.socket;
}
timings.phases.tcp = timings.connect - timings.lookup;
},
secureConnect: () => {
timings.secureConnect = Date.now();
timings.phases.tls = timings.secureConnect - timings.connect;
},
});
}
if (request.socket) {
onSocket(request.socket);
}
else {
request.prependOnceListener('socket', onSocket);
}
function onUpload() {
var _a;
timings.upload = Date.now();
timings.phases.request = timings.upload - ((_a = timings.secureConnect) !== null && _a !== void 0 ? _a : timings.connect);
}
if (request.writableFinished) {
onUpload();
}
else {
request.prependOnceListener('finish', onUpload);
}
request.prependOnceListener('response', (response) => {
timings.response = Date.now();
timings.phases.firstByte = timings.response - timings.upload;
response.timings = timings;
handleError(response);
response.prependOnceListener('end', () => {
request.off('abort', onAbort);
response.off('aborted', onAbort);
if (timings.phases.total) {
// Aborted or errored
return;
}
timings.end = Date.now();
timings.phases.download = timings.end - timings.response;
timings.phases.total = timings.end - timings.start;
});
response.prependOnceListener('aborted', onAbort);
});
return timings;
}
exports.httpTimer = httpTimer;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function isTLSSocket(socket) {
return socket.encrypted;
}
function deferToConnect(socket, fn) {
let listeners;
if (typeof fn === 'function') {
const connect = fn;
listeners = { connect };
}
else {
listeners = fn;
}
const hasConnectListener = typeof listeners.connect === 'function';
const hasSecureConnectListener = typeof listeners.secureConnect === 'function';
const hasCloseListener = typeof listeners.close === 'function';
function onConnect() {
if (hasConnectListener) {
listeners.connect();
}
if (isTLSSocket(socket) && hasSecureConnectListener) {
if (socket.authorized) {
listeners.secureConnect();
}
else if (!socket.authorizationError) {
socket.once('secureConnect', listeners.secureConnect);
}
}
if (hasCloseListener) {
socket.once('close', listeners.close);
}
}
if (socket.writable && !socket.connecting) {
onConnect();
}
else if (socket.connecting) {
socket.once('connect', onConnect);
}
else if (socket.destroyed && hasCloseListener) {
listeners.close(socket._hadError);
}
}
//# sourceMappingURL=httpTimer.js.map