UNPKG

urllib

Version:

Help in opening URLs (mostly HTTP) in a complex world — basic and digest authentication, redirections, cookies and more. Base undici fetch API.

132 lines 7.62 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.initDiagnosticsChannel = void 0; const tslib_1 = require("tslib"); const diagnostics_channel_1 = tslib_1.__importDefault(require("diagnostics_channel")); const perf_hooks_1 = require("perf_hooks"); const util_1 = require("util"); const symbols_1 = tslib_1.__importDefault(require("./symbols")); const utils_1 = require("./utils"); const debug = (0, util_1.debuglog)('urllib:DiagnosticsChannel'); let initedDiagnosticsChannel = false; // https://undici.nodejs.org/#/docs/api/DiagnosticsChannel // client --> server // undici:request:create => { request } // -> [optional] undici:client:connected => { socket } [first request will create socket] // -> undici:client:sendHeaders => { socket, request } // -> undici:request:bodySent => { request } // // server --> client // undici:request:headers => { request, response } // -> undici:request:trailers => { request, trailers } function initDiagnosticsChannel() { // makre sure init global DiagnosticsChannel once if (initedDiagnosticsChannel) return; initedDiagnosticsChannel = true; let kHandler; // This message is published when a new outgoing request is created. // Note: a request is only loosely completed to a given socket. diagnostics_channel_1.default.channel('undici:request:create').subscribe((message, name) => { var _a, _b; const { request } = message; if (!kHandler) { const symbols = Object.getOwnPropertySymbols(request); for (const symbol of symbols) { if (symbol.description === 'handler') { kHandler = symbol; break; } } } const opaque = (_b = (_a = request[kHandler]) === null || _a === void 0 ? void 0 : _a.opts) === null || _b === void 0 ? void 0 : _b.opaque; // ignore non HttpClient Request if (!opaque || !opaque[symbols_1.default.kRequestId]) return; debug('[%s] Request#%d %s %s, path: %s', name, opaque[symbols_1.default.kRequestId], request.method, request.origin, request.path); if (!opaque[symbols_1.default.kEnableRequestTiming]) return; opaque[symbols_1.default.kRequestTiming].queuing = (0, utils_1.performanceTime)(opaque[symbols_1.default.kRequestStartTime]); }); // diagnosticsChannel.channel('undici:client:beforeConnect') // diagnosticsChannel.channel('undici:client:connectError') // This message is published after a connection is established. diagnostics_channel_1.default.channel('undici:client:connected').subscribe((message, name) => { const { socket } = message; socket[symbols_1.default.kSocketId] = (0, utils_1.globalId)('UndiciSocket'); socket[symbols_1.default.kSocketStartTime] = perf_hooks_1.performance.now(); socket[symbols_1.default.kHandledRequests] = 0; socket[symbols_1.default.kHandledResponses] = 0; debug('[%s] Socket#%d connected', name, socket[symbols_1.default.kSocketId]); }); // This message is published right before the first byte of the request is written to the socket. diagnostics_channel_1.default.channel('undici:client:sendHeaders').subscribe((message, name) => { var _a, _b; const { request, socket } = message; if (!kHandler) return; const opaque = (_b = (_a = request[kHandler]) === null || _a === void 0 ? void 0 : _a.opts) === null || _b === void 0 ? void 0 : _b.opaque; if (!opaque || !opaque[symbols_1.default.kRequestId]) return; socket[symbols_1.default.kHandledRequests]++; // attach socket to opaque opaque[symbols_1.default.kRequestSocket] = socket; debug('[%s] Request#%d send headers on Socket#%d (handled %d requests)', name, opaque[symbols_1.default.kRequestId], socket[symbols_1.default.kSocketId], socket[symbols_1.default.kHandledRequests]); if (!opaque[symbols_1.default.kEnableRequestTiming]) return; opaque[symbols_1.default.kRequestTiming].requestHeadersSent = (0, utils_1.performanceTime)(opaque[symbols_1.default.kRequestStartTime]); // first socket need to caculate the connected time if (socket[symbols_1.default.kHandledRequests] === 1) { // kSocketStartTime - kRequestStartTime = connected time opaque[symbols_1.default.kRequestTiming].connected = (0, utils_1.performanceTime)(opaque[symbols_1.default.kRequestStartTime], socket[symbols_1.default.kSocketStartTime]); } }); diagnostics_channel_1.default.channel('undici:request:bodySent').subscribe((message, name) => { var _a, _b; const { request } = message; if (!kHandler) return; const opaque = (_b = (_a = request[kHandler]) === null || _a === void 0 ? void 0 : _a.opts) === null || _b === void 0 ? void 0 : _b.opaque; if (!opaque || !opaque[symbols_1.default.kRequestId]) return; debug('[%s] Request#%d send body', name, opaque[symbols_1.default.kRequestId]); if (!opaque[symbols_1.default.kEnableRequestTiming]) return; opaque[symbols_1.default.kRequestTiming].requestSent = (0, utils_1.performanceTime)(opaque[symbols_1.default.kRequestStartTime]); }); // This message is published after the response headers have been received, i.e. the response has been completed. diagnostics_channel_1.default.channel('undici:request:headers').subscribe((message, name) => { var _a, _b; const { request, response } = message; if (!kHandler) return; const opaque = (_b = (_a = request[kHandler]) === null || _a === void 0 ? void 0 : _a.opts) === null || _b === void 0 ? void 0 : _b.opaque; if (!opaque || !opaque[symbols_1.default.kRequestId]) return; // get socket from opaque const socket = opaque[symbols_1.default.kRequestSocket]; socket[symbols_1.default.kHandledResponses]++; debug('[%s] Request#%d get %s response headers on Socket#%d (handled %d responses)', name, opaque[symbols_1.default.kRequestId], response.statusCode, socket[symbols_1.default.kSocketId], socket[symbols_1.default.kHandledResponses]); if (!opaque[symbols_1.default.kEnableRequestTiming]) return; opaque[symbols_1.default.kRequestTiming].waiting = (0, utils_1.performanceTime)(opaque[symbols_1.default.kRequestStartTime]); }); // This message is published after the response body and trailers have been received, i.e. the response has been completed. diagnostics_channel_1.default.channel('undici:request:trailers').subscribe((message, name) => { var _a, _b; const { request } = message; if (!kHandler) return; const opaque = (_b = (_a = request[kHandler]) === null || _a === void 0 ? void 0 : _a.opts) === null || _b === void 0 ? void 0 : _b.opaque; if (!opaque || !opaque[symbols_1.default.kRequestId]) return; debug('[%s] Request#%d get response body and trailers', name, opaque[symbols_1.default.kRequestId]); if (!opaque[symbols_1.default.kEnableRequestTiming]) return; opaque[symbols_1.default.kRequestTiming].contentDownload = (0, utils_1.performanceTime)(opaque[symbols_1.default.kRequestStartTime]); }); // diagnosticsChannel.channel('undici:request:error') } exports.initDiagnosticsChannel = initDiagnosticsChannel; //# sourceMappingURL=diagnosticsChannel.js.map