| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 07ff3dd commit 2c6124c
6 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,31 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + | ||
| 3 | + const { | ||
| 4 | + NumberMAX_SAFE_INTEGER, | ||
| 5 | + Symbol, | ||
| 6 | + } = primordials; | ||
| 7 | + | ||
| 8 | + const { now } = require('internal/perf/utils'); | ||
| 9 | + const kInspectorRequestId = Symbol('kInspectorRequestId'); | ||
| 10 | + | ||
| 11 | + /** | ||
| 12 | + * Return a monotonically increasing time in seconds since an arbitrary point in the past. | ||
| 13 | + * @returns {number} | ||
| 14 | + */ | ||
| 15 | + function getMonotonicTime() { | ||
| 16 | + return now() / 1000; | ||
| 17 | + } | ||
| 18 | + | ||
| 19 | + let requestId = 0; | ||
| 20 | + function getNextRequestId() { | ||
| 21 | + if (requestId === NumberMAX_SAFE_INTEGER) { | ||
| 22 | + requestId = 0; | ||
| 23 | + } | ||
| 24 | + return `node-network-event-${++requestId}`; | ||
| 25 | + }; | ||
| 26 | + | ||
| 27 | + module.exports = { | ||
| 28 | + kInspectorRequestId, | ||
| 29 | + getMonotonicTime, | ||
| 30 | + getNextRequestId, | ||
| 31 | + }; | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,132 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + | ||
| 3 | + const { | ||
| 4 | + ArrayIsArray, | ||
| 5 | + DateNow, | ||
| 6 | + ObjectEntries, | ||
| 7 | + String, | ||
| 8 | + Symbol, | ||
| 9 | + } = primordials; | ||
| 10 | + | ||
| 11 | + const { | ||
| 12 | + kInspectorRequestId, | ||
| 13 | + getMonotonicTime, | ||
| 14 | + getNextRequestId, | ||
| 15 | + } = require('internal/inspector/network'); | ||
| 16 | + const dc = require('diagnostics_channel'); | ||
| 17 | + const { Network } = require('inspector'); | ||
| 18 | + | ||
| 19 | + const kResourceType = 'Other'; | ||
| 20 | + const kRequestUrl = Symbol('kRequestUrl'); | ||
| 21 | + | ||
| 22 | + // Convert a Headers object (Map<string, number | string | string[]>) to a plain object (Map<string, string>) | ||
| 23 | + const convertHeaderObject = (headers = {}) => { | ||
| 24 | + // The 'host' header that contains the host and port of the URL. | ||
| 25 | + let host; | ||
| 26 | + const dict = {}; | ||
| 27 | + for (const { 0: key, 1: value } of ObjectEntries(headers)) { | ||
| 28 | + if (key.toLowerCase() === 'host') { | ||
| 29 | + host = value; | ||
| 30 | + } | ||
| 31 | + if (typeof value === 'string') { | ||
| 32 | + dict[key] = value; | ||
| 33 | + } else if (ArrayIsArray(value)) { | ||
| 34 | + if (key.toLowerCase() === 'cookie') dict[key] = value.join('; '); | ||
| 35 | + // ChromeDevTools frontend treats 'set-cookie' as a special case | ||
| 36 | + // https://github.com/ChromeDevTools/devtools-frontend/blob/4275917f84266ef40613db3c1784a25f902ea74e/front_end/core/sdk/NetworkRequest.ts#L1368 | ||
| 37 | + else if (key.toLowerCase() === 'set-cookie') dict[key] = value.join('\n'); | ||
| 38 | + else dict[key] = value.join(', '); | ||
| 39 | + } else { | ||
| 40 | + dict[key] = String(value); | ||
| 41 | + } | ||
| 42 | + } | ||
| 43 | + return [host, dict]; | ||
| 44 | + }; | ||
| 45 | + | ||
| 46 | + /** | ||
| 47 | + * When a client request starts, emit Network.requestWillBeSent event. | ||
| 48 | + * https://chromedevtools.github.io/devtools-protocol/1-3/Network/#event-requestWillBeSent | ||
| 49 | + * @param {{ request: import('http').ClientRequest }} event | ||
| 50 | + */ | ||
| 51 | + function onClientRequestStart({ request }) { | ||
| 52 | + request[kInspectorRequestId] = getNextRequestId(); | ||
| 53 | + | ||
| 54 | + const { 0: host, 1: headers } = convertHeaderObject(request.getHeaders()); | ||
| 55 | + const url = `${request.protocol}//${host}${request.path}`; | ||
| 56 | + request[kRequestUrl] = url; | ||
| 57 | + | ||
| 58 | + Network.requestWillBeSent({ | ||
| 59 | + requestId: request[kInspectorRequestId], | ||
| 60 | + timestamp: getMonotonicTime(), | ||
| 61 | + wallTime: DateNow(), | ||
| 62 | + request: { | ||
| 63 | + url, | ||
| 64 | + method: request.method, | ||
| 65 | + headers, | ||
| 66 | + }, | ||
| 67 | + }); | ||
| 68 | + } | ||
| 69 | + | ||
| 70 | + /** | ||
| 71 | + * When a client request errors, emit Network.loadingFailed event. | ||
| 72 | + * https://chromedevtools.github.io/devtools-protocol/1-3/Network/#event-loadingFailed | ||
| 73 | + * @param {{ request: import('http').ClientRequest, error: any }} event | ||
| 74 | + */ | ||
| 75 | + function onClientRequestError({ request, error }) { | ||
| 76 | + if (typeof request[kInspectorRequestId] !== 'string') { | ||
| 77 | + return; | ||
| 78 | + } | ||
| 79 | + Network.loadingFailed({ | ||
| 80 | + requestId: request[kInspectorRequestId], | ||
| 81 | + timestamp: getMonotonicTime(), | ||
| 82 | + type: kResourceType, | ||
| 83 | + errorText: error.message, | ||
| 84 | + }); | ||
| 85 | + } | ||
| 86 | + | ||
| 87 | + /** | ||
| 88 | + * When response headers are received, emit Network.responseReceived event. | ||
| 89 | + * https://chromedevtools.github.io/devtools-protocol/1-3/Network/#event-responseReceived | ||
| 90 | + * @param {{ request: import('http').ClientRequest, error: any }} event | ||
| 91 | + */ | ||
| 92 | + function onClientResponseFinish({ request, response }) { | ||
| 93 | + if (typeof request[kInspectorRequestId] !== 'string') { | ||
| 94 | + return; | ||
| 95 | + } | ||
| 96 | + Network.responseReceived({ | ||
| 97 | + requestId: request[kInspectorRequestId], | ||
| 98 | + timestamp: getMonotonicTime(), | ||
| 99 | + type: kResourceType, | ||
| 100 | + response: { | ||
| 101 | + url: request[kRequestUrl], | ||
| 102 | + status: response.statusCode, | ||
| 103 | + statusText: response.statusMessage ?? '', | ||
| 104 | + headers: convertHeaderObject(response.headers)[1], | ||
| 105 | + }, | ||
| 106 | + }); | ||
| 107 | + | ||
| 108 | + // Wait until the response body is consumed by user code. | ||
| 109 | + response.once('end', () => { | ||
| 110 | + Network.loadingFinished({ | ||
| 111 | + requestId: request[kInspectorRequestId], | ||
| 112 | + timestamp: getMonotonicTime(), | ||
| 113 | + }); | ||
| 114 | + }); | ||
| 115 | + } | ||
| 116 | + | ||
| 117 | + function enable() { | ||
| 118 | + dc.subscribe('http.client.request.start', onClientRequestStart); | ||
| 119 | + dc.subscribe('http.client.request.error', onClientRequestError); | ||
| 120 | + dc.subscribe('http.client.response.finish', onClientResponseFinish); | ||
| 121 | + } | ||
| 122 | + | ||
| 123 | + function disable() { | ||
| 124 | + dc.unsubscribe('http.client.request.start', onClientRequestStart); | ||
| 125 | + dc.unsubscribe('http.client.request.error', onClientRequestError); | ||
| 126 | + dc.unsubscribe('http.client.response.finish', onClientResponseFinish); | ||
| 127 | + } | ||
| 128 | + | ||
| 129 | + module.exports = { | ||
| 130 | + enable, | ||
| 131 | + disable, | ||
| 132 | + }; | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,102 +1,15 @@ | |||
| 1 | 1 | 'use strict'; | |
| 2 | 2 | ||
| 3 | - const { | ||
| 4 | - ArrayIsArray, | ||
| 5 | - DateNow, | ||
| 6 | - ObjectEntries, | ||
| 7 | - String, | ||
| 8 | - } = primordials; | ||
| 9 | - | ||
| 10 | - let dc; | ||
| 11 | - let Network; | ||
| 12 | - | ||
| 13 | - let requestId = 0; | ||
| 14 | - const getNextRequestId = () => `node-network-event-${++requestId}`; | ||
| 15 | - | ||
| 16 | - // Convert a Headers object (Map<string, number | string | string[]>) to a plain object (Map<string, string>) | ||
| 17 | - const headerObjectToDictionary = (headers = {}) => { | ||
| 18 | - const dict = {}; | ||
| 19 | - for (const { 0: key, 1: value } of ObjectEntries(headers)) { | ||
| 20 | - if (typeof value === 'string') { | ||
| 21 | - dict[key] = value; | ||
| 22 | - } else if (ArrayIsArray(value)) { | ||
| 23 | - if (key.toLowerCase() === 'cookie') dict[key] = value.join('; '); | ||
| 24 | - // ChromeDevTools frontend treats 'set-cookie' as a special case | ||
| 25 | - // https://github.com/ChromeDevTools/devtools-frontend/blob/4275917f84266ef40613db3c1784a25f902ea74e/front_end/core/sdk/NetworkRequest.ts#L1368 | ||
| 26 | - else if (key.toLowerCase() === 'set-cookie') dict[key] = value.join('\n'); | ||
| 27 | - else dict[key] = value.join(', '); | ||
| 28 | - } else { | ||
| 29 | - dict[key] = String(value); | ||
| 30 | - } | ||
| 31 | - } | ||
| 32 | - return dict; | ||
| 33 | - }; | ||
| 34 | - | ||
| 35 | - function onClientRequestStart({ request }) { | ||
| 36 | - const url = `${request.protocol}//${request.host}${request.path}`; | ||
| 37 | - const wallTime = DateNow(); | ||
| 38 | - const timestamp = wallTime / 1000; | ||
| 39 | - request._inspectorRequestId = getNextRequestId(); | ||
| 40 | - Network.requestWillBeSent({ | ||
| 41 | - requestId: request._inspectorRequestId, | ||
| 42 | - timestamp, | ||
| 43 | - wallTime, | ||
| 44 | - request: { | ||
| 45 | - url, | ||
| 46 | - method: request.method, | ||
| 47 | - headers: headerObjectToDictionary(request.getHeaders()), | ||
| 48 | - }, | ||
| 49 | - }); | ||
| 50 | - } | ||
| 51 | - | ||
| 52 | - function onClientRequestError({ request, error }) { | ||
| 53 | - if (typeof request._inspectorRequestId !== 'string') { | ||
| 54 | - return; | ||
| 55 | - } | ||
| 56 | - const timestamp = DateNow() / 1000; | ||
| 57 | - Network.loadingFailed({ | ||
| 58 | - requestId: request._inspectorRequestId, | ||
| 59 | - timestamp, | ||
| 60 | - type: 'Other', | ||
| 61 | - errorText: error.message, | ||
| 62 | - }); | ||
| 63 | - } | ||
| 64 | - | ||
| 65 | - function onClientResponseFinish({ request, response }) { | ||
| 66 | - if (typeof request._inspectorRequestId !== 'string') { | ||
| 67 | - return; | ||
| 68 | - } | ||
| 69 | - const url = `${request.protocol}//${request.host}${request.path}`; | ||
| 70 | - const timestamp = DateNow() / 1000; | ||
| 71 | - Network.responseReceived({ | ||
| 72 | - requestId: request._inspectorRequestId, | ||
| 73 | - timestamp, | ||
| 74 | - type: 'Other', | ||
| 75 | - response: { | ||
| 76 | - url, | ||
| 77 | - status: response.statusCode, | ||
| 78 | - statusText: response.statusMessage ?? '', | ||
| 79 | - headers: headerObjectToDictionary(response.headers), | ||
| 80 | - }, | ||
| 81 | - }); | ||
| 82 | - Network.loadingFinished({ | ||
| 83 | - requestId: request._inspectorRequestId, | ||
| 84 | - timestamp, | ||
| 85 | - }); | ||
| 86 | - } | ||
| 87 | - | ||
| 88 | 3 | function enable() { | |
| 89 | - dc ??= require('diagnostics_channel'); | ||
| 90 | - Network ??= require('inspector').Network; | ||
| 91 | - dc.subscribe('http.client.request.start', onClientRequestStart); | ||
| 92 | - dc.subscribe('http.client.request.error', onClientRequestError); | ||
| 93 | - dc.subscribe('http.client.response.finish', onClientResponseFinish); | ||
| 4 | + require('internal/inspector/network_http').enable(); | ||
| 5 | + // TODO: add undici request/websocket tracking. | ||
| 6 | + // https://github.com/nodejs/node/issues/53946 | ||
| 94 | 7 | } | |
| 95 | 8 | ||
| 96 | 9 | function disable() { | |
| 97 | - dc.unsubscribe('http.client.request.start', onClientRequestStart); | ||
| 98 | - dc.unsubscribe('http.client.request.error', onClientRequestError); | ||
| 99 | - dc.unsubscribe('http.client.response.finish', onClientResponseFinish); | ||
| 10 | + require('internal/inspector/network_http').disable(); | ||
| 11 | + // TODO: add undici request/websocket tracking. | ||
| 12 | + // https://github.com/nodejs/node/issues/53946 | ||
| 100 | 13 | } | |
| 101 | 14 | ||
| 102 | 15 | module.exports = { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -119,6 +119,8 @@ BuiltinLoader::BuiltinCategories BuiltinLoader::GetBuiltinCategories() const { | |||
| 119 | 119 | builtin_categories.cannot_be_required = std::set<std::string> { | |
| 120 | 120 | #if !HAVE_INSPECTOR | |
| 121 | 121 | "inspector", "inspector/promises", "internal/util/inspector", | |
| 122 | + "internal/inspector/network", "internal/inspector/network_http", | ||
| 123 | + "internal/inspector_async_hook", "internal/inspector_network_tracking", | ||
| 122 | 124 | #endif // !HAVE_INSPECTOR | |
| 123 | 125 | ||
| 124 | 126 | #if !NODE_USE_V8_PLATFORM || !defined(NODE_HAVE_I18N_SUPPORT) | |
| Back | FazBrowse Home | New Git URL |
0 commit comments