Skip to content

[Site Isolation] Web Inspector: - #77391

Open
burg wants to merge 2 commits into
WebKit:mainfrom
burg:eng/bburg/si-websocket-events
Open

burg wants to merge 2 commits into
WebKit:mainfrom
burg:eng/bburg/si-websocket-events

Conversation

@burg

@burg burg commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

23b5081

[Site Isolation] Web Inspector: Network.resolveWebSocket is not implemented
https://bugs.webkit.org/show_bug.cgi?id=327496

Reviewed by NOBODY (OOPS!).

ProxyingNetworkAgent::resolveWebSocket returned "Not yet implemented", so Log WebSocket on a socket
in the Network tab did nothing under Site Isolation.

The command now routes to the process encoded in the "websocket-<process>.<channel>" requestId. That
process finds the socket among those of the page's documents by its channel's progress identifier
and wraps it with an injected script. A main-frame socket is wrapped by the page's injected script,
because the console's default execution context belongs to the page target; any other socket is
wrapped by the injected script of the frame that owns it. The reply crosses IPC as the
RemoteObject's JSON.

Injected-script object ids restart at 1 in every injected script manager, so an object id is only
meaningful on the target whose injected script made it. The frontend pairs the RemoteObject with
the page target for a main-frame socket and with the frame target that owns the socket's frame
otherwise. If it finds no such target it reports no object rather than pairing the id with another
target, where it could name a different object.

Routing needs an async reply, so resolveWebSocket becomes an async command. InspectorNetworkAgent
keeps its behavior and error strings.

Test: http/tests/site-isolation/inspector/network/cross-origin-iframe-websocket-resolve.html

* LayoutTests/http/tests/site-isolation/inspector/network/cross-origin-iframe-websocket-resolve-expected.txt: Added.
* LayoutTests/http/tests/site-isolation/inspector/network/cross-origin-iframe-websocket-resolve.html: Added.
* LayoutTests/http/tests/site-isolation/inspector/network/resources/websocket-iframe.html:
* LayoutTests/http/tests/site-isolation/inspector/network/resources/websocket-test-utilities.js:
* Source/JavaScriptCore/inspector/protocol/Network.json:
* Source/WebCore/inspector/InspectorResourceUtilities.h:
* Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp:
(WebCore::InspectorNetworkAgent::resolveWebSocket):
(Inspector::ResourceUtilities::resolveWebSocketInFrame):
* Source/WebCore/inspector/agents/InspectorNetworkAgent.h:
* Source/WebInspectorUI/UserInterface/Protocol/RemoteObject.js:
(WI.RemoteObject.resolveWebSocket):
* Source/WebKit/UIProcess/Inspector/Agents/ProxyingNetworkAgent.cpp:
(Inspector::ProxyingNetworkAgent::resolveWebSocket):
* Source/WebKit/UIProcess/Inspector/Agents/ProxyingNetworkAgent.h:
* Source/WebKit/WebProcess/Inspector/WebInspectorBackend.cpp:
(WebKit::WebInspectorBackend::resolveWebSocket):
* Source/WebKit/WebProcess/Inspector/WebInspectorBackend.h:
* Source/WebKit/WebProcess/Inspector/WebInspectorBackend.messages.in:

461420d

[Site Isolation] Web Inspector: WebSocket activity is missing from the Network domain
https://bugs.webkit.org/show_bug.cgi?id=327495

Reviewed by NOBODY (OOPS!).

Under Site Isolation the Network domain is served by ProxyingNetworkAgent in the UI process, fed by
a FrameNetworkAgentProxy per frame. The WebSocket hooks never joined that contract, so no WebSocket
showed up in Network at all, not even one opened by the main frame.

The hooks are now part of NetworkAgentInstrumentation. FrameNetworkAgentProxy forwards each one over
IPC, keyed by its process and the channel's progress identifier, and ProxyingNetworkAgent turns that
into a "websocket-<process>.<channel>" requestId. Channel identifiers come from a different counter
than resource loads, so they take their own prefix. Since the requestId names the process, the UI
process rejects a WebSocket message whose process identifier is not the sender's.

