Skip to content

Commit

Permalink
inspector: convert a header object to a simple string dictionary
Browse files Browse the repository at this point in the history
  • Loading branch information
cola119 committed Aug 2, 2024
1 parent a489613 commit e02aaa7
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 2 deletions.
26 changes: 24 additions & 2 deletions lib/internal/inspector_network_tracking.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
'use strict';

const {
ArrayIsArray,
DateNow,
ObjectEntries,
String,
} = primordials;

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

// Convert a Headers object (Map<string, number | string | string[]>) to a plain object (Map<string, string>)
const headerObjectToDictionary = (headers = {}) => {
const dict = {};
for (const { 0: key, 1: value } of ObjectEntries(headers)) {
if (typeof value === 'string') {
dict[key] = value;
} else if (ArrayIsArray(value)) {
if (key.toLowerCase() === 'cookie') dict[key] = value.join('; ');
// ChromeDevTools frontend treats 'set-cookie' as a special case
// https://github.com/ChromeDevTools/devtools-frontend/blob/4275917f84266ef40613db3c1784a25f902ea74e/front_end/core/sdk/NetworkRequest.ts#L1368
else if (key.toLowerCase() === 'set-cookie') dict[key] = value.join('\n');
else dict[key] = value.join(', ');
} else {
dict[key] = String(value);
}
}
return dict;
};

function onClientRequestStart({ request }) {
const url = `${request.protocol}//${request.host}${request.path}`;
const wallTime = DateNow();
Expand All @@ -22,7 +44,7 @@ function onClientRequestStart({ request }) {
request: {
url,
method: request.method,
headers: request.getHeaders(),
headers: headerObjectToDictionary(request.getHeaders()),
},
});
}
Expand All @@ -41,7 +63,7 @@ function onClientResponseFinish({ request, response }) {
url,
status: response.statusCode,
statusText: response.statusMessage ?? '',
headers: response.headers,
headers: headerObjectToDictionary(response.headers),
},
});
Network.loadingFinished({
Expand Down
34 changes: 34 additions & 0 deletions test/parallel/test-inspector-network-domain.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,25 @@ const inspector = require('node:inspector/promises');
const session = new inspector.Session();
session.connect();

const requestHeaders = {
'accept-language': 'en-US',
'Cookie': ['k1=v1', 'k2=v2'],
'age': 1000,
'x-header1': ['value1', 'value2']
};

const setResponseHeaders = (res) => {
res.setHeader('server', 'node');
res.setHeader('etag', 12345);
res.setHeader('Set-Cookie', ['key1=value1', 'key2=value2']);
res.setHeader('x-header2', ['value1', 'value2']);
};

const httpServer = http.createServer((req, res) => {
const path = req.url;
switch (path) {
case '/hello-world':
setResponseHeaders(res);
res.writeHead(200);
res.end('hello world\n');
break;
Expand All @@ -32,6 +47,7 @@ const httpsServer = https.createServer({
const path = req.url;
switch (path) {
case '/hello-world':
setResponseHeaders(res);
res.writeHead(200);
res.end('hello world\n');
break;
Expand All @@ -53,6 +69,10 @@ const testHttpGet = () => new Promise((resolve, reject) => {
assert.strictEqual(params.request.url, 'http://127.0.0.1/hello-world');
assert.strictEqual(params.request.method, 'GET');
assert.strictEqual(typeof params.request.headers, 'object');
assert.strictEqual(params.request.headers['accept-language'], 'en-US');
assert.strictEqual(params.request.headers.cookie, 'k1=v1; k2=v2');
assert.strictEqual(params.request.headers.age, '1000');
assert.strictEqual(params.request.headers['x-header1'], 'value1, value2');
assert.strictEqual(typeof params.timestamp, 'number');
assert.strictEqual(typeof params.wallTime, 'number');
}));
Expand All @@ -64,6 +84,10 @@ const testHttpGet = () => new Promise((resolve, reject) => {
assert.strictEqual(params.response.statusText, 'OK');
assert.strictEqual(params.response.url, 'http://127.0.0.1/hello-world');
assert.strictEqual(typeof params.response.headers, 'object');
assert.strictEqual(params.response.headers.server, 'node');
assert.strictEqual(params.response.headers.etag, '12345');
assert.strictEqual(params.response.headers['set-cookie'], 'key1=value1\nkey2=value2');
assert.strictEqual(params.response.headers['x-header2'], 'value1, value2');
}));
session.on('Network.loadingFinished', common.mustCall(({ params }) => {
assert.ok(params.requestId.startsWith('node-network-event-'));
Expand All @@ -75,6 +99,7 @@ const testHttpGet = () => new Promise((resolve, reject) => {
host: '127.0.0.1',
port: httpServer.address().port,
path: '/hello-world',
headers: requestHeaders
}, common.mustCall());
});

Expand All @@ -84,6 +109,10 @@ const testHttpsGet = () => new Promise((resolve, reject) => {
assert.strictEqual(params.request.url, 'https://127.0.0.1/hello-world');
assert.strictEqual(params.request.method, 'GET');
assert.strictEqual(typeof params.request.headers, 'object');
assert.strictEqual(params.request.headers['accept-language'], 'en-US');
assert.strictEqual(params.request.headers.cookie, 'k1=v1; k2=v2');
assert.strictEqual(params.request.headers.age, '1000');
assert.strictEqual(params.request.headers['x-header1'], 'value1, value2');
assert.strictEqual(typeof params.timestamp, 'number');
assert.strictEqual(typeof params.wallTime, 'number');
}));
Expand All @@ -95,6 +124,10 @@ const testHttpsGet = () => new Promise((resolve, reject) => {
assert.strictEqual(params.response.statusText, 'OK');
assert.strictEqual(params.response.url, 'https://127.0.0.1/hello-world');
assert.strictEqual(typeof params.response.headers, 'object');
assert.strictEqual(params.response.headers.server, 'node');
assert.strictEqual(params.response.headers.etag, '12345');
assert.strictEqual(params.response.headers['set-cookie'], 'key1=value1\nkey2=value2');
assert.strictEqual(params.response.headers['x-header2'], 'value1, value2');
}));
session.on('Network.loadingFinished', common.mustCall(({ params }) => {
assert.ok(params.requestId.startsWith('node-network-event-'));
Expand All @@ -107,6 +140,7 @@ const testHttpsGet = () => new Promise((resolve, reject) => {
port: httpsServer.address().port,
path: '/hello-world',
rejectUnauthorized: false,
headers: requestHeaders,
}, common.mustCall());
});

Expand Down

0 comments on commit e02aaa7

Please sign in to comment.