Skip to content

Commit

Permalink
inspector: provide detailed network information to fix devtools front…
Browse files Browse the repository at this point in the history
…end errors
  • Loading branch information
cola119 committed Aug 1, 2024
1 parent e7edcf3 commit fb6195c
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 11 deletions.
10 changes: 9 additions & 1 deletion lib/internal/inspector_network_tracking.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,26 @@ function onClientRequestStart({ request }) {
request: {
url,
method: request.method,
headers: request.getHeaders(),
},
});
}

function onClientResponseFinish({ request }) {
function onClientResponseFinish({ request, response }) {
if (typeof request._inspectorRequestId !== 'string') {
return;
}
const url = `${request.protocol}//${request.host}${request.path}`;
const timestamp = DateNow() / 1000;
Network.responseReceived({
requestId: request._inspectorRequestId,
timestamp,
type: 'Other',
response: {
url,
status: response.statusCode,
headers: response.headers,
},
});
Network.loadingFinished({
requestId: request._inspectorRequestId,
Expand Down
53 changes: 47 additions & 6 deletions src/inspector/network_agent.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,24 @@ namespace node {
namespace inspector {
namespace protocol {

std::unique_ptr<Network::Request> Request(const String& url,
const String& method) {
return Network::Request::create().setUrl(url).setMethod(method).build();
std::unique_ptr<Network::Request> createRequest(
const String& url,
const String& method,
std::unique_ptr<Network::Headers> headers) {
return Network::Request::create()
.setUrl(url)
.setMethod(method)
.setHeaders(std::move(headers))
.build();
}

std::unique_ptr<Network::Response> createResponse(
const String& url, int status, std::unique_ptr<Network::Headers> headers) {
return Network::Response::create()
.setUrl(url)
.setStatus(status)
.setHeaders(std::move(headers))
.build();
}

NetworkAgent::NetworkAgent(NetworkInspector* inspector)
Expand Down Expand Up @@ -55,8 +70,17 @@ void NetworkAgent::requestWillBeSent(
String method;
request->getString("method", &method);

frontend_->requestWillBeSent(
request_id, Request(url, method), timestamp, wall_time);
ErrorSupport errors;
auto headers =
Network::Headers::fromValue(request->getObject("headers"), &errors);
if (errors.hasErrors()) {
headers = std::make_unique<Network::Headers>(DictionaryValue::create());
}

frontend_->requestWillBeSent(request_id,
createRequest(url, method, std::move(headers)),
timestamp,
wall_time);
}

void NetworkAgent::responseReceived(
Expand All @@ -65,8 +89,25 @@ void NetworkAgent::responseReceived(
params->getString("requestId", &request_id);
double timestamp;
params->getDouble("timestamp", &timestamp);
String type;
params->getString("type", &type);
auto response = params->getObject("response");
String url;
response->getString("url", &url);
int status;
response->getInteger("status", &status);

ErrorSupport errors;
auto headers =
Network::Headers::fromValue(response->getObject("headers"), &errors);
if (errors.hasErrors()) {
headers = std::make_unique<Network::Headers>(DictionaryValue::create());
}

frontend_->responseReceived(request_id, timestamp);
frontend_->responseReceived(request_id,
timestamp,
type,
createResponse(url, status, std::move(headers)));
}

void NetworkAgent::loadingFinished(
Expand Down
8 changes: 6 additions & 2 deletions src/inspector/network_agent.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,12 @@ class NetworkInspector;

namespace protocol {

std::unique_ptr<Network::Request> Request(const String& url,
const String& method);
std::unique_ptr<Network::Request> createRequest(
const String& url,
const String& method,
std::unique_ptr<Network::Headers> headers);
std::unique_ptr<Network::Response> createResponse(
const String& url, int status, std::unique_ptr<Network::Headers> headers);

class NetworkAgent : public Network::Backend {
public:
Expand Down
37 changes: 37 additions & 0 deletions src/inspector/node_protocol.pdl
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,28 @@ experimental domain NodeWorker
# Partial support for Network domain of ChromeDevTools Protocol.
# https://chromedevtools.github.io/devtools-protocol/tot/Network
experimental domain Network
# Resource type as it was perceived by the rendering engine.
type ResourceType extends string
enum
Document
Stylesheet
Image
Media
Font
Script
TextTrack
XHR
Fetch
Prefetch
EventSource
WebSocket
Manifest
SignedExchange
Ping
CSPViolationReport
Preflight
Other

# Unique request identifier.
type RequestId extends string

Expand All @@ -115,6 +137,17 @@ experimental domain Network
properties
string url
string method
Headers headers

# HTTP response data.
type Response extends object
properties
string url
integer status
Headers headers

# Request / response headers as keys / values of JSON object.
type Headers extends object

# Disables network tracking, prevents network events from being sent to the client.
command disable
Expand All @@ -141,6 +174,10 @@ experimental domain Network
RequestId requestId
# Timestamp.
MonotonicTime timestamp
# Resource type.
ResourceType type
# Response data.
Response response

event loadingFinished
parameters
Expand Down
20 changes: 18 additions & 2 deletions test/parallel/test-inspector-emit-protocol-event.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,17 @@ const EXPECTED_EVENTS = {
requestId: 'request-id-1',
request: {
url: 'https://nodejs.org/en',
method: 'GET'
method: 'GET',
},
timestamp: 1000,
wallTime: 1000,
},
expected: {
requestId: 'request-id-1',
request: {
url: 'https://nodejs.org/en',
method: 'GET',
headers: {} // Headers should be an empty object if not provided.
},
timestamp: 1000,
wallTime: 1000,
Expand All @@ -26,6 +36,12 @@ const EXPECTED_EVENTS = {
params: {
requestId: 'request-id-1',
timestamp: 1000,
type: 'Other',
response: {
url: 'https://nodejs.org/en',
status: 200,
headers: { host: 'nodejs.org' }
}
}
},
{
Expand Down Expand Up @@ -68,7 +84,7 @@ const runAsyncTest = async () => {
for (const [domain, events] of Object.entries(EXPECTED_EVENTS)) {
for (const event of events) {
session.on(`${domain}.${event.name}`, common.mustCall(({ params }) => {
assert.deepStrictEqual(params, event.params);
assert.deepStrictEqual(params, event.expected ?? event.params);
}));
inspector[domain][event.name](event.params);
}
Expand Down
10 changes: 10 additions & 0 deletions test/parallel/test-inspector-network-domain.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,17 @@ const testHttpGet = () => new Promise((resolve, reject) => {
assert.ok(params.requestId.startsWith('node-network-event-'));
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(typeof params.timestamp, 'number');
assert.strictEqual(typeof params.wallTime, 'number');
}));
session.on('Network.responseReceived', common.mustCall(({ params }) => {
assert.ok(params.requestId.startsWith('node-network-event-'));
assert.strictEqual(typeof params.timestamp, 'number');
assert.strictEqual(params.type, 'Other');
assert.strictEqual(params.response.status, 200);
assert.strictEqual(params.response.url, 'http://127.0.0.1/hello-world');
assert.strictEqual(typeof params.response.headers, 'object');
}));
session.on('Network.loadingFinished', common.mustCall(({ params }) => {
assert.ok(params.requestId.startsWith('node-network-event-'));
Expand All @@ -77,12 +82,17 @@ const testHttpsGet = () => new Promise((resolve, reject) => {
assert.ok(params.requestId.startsWith('node-network-event-'));
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(typeof params.timestamp, 'number');
assert.strictEqual(typeof params.wallTime, 'number');
}));
session.on('Network.responseReceived', common.mustCall(({ params }) => {
assert.ok(params.requestId.startsWith('node-network-event-'));
assert.strictEqual(typeof params.timestamp, 'number');
assert.strictEqual(params.type, 'Other');
assert.strictEqual(params.response.status, 200);
assert.strictEqual(params.response.url, 'https://127.0.0.1/hello-world');
assert.strictEqual(typeof params.response.headers, 'object');
}));
session.on('Network.loadingFinished', common.mustCall(({ params }) => {
assert.ok(params.requestId.startsWith('node-network-event-'));
Expand Down

0 comments on commit fb6195c

Please sign in to comment.