InspectorInstrumentation used to resolve WebSocket hooks through the document's page, which never
reaches a per-frame proxy. They now resolve through the document's frame. A frame's agents fall back
to its page's, so InspectorNetworkAgent still gets them outside Site Isolation.
InspectorNetworkAgent isn't enabled under Site Isolation, so each socket is reported once.

webSocketCreated gains optional frameId and loaderId. NetworkManager uses them to file the
WebSocketResource under the frame that opened it, making a placeholder frame if that frame hasn't
arrived yet. Without them it still files the socket under the main frame. The webSocket* events and
resolveWebSocket now include "web-page" in their targetTypes so the multiplexing target can deliver
them. resolveWebSocket is still unimplemented on ProxyingNetworkAgent.

Sockets that were already open when Network was enabled are not replayed to the frame proxy.

Test: http/tests/site-isolation/inspector/network/cross-origin-iframe-websocket-events.html

* LayoutTests/http/tests/site-isolation/inspector/network/cross-origin-iframe-websocket-events-expected.txt: Added.
* LayoutTests/http/tests/site-isolation/inspector/network/cross-origin-iframe-websocket-events.html: Added.
* LayoutTests/http/tests/site-isolation/inspector/network/resources/websocket-iframe.html: Added.
* LayoutTests/http/tests/site-isolation/inspector/network/resources/websocket-test-utilities.js: Added.
* Source/JavaScriptCore/inspector/protocol/Network.json:
* Source/WebCore/inspector/InspectorIdentifierRegistry.h:
(Inspector::IdentifierRegistry::protocolWebSocketRequestId):
(Inspector::IdentifierRegistry::parseProtocolWebSocketRequestId):
* Source/WebCore/inspector/InspectorInstrumentation.cpp:
(WebCore::InspectorInstrumentation::didCreateWebSocketImpl):
(WebCore::InspectorInstrumentation::willSendWebSocketHandshakeRequestImpl):
(WebCore::InspectorInstrumentation::didSendWebSocketHandshakeRequestImpl):
(WebCore::InspectorInstrumentation::didReceiveWebSocketHandshakeResponseImpl):
(WebCore::InspectorInstrumentation::didCloseWebSocketImpl):
(WebCore::InspectorInstrumentation::didReceiveWebSocketFrameImpl):
(WebCore::InspectorInstrumentation::didReceiveWebSocketFrameErrorImpl):
(WebCore::InspectorInstrumentation::didSendWebSocketFrameImpl):
(WebCore::InspectorInstrumentation::instrumentingAgentsForWebSocket):
* Source/WebCore/inspector/InspectorInstrumentation.h:
* Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp:
(WebCore::InspectorNetworkAgent::didCreateWebSocket):
* Source/WebCore/inspector/agents/InspectorNetworkAgent.h:
* Source/WebCore/inspector/hooks/NetworkAgentInstrumentation.h:
* Source/WebInspectorUI/UserInterface/Controllers/NetworkManager.js:
(WI.NetworkManager):
(WI.NetworkManager.prototype.webSocketCreated):
(WI.NetworkManager.prototype.webSocketWillSendHandshakeRequest):
(WI.NetworkManager.prototype.webSocketClosed):
(WI.NetworkManager.prototype._createPlaceholderFrame):
(WI.NetworkManager.prototype._addNewResourceToFrameOrTarget):
* Source/WebInspectorUI/UserInterface/Protocol/NetworkObserver.js:
(WI.NetworkObserver.prototype.webSocketCreated):
* Source/WebKit/UIProcess/Inspector/Agents/ProxyingNetworkAgent.cpp:
(Inspector::buildObjectForWebSocketFrame):
(Inspector::ProxyingNetworkAgent::webSocketCreated):
(Inspector::ProxyingNetworkAgent::webSocketWillSendHandshakeRequest):
(Inspector::ProxyingNetworkAgent::webSocketHandshakeResponseReceived):
(Inspector::ProxyingNetworkAgent::webSocketFrameReceived):
(Inspector::ProxyingNetworkAgent::webSocketFrameSent):
(Inspector::ProxyingNetworkAgent::webSocketFrameError):
(Inspector::ProxyingNetworkAgent::webSocketClosed):
* Source/WebKit/UIProcess/Inspector/Agents/ProxyingNetworkAgent.h:
* Source/WebKit/UIProcess/Inspector/Agents/ProxyingNetworkAgent.messages.in:
* Source/WebKit/WebProcess/Inspector/FrameNetworkAgentProxy.cpp:
(WebKit::FrameNetworkAgentProxy::FrameNetworkAgentProxy):
(WebKit::currentMonotonicSeconds):
(WebKit::webSocketPayloadData):
(WebKit::FrameNetworkAgentProxy::didCreateWebSocket):
(WebKit::FrameNetworkAgentProxy::willSendWebSocketHandshakeRequest):
(WebKit::FrameNetworkAgentProxy::didSendWebSocketHandshakeRequest):
(WebKit::FrameNetworkAgentProxy::didReceiveWebSocketHandshakeResponse):
(WebKit::FrameNetworkAgentProxy::didCloseWebSocket):
(WebKit::FrameNetworkAgentProxy::didReceiveWebSocketFrame):
(WebKit::FrameNetworkAgentProxy::didSendWebSocketFrame):
(WebKit::FrameNetworkAgentProxy::didReceiveWebSocketFrameError):
* Source/WebKit/WebProcess/Inspector/FrameNetworkAgentProxy.h:
* Source/WebKit/WebProcess/Inspector/WebInspectorBackend.cpp:
(WebKit::WebInspectorBackend::ensureNetworkInstrumentationForFrame):

