| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 0379a8b commit 772f8f4
4 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,190 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + | ||
| 3 | + const { | ||
| 4 | + ArrayIsArray, | ||
| 5 | + DateNow, | ||
| 6 | + ObjectEntries, | ||
| 7 | + String, | ||
| 8 | + Symbol, | ||
| 9 | + } = primordials; | ||
| 10 | + | ||
| 11 | + const { | ||
| 12 | + kInspectorRequestId, | ||
| 13 | + kResourceType, | ||
| 14 | + getMonotonicTime, | ||
| 15 | + getNextRequestId, | ||
| 16 | + sniffMimeType, | ||
| 17 | + } = require('internal/inspector/network'); | ||
| 18 | + const dc = require('diagnostics_channel'); | ||
| 19 | + const { Network } = require('inspector'); | ||
| 20 | + const { | ||
| 21 | + HTTP2_HEADER_AUTHORITY, | ||
| 22 | + HTTP2_HEADER_CONTENT_TYPE, | ||
| 23 | + HTTP2_HEADER_COOKIE, | ||
| 24 | + HTTP2_HEADER_METHOD, | ||
| 25 | + HTTP2_HEADER_PATH, | ||
| 26 | + HTTP2_HEADER_SCHEME, | ||
| 27 | + HTTP2_HEADER_SET_COOKIE, | ||
| 28 | + HTTP2_HEADER_STATUS, | ||
| 29 | + NGHTTP2_NO_ERROR, | ||
| 30 | + } = internalBinding('http2').constants; | ||
| 31 | + | ||
| 32 | + const kRequestUrl = Symbol('kRequestUrl'); | ||
| 33 | + | ||
| 34 | + // Convert a Headers object (Map<string, number | string | string[]>) to a plain object (Map<string, string>) | ||
| 35 | + function convertHeaderObject(headers = {}) { | ||
| 36 | + let scheme; | ||
| 37 | + let authority; | ||
| 38 | + let path; | ||
| 39 | + let method; | ||
| 40 | + let statusCode; | ||
| 41 | + let charset; | ||
| 42 | + let mimeType; | ||
| 43 | + const dict = {}; | ||
| 44 | + | ||
| 45 | + for (const { 0: key, 1: value } of ObjectEntries(headers)) { | ||
| 46 | + const lowerCasedKey = key.toLowerCase(); | ||
| 47 | + | ||
| 48 | + if (lowerCasedKey === HTTP2_HEADER_SCHEME) { | ||
| 49 | + scheme = value; | ||
| 50 | + } else if (lowerCasedKey === HTTP2_HEADER_AUTHORITY) { | ||
| 51 | + authority = value; | ||
| 52 | + } else if (lowerCasedKey === HTTP2_HEADER_PATH) { | ||
| 53 | + path = value; | ||
| 54 | + } else if (lowerCasedKey === HTTP2_HEADER_METHOD) { | ||
| 55 | + method = value; | ||
| 56 | + } else if (lowerCasedKey === HTTP2_HEADER_STATUS) { | ||
| 57 | + statusCode = value; | ||
| 58 | + } else if (lowerCasedKey === HTTP2_HEADER_CONTENT_TYPE) { | ||
| 59 | + const result = sniffMimeType(value); | ||
| 60 | + charset = result.charset; | ||
| 61 | + mimeType = result.mimeType; | ||
| 62 | + } | ||
| 63 | + | ||
| 64 | + if (typeof value === 'string') { | ||
| 65 | + dict[key] = value; | ||
| 66 | + } else if (ArrayIsArray(value)) { | ||
| 67 | + if (lowerCasedKey === HTTP2_HEADER_COOKIE) dict[key] = value.join('; '); | ||
| 68 | + // ChromeDevTools frontend treats 'set-cookie' as a special case | ||
| 69 | + // https://github.com/ChromeDevTools/devtools-frontend/blob/4275917f84266ef40613db3c1784a25f902ea74e/front_end/core/sdk/NetworkRequest.ts#L1368 | ||
| 70 | + else if (lowerCasedKey === HTTP2_HEADER_SET_COOKIE) dict[key] = value.join('\n'); | ||
| 71 | + else dict[key] = value.join(', '); | ||
| 72 | + } else { | ||
| 73 | + dict[key] = String(value); | ||
| 74 | + } | ||
| 75 | + } | ||
| 76 | + | ||
| 77 | + const url = `${scheme}://${authority}${path}`; | ||
| 78 | + | ||
| 79 | + return [dict, url, method, statusCode, charset, mimeType]; | ||
| 80 | + } | ||
| 81 | + | ||
| 82 | + /** | ||
| 83 | + * When a client stream is created, emit Network.requestWillBeSent event. | ||
| 84 | + * https://chromedevtools.github.io/devtools-protocol/1-3/Network/#event-requestWillBeSent | ||
| 85 | + * @param {{ stream: import('http2').ClientHttp2Stream, headers: object }} event | ||
| 86 | + */ | ||
| 87 | + function onClientStreamCreated({ stream, headers }) { | ||
| 88 | + stream[kInspectorRequestId] = getNextRequestId(); | ||
| 89 | + | ||
| 90 | + const { 0: convertedHeaderObject, 1: url, 2: method, 4: charset } = convertHeaderObject(headers); | ||
| 91 | + stream[kRequestUrl] = url; | ||
| 92 | + | ||
| 93 | + Network.requestWillBeSent({ | ||
| 94 | + requestId: stream[kInspectorRequestId], | ||
| 95 | + timestamp: getMonotonicTime(), | ||
| 96 | + wallTime: DateNow(), | ||
| 97 | + charset, | ||
| 98 | + request: { | ||
| 99 | + url, | ||
| 100 | + method, | ||
| 101 | + headers: convertedHeaderObject, | ||
| 102 | + }, | ||
| 103 | + }); | ||
| 104 | + } | ||
| 105 | + | ||
| 106 | + /** | ||
| 107 | + * When a client stream errors, emit Network.loadingFailed event. | ||
| 108 | + * https://chromedevtools.github.io/devtools-protocol/1-3/Network/#event-loadingFailed | ||
| 109 | + * @param {{ stream: import('http2').ClientHttp2Stream, error: any }} event | ||
| 110 | + */ | ||
| 111 | + function onClientStreamError({ stream, error }) { | ||
| 112 | + if (typeof stream[kInspectorRequestId] !== 'string') { | ||
| 113 | + return; | ||
| 114 | + } | ||
| 115 | + | ||
| 116 | + Network.loadingFailed({ | ||
| 117 | + requestId: stream[kInspectorRequestId], | ||
| 118 | + timestamp: getMonotonicTime(), | ||
| 119 | + type: kResourceType.Other, | ||
| 120 | + errorText: error.message, | ||
| 121 | + }); | ||
| 122 | + } | ||
| 123 | + | ||
| 124 | + /** | ||
| 125 | + * When response headers are received, emit Network.responseReceived event. | ||
| 126 | + * https://chromedevtools.github.io/devtools-protocol/1-3/Network/#event-responseReceived | ||
| 127 | + * @param {{ stream: import('http2').ClientHttp2Stream, headers: object }} event | ||
| 128 | + */ | ||
| 129 | + function onClientStreamFinish({ stream, headers }) { | ||
| 130 | + if (typeof stream[kInspectorRequestId] !== 'string') { | ||
| 131 | + return; | ||
| 132 | + } | ||
| 133 | + | ||
| 134 | + const { 0: convertedHeaderObject, 3: statusCode, 4: charset, 5: mimeType } = convertHeaderObject(headers); | ||
| 135 | + | ||
| 136 | + Network.responseReceived({ | ||
| 137 | + requestId: stream[kInspectorRequestId], | ||
| 138 | + timestamp: getMonotonicTime(), | ||
| 139 | + type: kResourceType.Other, | ||
| 140 | + response: { | ||
| 141 | + url: stream[kRequestUrl], | ||
| 142 | + status: statusCode, | ||
| 143 | + statusText: '', | ||
| 144 | + headers: convertedHeaderObject, | ||
| 145 | + mimeType, | ||
| 146 | + charset, | ||
| 147 | + }, | ||
| 148 | + }); | ||
| 149 | + } | ||
| 150 | + | ||
| 151 | + /** | ||
| 152 | + * When user code completes consuming the response body, emit Network.loadingFinished event. | ||
| 153 | + * https://chromedevtools.github.io/devtools-protocol/1-3/Network/#event-loadingFinished | ||
| 154 | + * @param {{ stream: import('http2').ClientHttp2Stream }} event | ||
| 155 | + */ | ||
| 156 | + function onClientStreamClose({ stream }) { | ||
| 157 | + if (typeof stream[kInspectorRequestId] !== 'string') { | ||
| 158 | + return; | ||
| 159 | + } | ||
| 160 | + | ||
| 161 | + if (stream.rstCode !== NGHTTP2_NO_ERROR) { | ||
| 162 | + // This is an error case, so only Network.loadingFailed should be emitted | ||
| 163 | + // which is already done by onClientStreamError(). | ||
| 164 | + return; | ||
| 165 | + } | ||
| 166 | + | ||
| 167 | + Network.loadingFinished({ | ||
| 168 | + requestId: stream[kInspectorRequestId], | ||
| 169 | + timestamp: getMonotonicTime(), | ||
| 170 | + }); | ||
| 171 | + } | ||
| 172 | + | ||
| 173 | + function enable() { | ||
| 174 | + dc.subscribe('http2.client.stream.created', onClientStreamCreated); | ||
| 175 | + dc.subscribe('http2.client.stream.error', onClientStreamError); | ||
| 176 | + dc.subscribe('http2.client.stream.finish', onClientStreamFinish); | ||
| 177 | + dc.subscribe('http2.client.stream.close', onClientStreamClose); | ||
| 178 | + } | ||
| 179 | + | ||
| 180 | + function disable() { | ||
| 181 | + dc.unsubscribe('http2.client.stream.created', onClientStreamCreated); | ||
| 182 | + dc.unsubscribe('http2.client.stream.error', onClientStreamError); | ||
| 183 | + dc.unsubscribe('http2.client.stream.finish', onClientStreamFinish); | ||
| 184 | + dc.unsubscribe('http2.client.stream.close', onClientStreamClose); | ||
| 185 | + } | ||
| 186 | + | ||
| 187 | + module.exports = { | ||
| 188 | + enable, | ||
| 189 | + disable, | ||
| 190 | + }; | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2,11 +2,13 @@ | |||
| 2 | 2 | ||
| 3 | 3 | function enable() { | |
| 4 | 4 | require('internal/inspector/network_http').enable(); | |
| 5 | + require('internal/inspector/network_http2').enable(); | ||
| 5 | 6 | require('internal/inspector/network_undici').enable(); | |
| 6 | 7 | } | |
| 7 | 8 | ||
| 8 | 9 | function disable() { | |
| 9 | 10 | require('internal/inspector/network_http').disable(); | |
| 11 | + require('internal/inspector/network_http2').disable(); | ||
| 10 | 12 | require('internal/inspector/network_undici').disable(); | |
| 11 | 13 | } | |
| 12 | 14 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -122,8 +122,8 @@ BuiltinLoader::BuiltinCategories BuiltinLoader::GetBuiltinCategories() const { | |||
| 122 | 122 | #if !HAVE_INSPECTOR | |
| 123 | 123 | "inspector", "inspector/promises", "internal/util/inspector", | |
| 124 | 124 | "internal/inspector/network", "internal/inspector/network_http", | |
| 125 | - "internal/inspector/network_undici", "internal/inspector_async_hook", | ||
| 126 | - "internal/inspector_network_tracking", | ||
| 125 | + "internal/inspector/network_http2", "internal/inspector/network_undici", | ||
| 126 | + "internal/inspector_async_hook", "internal/inspector_network_tracking", | ||
| 127 | 127 | #endif // !HAVE_INSPECTOR | |
| 128 | 128 | ||
| 129 | 129 | #if !NODE_USE_V8_PLATFORM || !defined(NODE_HAVE_I18N_SUPPORT) | |
| Back | FazBrowse Home | New Git URL |
0 commit comments