Skip to content

Commit e02aaa7

Browse files
committed
inspector: convert a header object to a simple string dictionary
1 parent a489613 commit e02aaa7

File tree

2 files changed

+58
-2
lines changed

2 files changed

+58
-2
lines changed

lib/internal/inspector_network_tracking.js

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
'use strict';
22

33
const {
4+
ArrayIsArray,
45
DateNow,
6+
ObjectEntries,
7+
String,
58
} = primordials;
69

710
let dc;
@@ -10,6 +13,25 @@ let Network;
1013
let requestId = 0;
1114
const getNextRequestId = () => `node-network-event-${++requestId}`;
1215

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+
1335
function onClientRequestStart({ request }) {
1436
const url = `${request.protocol}//${request.host}${request.path}`;
1537
const wallTime = DateNow();
@@ -22,7 +44,7 @@ function onClientRequestStart({ request }) {
2244
request: {
2345
url,
2446
method: request.method,
25-
headers: request.getHeaders(),
47+
headers: headerObjectToDictionary(request.getHeaders()),
2648
},
2749
});
2850
}
@@ -41,7 +63,7 @@ function onClientResponseFinish({ request, response }) {
4163
url,
4264
status: response.statusCode,
4365
statusText: response.statusMessage ?? '',
44-
headers: response.headers,
66+
headers: headerObjectToDictionary(response.headers),
4567
},
4668
});
4769
Network.loadingFinished({

test/parallel/test-inspector-network-domain.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,25 @@ const inspector = require('node:inspector/promises');
1313
const session = new inspector.Session();
1414
session.connect();
1515

16+
const requestHeaders = {
17+
'accept-language': 'en-US',
18+
'Cookie': ['k1=v1', 'k2=v2'],
19+
'age': 1000,
20+
'x-header1': ['value1', 'value2']
21+
};
22+
23+
const setResponseHeaders = (res) => {
24+
res.setHeader('server', 'node');
25+
res.setHeader('etag', 12345);
26+
res.setHeader('Set-Cookie', ['key1=value1', 'key2=value2']);
27+
res.setHeader('x-header2', ['value1', 'value2']);
28+
};
29+
1630
const httpServer = http.createServer((req, res) => {
1731
const path = req.url;
1832
switch (path) {
1933
case '/hello-world':
34+
setResponseHeaders(res);
2035
res.writeHead(200);
2136
res.end('hello world\n');
2237
break;
@@ -32,6 +47,7 @@ const httpsServer = https.createServer({
3247
const path = req.url;
3348
switch (path) {
3449
case '/hello-world':
50+
setResponseHeaders(res);
3551
res.writeHead(200);
3652
res.end('hello world\n');
3753
break;
@@ -53,6 +69,10 @@ const testHttpGet = () => new Promise((resolve, reject) => {
5369
assert.strictEqual(params.request.url, 'http://127.0.0.1/hello-world');
5470
assert.strictEqual(params.request.method, 'GET');
5571
assert.strictEqual(typeof params.request.headers, 'object');
72+
assert.strictEqual(params.request.headers['accept-language'], 'en-US');
73+
assert.strictEqual(params.request.headers.cookie, 'k1=v1; k2=v2');
74+
assert.strictEqual(params.request.headers.age, '1000');
75+
assert.strictEqual(params.request.headers['x-header1'], 'value1, value2');
5676
assert.strictEqual(typeof params.timestamp, 'number');
5777
assert.strictEqual(typeof params.wallTime, 'number');
5878
}));
@@ -64,6 +84,10 @@ const testHttpGet = () => new Promise((resolve, reject) => {
6484
assert.strictEqual(params.response.statusText, 'OK');
6585
assert.strictEqual(params.response.url, 'http://127.0.0.1/hello-world');
6686
assert.strictEqual(typeof params.response.headers, 'object');
87+
assert.strictEqual(params.response.headers.server, 'node');
88+
assert.strictEqual(params.response.headers.etag, '12345');
89+
assert.strictEqual(params.response.headers['set-cookie'], 'key1=value1\nkey2=value2');
90+
assert.strictEqual(params.response.headers['x-header2'], 'value1, value2');
6791
}));
6892
session.on('Network.loadingFinished', common.mustCall(({ params }) => {
6993
assert.ok(params.requestId.startsWith('node-network-event-'));
@@ -75,6 +99,7 @@ const testHttpGet = () => new Promise((resolve, reject) => {
7599
host: '127.0.0.1',
76100
port: httpServer.address().port,
77101
path: '/hello-world',
102+
headers: requestHeaders
78103
}, common.mustCall());
79104
});
80105

@@ -84,6 +109,10 @@ const testHttpsGet = () => new Promise((resolve, reject) => {
84109
assert.strictEqual(params.request.url, 'https://127.0.0.1/hello-world');
85110
assert.strictEqual(params.request.method, 'GET');
86111
assert.strictEqual(typeof params.request.headers, 'object');
112+
assert.strictEqual(params.request.headers['accept-language'], 'en-US');
113+
assert.strictEqual(params.request.headers.cookie, 'k1=v1; k2=v2');
114+
assert.strictEqual(params.request.headers.age, '1000');
115+
assert.strictEqual(params.request.headers['x-header1'], 'value1, value2');
87116
assert.strictEqual(typeof params.timestamp, 'number');
88117
assert.strictEqual(typeof params.wallTime, 'number');
89118
}));
@@ -95,6 +124,10 @@ const testHttpsGet = () => new Promise((resolve, reject) => {
95124
assert.strictEqual(params.response.statusText, 'OK');
96125
assert.strictEqual(params.response.url, 'https://127.0.0.1/hello-world');
97126
assert.strictEqual(typeof params.response.headers, 'object');
127+
assert.strictEqual(params.response.headers.server, 'node');
128+
assert.strictEqual(params.response.headers.etag, '12345');
129+
assert.strictEqual(params.response.headers['set-cookie'], 'key1=value1\nkey2=value2');
130+
assert.strictEqual(params.response.headers['x-header2'], 'value1, value2');
98131
}));
99132
session.on('Network.loadingFinished', common.mustCall(({ params }) => {
100133
assert.ok(params.requestId.startsWith('node-network-event-'));
@@ -107,6 +140,7 @@ const testHttpsGet = () => new Promise((resolve, reject) => {
107140
port: httpsServer.address().port,
108141
path: '/hello-world',
109142
rejectUnauthorized: false,
143+
headers: requestHeaders,
110144
}, common.mustCall());
111145
});
112146

0 commit comments

Comments
 (0)