23b5081

Misc iOS, visionOS, tvOS & watchOS macOS Linux Windows
✅ 🧪 style ✅ 🛠 ios ✅ 🛠 mac ✅ 🛠 wpe ✅ 🛠 win
✅ 🧪 bindings ✅ 🛠 ios-sim ✅ 🛠 mac-AS-debug ✅ 🧪 wpe-wk2 ✅ 🧪 win-tests
✅ 🧪 webkitperl ✅ 🧪 ios-wk2 ✅ 🧪 api-mac ✅ 🧪 api-wpe
✅ 🧪 ios-wk2-wpt ⏳ 🧪 api-mac-debug ✅ 🧪 jsc-wpe
✅ 🧪 jsc-x86-64 ✅ 🧪 api-ios ✅ 🧪 mac-wk2 ✅ 🛠 gtk3-gcc
✅ 🛠 🧪 jsc-debug-arm64 ✅ 🛠 ios-safer-cpp ✅ 🧪 mac-AS-debug-wk2 ✅ 🛠 gtk
✅ 🛠 vision ✅ 🧪 mac-wk2-stress ✅ 🧪 gtk-wk2
✅ 🛠 vision-sim ✅ 🧪 mac-intel-wk2 ✅ 🧪 api-gtk
✅ 🧪 vision-wk2 ✅ 🛠 mac-safer-cpp ✅ 🛠 playstation
✅ 🛠 tv ✅ 🧪 mac-site-isolation
✅ 🛠 tv-sim
✅ 🛠 watch
✅ 🛠 watch-sim

BJ Burg added 2 commits October 16, 2026 21:26
…e Network domain

https://bugs.webkit.org/show_bug.cgi?id=327495

Reviewed by NOBODY (OOPS!).

Under Site Isolation the Network domain is served by ProxyingNetworkAgent in the UI process, fed by
a FrameNetworkAgentProxy per frame. The WebSocket hooks never joined that contract, so no WebSocket
showed up in Network at all, not even one opened by the main frame.

The hooks are now part of NetworkAgentInstrumentation. FrameNetworkAgentProxy forwards each one over
IPC, keyed by its process and the channel's progress identifier, and ProxyingNetworkAgent turns that
into a "websocket-<process>.<channel>" requestId. Channel identifiers come from a different counter
than resource loads, so they take their own prefix. Since the requestId names the process, the UI
process rejects a WebSocket message whose process identifier is not the sender's.

InspectorInstrumentation used to resolve WebSocket hooks through the document's page, which never
reaches a per-frame proxy. They now resolve through the document's frame. A frame's agents fall back
to its page's, so InspectorNetworkAgent still gets them outside Site Isolation.
InspectorNetworkAgent isn't enabled under Site Isolation, so each socket is reported once.

