Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

inspector: add Network.Initiator in inspector protocol #56805

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions lib/internal/inspector/network_http.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@ const convertHeaderObject = (headers = {}) => {
};

/**
* When a client request starts, emit Network.requestWillBeSent event.
* When a client request is created, emit Network.requestWillBeSent event.
* https://chromedevtools.github.io/devtools-protocol/1-3/Network/#event-requestWillBeSent
* @param {{ request: import('http').ClientRequest }} event
*/
function onClientRequestStart({ request }) {
function onClientRequestCreated({ request }) {
request[kInspectorRequestId] = getNextRequestId();

const { 0: host, 1: headers } = convertHeaderObject(request.getHeaders());
Expand Down Expand Up @@ -115,13 +115,13 @@ function onClientResponseFinish({ request, response }) {
}

function enable() {
dc.subscribe('http.client.request.start', onClientRequestStart);
dc.subscribe('http.client.request.created', onClientRequestCreated);
dc.subscribe('http.client.request.error', onClientRequestError);
dc.subscribe('http.client.response.finish', onClientResponseFinish);
}

function disable() {
dc.unsubscribe('http.client.request.start', onClientRequestStart);
dc.unsubscribe('http.client.request.created', onClientRequestCreated);
dc.unsubscribe('http.client.request.error', onClientRequestError);
dc.unsubscribe('http.client.response.finish', onClientResponseFinish);
}
Expand Down
8 changes: 4 additions & 4 deletions lib/internal/inspector/network_undici.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,10 @@ function enable() {
}

function disable() {
dc.subscribe('undici:request:create', onClientRequestStart);
dc.subscribe('undici:request:error', onClientRequestError);
dc.subscribe('undici:request:headers', onClientResponseHeaders);
dc.subscribe('undici:request:trailers', onClientResponseFinish);
dc.unsubscribe('undici:request:create', onClientRequestStart);
dc.unsubscribe('undici:request:error', onClientRequestError);
dc.unsubscribe('undici:request:headers', onClientResponseHeaders);
dc.unsubscribe('undici:request:trailers', onClientResponseFinish);
}

module.exports = {
Expand Down
13 changes: 11 additions & 2 deletions src/inspector/network_agent.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ std::unique_ptr<Network::Response> createResponse(
.build();
}

NetworkAgent::NetworkAgent(NetworkInspector* inspector)
: inspector_(inspector) {
NetworkAgent::NetworkAgent(NetworkInspector* inspector,
v8_inspector::V8Inspector* v8_inspector)
: inspector_(inspector), v8_inspector_(v8_inspector) {
event_notifier_map_["requestWillBeSent"] = &NetworkAgent::requestWillBeSent;
event_notifier_map_["responseReceived"] = &NetworkAgent::responseReceived;
event_notifier_map_["loadingFailed"] = &NetworkAgent::loadingFailed;
Expand Down Expand Up @@ -75,6 +76,13 @@ void NetworkAgent::requestWillBeSent(
String method;
request->getString("method", &method);

std::unique_ptr<Network::Initiator> initiator =
Network::Initiator::create()
.setType(Network::Initiator::TypeEnum::Script)
.setStack(
v8_inspector_->captureStackTrace(true)->buildInspectorObject(0))
.build();

ErrorSupport errors;
errors.Push();
errors.SetName("headers");
Expand All @@ -86,6 +94,7 @@ void NetworkAgent::requestWillBeSent(

frontend_->requestWillBeSent(request_id,
createRequest(url, method, std::move(headers)),
std::move(initiator),
timestamp,
wall_time);
}
Expand Down
4 changes: 3 additions & 1 deletion src/inspector/network_agent.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ namespace protocol {

class NetworkAgent : public Network::Backend {
public:
explicit NetworkAgent(NetworkInspector* inspector);
explicit NetworkAgent(NetworkInspector* inspector,
v8_inspector::V8Inspector* v8_inspector);

void Wire(UberDispatcher* dispatcher);

Expand All @@ -35,6 +36,7 @@ class NetworkAgent : public Network::Backend {

private:
NetworkInspector* inspector_;
v8_inspector::V8Inspector* v8_inspector_;
std::shared_ptr<Network::Frontend> frontend_;
using EventNotifier =
void (NetworkAgent::*)(std::unique_ptr<protocol::DictionaryValue>);
Expand Down
5 changes: 3 additions & 2 deletions src/inspector/network_inspector.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
namespace node {
namespace inspector {

NetworkInspector::NetworkInspector(Environment* env)
NetworkInspector::NetworkInspector(Environment* env,
v8_inspector::V8Inspector* v8_inspector)
: enabled_(false), env_(env) {
network_agent_ = std::make_unique<protocol::NetworkAgent>(this);
network_agent_ = std::make_unique<protocol::NetworkAgent>(this, v8_inspector);
}
NetworkInspector::~NetworkInspector() {
network_agent_.reset();
Expand Down
3 changes: 2 additions & 1 deletion src/inspector/network_inspector.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ namespace inspector {

class NetworkInspector {
public:
explicit NetworkInspector(Environment* env);
explicit NetworkInspector(Environment* env,
v8_inspector::V8Inspector* v8_inspector);
anonrig marked this conversation as resolved.
Show resolved Hide resolved
~NetworkInspector();

void Wire(protocol::UberDispatcher* dispatcher);
Expand Down
4 changes: 4 additions & 0 deletions src/inspector/node_inspector.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@
'<(SHARED_INTERMEDIATE_DIR)/include', # for inspector
'<(SHARED_INTERMEDIATE_DIR)',
'<(SHARED_INTERMEDIATE_DIR)/src', # for inspector
# TODO(legendecas): Convert `tools/v8_gypfiles/inspector.gypi` to a dependable target
# and remove this duplication of variable `inspector_generated_output_root`.
'<(SHARED_INTERMEDIATE_DIR)/inspector-generated-output-root/include', # for v8_inspector
],
'dependencies': [
'<(protocol_tool_path)/inspector_protocol.gyp:crdtp',
Expand All @@ -95,6 +98,7 @@
'action_name': 'node_protocol_generated_sources',
'inputs': [
'node_protocol_config.json',
'node_protocol.pdl',
'<(SHARED_INTERMEDIATE_DIR)/src/node_protocol.json',
'<@(node_protocol_files)',
'<(protocol_tool_path)/code_generator.py',
Expand Down
29 changes: 29 additions & 0 deletions src/inspector/node_protocol.pdl
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ experimental domain NodeWorker
# Partial support for Network domain of ChromeDevTools Protocol.
# https://chromedevtools.github.io/devtools-protocol/tot/Network
experimental domain Network
depends on Runtime

# Resource type as it was perceived by the rendering engine.
type ResourceType extends string
enum
Expand Down Expand Up @@ -132,6 +134,31 @@ experimental domain Network
# Monotonically increasing time in seconds since an arbitrary point in the past.
type MonotonicTime extends number

# Information about the request initiator.
type Initiator extends object
properties
# Type of this initiator.
enum type
parser
script
preload
SignedExchange
preflight
other
# Initiator JavaScript stack trace, set for Script only.
# Requires the Debugger domain to be enabled.
optional Runtime.StackTrace stack
# Initiator URL, set for Parser type or for Script type (when script is importing module) or for SignedExchange type.
optional string url
# Initiator line number, set for Parser type or for Script type (when script is importing
# module) (0-based).
optional number lineNumber
# Initiator column number, set for Parser type or for Script type (when script is importing
# module) (0-based).
optional number columnNumber
# Set if another request triggered this request (e.g. preflight).
optional RequestId requestId

# HTTP request data.
type Request extends object
properties
Expand Down Expand Up @@ -163,6 +190,8 @@ experimental domain Network
RequestId requestId
# Request data.
Request request
# Request initiator.
Initiator initiator
# Timestamp.
MonotonicTime timestamp
# Timestamp.
Expand Down
11 changes: 11 additions & 0 deletions src/inspector/node_protocol_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,17 @@
"output": "node/inspector/protocol",
"namespace": ["node", "inspector", "protocol"]
},
"imported": {
"path": "../../deps/v8/include/js_protocol.pdl",
"header": "<v8-inspector-protocol.h>",
"namespace": ["v8_inspector", "protocol"],
"options": [
{
"domain": "Runtime",
"imported": ["StackTrace"]
}
]
},
"exported": {
"package": "include/inspector",
"output": "../../include/inspector",
Expand Down
3 changes: 2 additions & 1 deletion src/inspector_agent.cc
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,8 @@ class ChannelImpl final : public v8_inspector::V8Inspector::Channel,
}
runtime_agent_ = std::make_unique<protocol::RuntimeAgent>();
runtime_agent_->Wire(node_dispatcher_.get());
network_inspector_ = std::make_unique<NetworkInspector>(env);
network_inspector_ =
std::make_unique<NetworkInspector>(env, inspector.get());
network_inspector_->Wire(node_dispatcher_.get());
}

Expand Down
11 changes: 11 additions & 0 deletions test/parallel/test-inspector-network-fetch.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,13 @@ const terminate = () => {
inspector.close();
};

function findFrameInInitiator(scriptName, initiator) {
const frame = initiator.stack.callFrames.find((it) => {
return it.url === scriptName;
});
return frame;
}

const testHttpGet = () => new Promise((resolve, reject) => {
session.on('Network.requestWillBeSent', common.mustCall(({ params }) => {
assert.ok(params.requestId.startsWith('node-network-event-'));
Expand All @@ -77,6 +84,10 @@ const testHttpGet = () => new Promise((resolve, reject) => {
assert.strictEqual(params.request.headers['x-header1'], 'value1, value2');
assert.strictEqual(typeof params.timestamp, 'number');
assert.strictEqual(typeof params.wallTime, 'number');

assert.strictEqual(typeof params.initiator, 'object');
assert.strictEqual(params.initiator.type, 'script');
assert.ok(findFrameInInitiator(__filename, params.initiator));
}));
session.on('Network.responseReceived', common.mustCall(({ params }) => {
assert.ok(params.requestId.startsWith('node-network-event-'));
Expand Down
11 changes: 11 additions & 0 deletions test/parallel/test-inspector-network-http.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,13 @@ const terminate = () => {
inspector.close();
};

function findFrameInInitiator(scriptName, initiator) {
const frame = initiator.stack.callFrames.find((it) => {
return it.url === scriptName;
});
return frame;
}

function verifyRequestWillBeSent({ method, params }, expect) {
assert.strictEqual(method, 'Network.requestWillBeSent');

Expand All @@ -78,6 +85,10 @@ function verifyRequestWillBeSent({ method, params }, expect) {
assert.strictEqual(typeof params.timestamp, 'number');
assert.strictEqual(typeof params.wallTime, 'number');

assert.strictEqual(typeof params.initiator, 'object');
assert.strictEqual(params.initiator.type, 'script');
assert.ok(findFrameInInitiator(__filename, params.initiator));

return params;
}

Expand Down
Loading