inspector: add protocol methods retrieving sent/received data · nodejs/node@be93091 · GitHub
Skip to content

Commit be93091

Browse files
legendecasRafaelGSS
authored andcommitted
inspector: add protocol methods retrieving sent/received data
Add protocol method `Network.dataSent` to buffer request data. And expose protocol methods `Network.getRequestPostData` and `Network.getResponseBody` allowing devtool to retrieve buffered data. PR-URL: #58645 Reviewed-By: Ryuhei Shima <shimaryuhei@gmail.com>
1 parent b5ff3f4 commit be93091

11 files changed

Lines changed: 480 additions & 85 deletions

doc/api/inspector.md

Lines changed: 14 additions & 0 deletions

lib/inspector.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ const Network = {
214214
responseReceived: (params) => broadcastToFrontend('Network.responseReceived', params),
215215
loadingFinished: (params) => broadcastToFrontend('Network.loadingFinished', params),
216216
loadingFailed: (params) => broadcastToFrontend('Network.loadingFailed', params),
217+
dataSent: (params) => broadcastToFrontend('Network.dataSent', params),
217218
dataReceived: (params) => broadcastToFrontend('Network.dataReceived', params),
218219
};
219220

lib/internal/inspector/network.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ const {
66
} = primordials;
77

88
const { now } = require('internal/perf/utils');
9+
const { MIMEType } = require('internal/mime');
910
const kInspectorRequestId = Symbol('kInspectorRequestId');
1011

1112
// https://chromedevtools.github.io/devtools-protocol/1-3/Network/#type-ResourceType
@@ -46,9 +47,29 @@ function getNextRequestId() {
4647
return `node-network-event-${++requestId}`;
4748
};
4849

50+
function sniffMimeType(contentType) {
51+
let mimeType;
52+
let charset;
53+
try {
54+
const mimeTypeObj = new MIMEType(contentType);
55+
mimeType = mimeTypeObj.essence || '';
56+
charset = mimeTypeObj.params.get('charset') || '';
57+
} catch {
58+
mimeType = '';
59+
charset = '';
60+
}
61+
62+
return {
63+
__proto__: null,
64+
mimeType,
65+
charset,
66+
};
67+
}
68+
4969
module.exports = {
5070
kInspectorRequestId,
5171
kResourceType,
5272
getMonotonicTime,
5373
getNextRequestId,
74+
sniffMimeType,
5475
};

lib/internal/inspector/network_http.js

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,35 +13,43 @@ const {
1313
kResourceType,
1414
getMonotonicTime,
1515
getNextRequestId,
16+
sniffMimeType,
1617
} = require('internal/inspector/network');
1718
const dc = require('diagnostics_channel');
1819
const { Network } = require('inspector');
19-
const { MIMEType } = require('internal/mime');
2020

2121
const kRequestUrl = Symbol('kRequestUrl');
2222

2323
// Convert a Headers object (Map<string, number | string | string[]>) to a plain object (Map<string, string>)
2424
const convertHeaderObject = (headers = {}) => {
2525
// The 'host' header that contains the host and port of the URL.
2626
let host;
27+
let charset;
28+
let mimeType;
2729
const dict = {};
2830
for (const { 0: key, 1: value } of ObjectEntries(headers)) {
29-
if (key.toLowerCase() === 'host') {
31+
const lowerCasedKey = key.toLowerCase();
32+
if (lowerCasedKey === 'host') {
3033
host = value;
3134
}
35+
if (lowerCasedKey === 'content-type') {
36+
const result = sniffMimeType(value);
37+
charset = result.charset;
38+
mimeType = result.mimeType;
39+
}
3240
if (typeof value === 'string') {
3341
dict[key] = value;
3442
} else if (ArrayIsArray(value)) {
35-
if (key.toLowerCase() === 'cookie') dict[key] = value.join('; ');
43+
if (lowerCasedKey === 'cookie') dict[key] = value.join('; ');
3644
// ChromeDevTools frontend treats 'set-cookie' as a special case
3745
// https://github.com/ChromeDevTools/devtools-frontend/blob/4275917f84266ef40613db3c1784a25f902ea74e/front_end/core/sdk/NetworkRequest.ts#L1368
38-
else if (key.toLowerCase() === 'set-cookie') dict[key] = value.join('\n');
46+
else if (lowerCasedKey === 'set-cookie') dict[key] = value.join('\n');
3947
else dict[key] = value.join(', ');
4048
} else {
4149
dict[key] = String(value);
4250
}
4351
}
44-
return [host, dict];
52+
return [dict, host, charset, mimeType];
4553
};
4654

4755
/**
@@ -52,14 +60,15 @@ const convertHeaderObject = (headers = {}) => {
5260
function onClientRequestCreated({ request }) {
5361
request[kInspectorRequestId] = getNextRequestId();
5462

55-
const { 0: host, 1: headers } = convertHeaderObject(request.getHeaders());
63+
const { 0: headers, 1: host, 2: charset } = convertHeaderObject(request.getHeaders());
5664
const url = `${request.protocol}//${host}${request.path}`;
5765
request[kRequestUrl] = url;
5866

5967
Network.requestWillBeSent({
6068
requestId: request[kInspectorRequestId],
6169
timestamp: getMonotonicTime(),
6270
wallTime: DateNow(),
71+
charset,
6372
request: {
6473
url,
6574
method: request.method,
@@ -95,16 +104,7 @@ function onClientResponseFinish({ request, response }) {
95104
return;
96105
}
97106

98-
let mimeType;
99-
let charset;
100-
try {
101-
const mimeTypeObj = new MIMEType(response.headers['content-type']);
102-
mimeType = mimeTypeObj.essence || '';
103-
charset = mimeTypeObj.params.get('charset') || '';
104-
} catch {
105-
mimeType = '';
106-
charset = '';
107-
}
107+
const { 0: headers, 2: charset, 3: mimeType } = convertHeaderObject(response.headers);
108108

109109
Network.responseReceived({
110110
requestId: request[kInspectorRequestId],
@@ -114,7 +114,7 @@ function onClientResponseFinish({ request, response }) {
114114
url: request[kRequestUrl],
115115
status: response.statusCode,
116116
statusText: response.statusMessage ?? '',
117-
headers: convertHeaderObject(response.headers)[1],
117+
headers,
118118
mimeType,
119119
charset,
120120
},

lib/internal/inspector/network_undici.js

Lines changed: 19 additions & 18 deletions

0 commit comments

Comments
 (0)