webSocketCreated gains optional frameId and loaderId. NetworkManager uses them to file the
WebSocketResource under the frame that opened it, making a placeholder frame if that frame hasn't
arrived yet. Without them it still files the socket under the main frame. The webSocket* events and
resolveWebSocket now include "web-page" in their targetTypes so the multiplexing target can deliver
them. resolveWebSocket is still unimplemented on ProxyingNetworkAgent.

Sockets that were already open when Network was enabled are not replayed to the frame proxy.

Test: http/tests/site-isolation/inspector/network/cross-origin-iframe-websocket-events.html

* LayoutTests/http/tests/site-isolation/inspector/network/cross-origin-iframe-websocket-events-expected.txt: Added.
* LayoutTests/http/tests/site-isolation/inspector/network/cross-origin-iframe-websocket-events.html: Added.
* LayoutTests/http/tests/site-isolation/inspector/network/resources/websocket-iframe.html: Added.
* LayoutTests/http/tests/site-isolation/inspector/network/resources/websocket-test-utilities.js: Added.
* Source/JavaScriptCore/inspector/protocol/Network.json:
* Source/WebCore/inspector/InspectorIdentifierRegistry.h:
(Inspector::IdentifierRegistry::protocolWebSocketRequestId):
(Inspector::IdentifierRegistry::parseProtocolWebSocketRequestId):
* Source/WebCore/inspector/InspectorInstrumentation.cpp:
(WebCore::InspectorInstrumentation::didCreateWebSocketImpl):
(WebCore::InspectorInstrumentation::willSendWebSocketHandshakeRequestImpl):
(WebCore::InspectorInstrumentation::didSendWebSocketHandshakeRequestImpl):
(WebCore::InspectorInstrumentation::didReceiveWebSocketHandshakeResponseImpl):
(WebCore::InspectorInstrumentation::didCloseWebSocketImpl):
(WebCore::InspectorInstrumentation::didReceiveWebSocketFrameImpl):
(WebCore::InspectorInstrumentation::didReceiveWebSocketFrameErrorImpl):
(WebCore::InspectorInstrumentation::didSendWebSocketFrameImpl):
(WebCore::InspectorInstrumentation::instrumentingAgentsForWebSocket):
* Source/WebCore/inspector/InspectorInstrumentation.h:
* Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp:
(WebCore::InspectorNetworkAgent::didCreateWebSocket):
* Source/WebCore/inspector/agents/InspectorNetworkAgent.h:
* Source/WebCore/inspector/hooks/NetworkAgentInstrumentation.h:
* Source/WebInspectorUI/UserInterface/Controllers/NetworkManager.js:
(WI.NetworkManager):
(WI.NetworkManager.prototype.webSocketCreated):
(WI.NetworkManager.prototype.webSocketWillSendHandshakeRequest):
(WI.NetworkManager.prototype.webSocketClosed):
(WI.NetworkManager.prototype._createPlaceholderFrame):
(WI.NetworkManager.prototype._addNewResourceToFrameOrTarget):
* Source/WebInspectorUI/UserInterface/Protocol/NetworkObserver.js:
(WI.NetworkObserver.prototype.webSocketCreated):
* Source/WebKit/UIProcess/Inspector/Agents/ProxyingNetworkAgent.cpp:
(Inspector::buildObjectForWebSocketFrame):
(Inspector::ProxyingNetworkAgent::webSocketCreated):
(Inspector::ProxyingNetworkAgent::webSocketWillSendHandshakeRequest):
(Inspector::ProxyingNetworkAgent::webSocketHandshakeResponseReceived):
(Inspector::ProxyingNetworkAgent::webSocketFrameReceived):
(Inspector::ProxyingNetworkAgent::webSocketFrameSent):
(Inspector::ProxyingNetworkAgent::webSocketFrameError):
(Inspector::ProxyingNetworkAgent::webSocketClosed):
* Source/WebKit/UIProcess/Inspector/Agents/ProxyingNetworkAgent.h:
* Source/WebKit/UIProcess/Inspector/Agents/ProxyingNetworkAgent.messages.in:
* Source/WebKit/WebProcess/Inspector/FrameNetworkAgentProxy.cpp:
(WebKit::FrameNetworkAgentProxy::FrameNetworkAgentProxy):
(WebKit::currentMonotonicSeconds):
(WebKit::webSocketPayloadData):
(WebKit::FrameNetworkAgentProxy::didCreateWebSocket):
(WebKit::FrameNetworkAgentProxy::willSendWebSocketHandshakeRequest):
(WebKit::FrameNetworkAgentProxy::didSendWebSocketHandshakeRequest):
(WebKit::FrameNetworkAgentProxy::didReceiveWebSocketHandshakeResponse):
(WebKit::FrameNetworkAgentProxy::didCloseWebSocket):
(WebKit::FrameNetworkAgentProxy::didReceiveWebSocketFrame):
(WebKit::FrameNetworkAgentProxy::didSendWebSocketFrame):
(WebKit::FrameNetworkAgentProxy::didReceiveWebSocketFrameError):
* Source/WebKit/WebProcess/Inspector/FrameNetworkAgentProxy.h:
* Source/WebKit/WebProcess/Inspector/WebInspectorBackend.cpp:
(WebKit::WebInspectorBackend::ensureNetworkInstrumentationForFrame):
…mented

