Path: blob/master/node_modules/@szmarczak/http-timer/dist/source/index.js
2593 views
"use strict";1Object.defineProperty(exports, "__esModule", { value: true });2const defer_to_connect_1 = require("defer-to-connect");3const util_1 = require("util");4const nodejsMajorVersion = Number(process.versions.node.split('.')[0]);5const timer = (request) => {6if (request.timings) {7return request.timings;8}9const timings = {10start: Date.now(),11socket: undefined,12lookup: undefined,13connect: undefined,14secureConnect: undefined,15upload: undefined,16response: undefined,17end: undefined,18error: undefined,19abort: undefined,20phases: {21wait: undefined,22dns: undefined,23tcp: undefined,24tls: undefined,25request: undefined,26firstByte: undefined,27download: undefined,28total: undefined29}30};31request.timings = timings;32const handleError = (origin) => {33const emit = origin.emit.bind(origin);34origin.emit = (event, ...args) => {35// Catches the `error` event36if (event === 'error') {37timings.error = Date.now();38timings.phases.total = timings.error - timings.start;39origin.emit = emit;40}41// Saves the original behavior42return emit(event, ...args);43};44};45handleError(request);46const onAbort = () => {47timings.abort = Date.now();48// Let the `end` response event be responsible for setting the total phase,49// unless the Node.js major version is >= 13.50if (!timings.response || nodejsMajorVersion >= 13) {51timings.phases.total = Date.now() - timings.start;52}53};54request.prependOnceListener('abort', onAbort);55const onSocket = (socket) => {56timings.socket = Date.now();57timings.phases.wait = timings.socket - timings.start;58if (util_1.types.isProxy(socket)) {59return;60}61const lookupListener = () => {62timings.lookup = Date.now();63timings.phases.dns = timings.lookup - timings.socket;64};65socket.prependOnceListener('lookup', lookupListener);66defer_to_connect_1.default(socket, {67connect: () => {68timings.connect = Date.now();69if (timings.lookup === undefined) {70socket.removeListener('lookup', lookupListener);71timings.lookup = timings.connect;72timings.phases.dns = timings.lookup - timings.socket;73}74timings.phases.tcp = timings.connect - timings.lookup;75// This callback is called before flushing any data,76// so we don't need to set `timings.phases.request` here.77},78secureConnect: () => {79timings.secureConnect = Date.now();80timings.phases.tls = timings.secureConnect - timings.connect;81}82});83};84if (request.socket) {85onSocket(request.socket);86}87else {88request.prependOnceListener('socket', onSocket);89}90const onUpload = () => {91var _a;92timings.upload = Date.now();93timings.phases.request = timings.upload - ((_a = timings.secureConnect) !== null && _a !== void 0 ? _a : timings.connect);94};95const writableFinished = () => {96if (typeof request.writableFinished === 'boolean') {97return request.writableFinished;98}99// Node.js doesn't have `request.writableFinished` property100return request.finished && request.outputSize === 0 && (!request.socket || request.socket.writableLength === 0);101};102if (writableFinished()) {103onUpload();104}105else {106request.prependOnceListener('finish', onUpload);107}108request.prependOnceListener('response', (response) => {109timings.response = Date.now();110timings.phases.firstByte = timings.response - timings.upload;111response.timings = timings;112handleError(response);113response.prependOnceListener('end', () => {114timings.end = Date.now();115timings.phases.download = timings.end - timings.response;116timings.phases.total = timings.end - timings.start;117});118response.prependOnceListener('aborted', onAbort);119});120return timings;121};122exports.default = timer;123// For CommonJS default export support124module.exports = timer;125module.exports.default = timer;126127128