https://bugs.webkit.org/show_bug.cgi?id=327496

Reviewed by NOBODY (OOPS!).

ProxyingNetworkAgent::resolveWebSocket returned "Not yet implemented", so Log WebSocket on a socket
in the Network tab did nothing under Site Isolation.

The command now routes to the process encoded in the "websocket-<process>.<channel>" requestId. That
process finds the socket among those of the page's documents by its channel's progress identifier
and wraps it with an injected script. A main-frame socket is wrapped by the page's injected script,
because the console's default execution context belongs to the page target; any other socket is
wrapped by the injected script of the frame that owns it. The reply crosses IPC as the
RemoteObject's JSON.

Injected-script object ids restart at 1 in every injected script manager, so an object id is only
meaningful on the target whose injected script made it. The frontend pairs the RemoteObject with
the page target for a main-frame socket and with the frame target that owns the socket's frame
otherwise. If it finds no such target it reports no object rather than pairing the id with another
target, where it could name a different object.

Routing needs an async reply, so resolveWebSocket becomes an async command. InspectorNetworkAgent
keeps its behavior and error strings.

Test: http/tests/site-isolation/inspector/network/cross-origin-iframe-websocket-resolve.html

* LayoutTests/http/tests/site-isolation/inspector/network/cross-origin-iframe-websocket-resolve-expected.txt: Added.
* LayoutTests/http/tests/site-isolation/inspector/network/cross-origin-iframe-websocket-resolve.html: Added.
* LayoutTests/http/tests/site-isolation/inspector/network/resources/websocket-iframe.html:
* LayoutTests/http/tests/site-isolation/inspector/network/resources/websocket-test-utilities.js:
* Source/JavaScriptCore/inspector/protocol/Network.json:
* Source/WebCore/inspector/InspectorResourceUtilities.h:
* Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp:
(WebCore::InspectorNetworkAgent::resolveWebSocket):
(Inspector::ResourceUtilities::resolveWebSocketInFrame):
* Source/WebCore/inspector/agents/InspectorNetworkAgent.h:
* Source/WebInspectorUI/UserInterface/Protocol/RemoteObject.js:
(WI.RemoteObject.resolveWebSocket):
* Source/WebKit/UIProcess/Inspector/Agents/ProxyingNetworkAgent.cpp:
(Inspector::ProxyingNetworkAgent::resolveWebSocket):
* Source/WebKit/UIProcess/Inspector/Agents/ProxyingNetworkAgent.h:
* Source/WebKit/WebProcess/Inspector/WebInspectorBackend.cpp:
(WebKit::WebInspectorBackend::resolveWebSocket):
* Source/WebKit/WebProcess/Inspector/WebInspectorBackend.h:
* Source/WebKit/WebProcess/Inspector/WebInspectorBackend.messages.in:
@burg burg self-assigned this Oct 17, 2026
@burg burg added the Web Inspector Bugs related to the WebKit Web Inspector. label Oct 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Web Inspector Bugs related to the WebKit Web Inspector.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants