Correlation between WS HTTP upgrade request (101) and WS connection

NEW
Assigned to

Status

()

Core
Networking: WebSockets
P3
normal
2 years ago
7 months ago

People

(Reporter: Honza, Assigned: michal)

Tracking

Firefox Tracking Flags

(Not tracked)

Details

(Whiteboard: [necko-backlog])

(Reporter)

Description

2 years ago
Our tooling should be able to see correlation between HTTP upgrade request (101 - Web Socket Protocol Handshake) and WS connection (both ways).

HTTP request -> WS connection (ID?)
WS connection -> HTTP request (copy of the original nsIHttpRequest?)

This should help us to implement the following in the UI:

1) Navigate from the Network panel to the WebSocket panel by e.g. right clicking on existing HTTP upgrade request (in the Net panel) and picking something like: "Show related WS Frames". The WS panel can be consequently selected and filtered to show only related frames.

2) Go from the WS panel to the Network panel (similar UX as in #1).For this we also need full info related to the HTTP request. If the nsIHttpRequest object is not directly accessible, we somehow need to get the data (request ID, request/response headers, the response body in case the body can be non-empty, etc.).

3) Eventually we need access to the WebSocket JS object on the page, but I am not sure if this is in the scope of this bug.

Honza
(Reporter)

Updated

2 years ago
Summary: Connection between WS HTTP upgrade request (101) and WS connection → Correlation between WS HTTP upgrade request (101) and WS connection
Assignee: nobody → amarchesini
Question: in devtools, in the network panel, do you have access to the nsIHttpChannel objects?
If not, how do you get data of the http connections?
Flags: needinfo?(odvarko)
(Reporter)

Comment 2

2 years ago
(In reply to Andrea Marchesini (:baku) from comment #1)
> Question: in devtools, in the network panel, do you have access to the
> nsIHttpChannel objects?
No

> If not, how do you get data of the http connections?
They are sent from the backend (the server side) over RDP from WebConsoleActor.

The WebConsoleActor utilises an object - NetworkMonitor, running in the right process, so it has access to the nsIHttpRequest. This object uses the nsIHttpActivityDistributor to monitor network requests.  The nsIObserverService is also used for monitoring http-on-examine-response notifications. All network request information is consequently routed (through RDP) to the remote Web Console - i.e. the Console and Network monitor panels - on the client side.

We need to use similar concept. We already have an actor, that is registering WS listener on the backend and routing all WS messages to the client side (to the WS panel) over RDP.

So, we have all on the client side (network requests as well as WS messages), there is just no way how to figure out what HTTP request belong to specific connection ID...


Honza
Flags: needinfo?(odvarko)
nsIHttpActivityDistributor::observeActivity receives a channel, and this can be a nsIHttpChannel.
What about if we implement:

// do_queryInterface(...);
serialId = nsIHttpChannel::getTheOwningWebSocketSerial(); // please, a better name here.

And in case this is not an nsIHttpChannel or it doesn't not owned by a WebSocket we throw an exception, or we return 0.
Flags: needinfo?(odvarko)
(Reporter)

Comment 4

2 years ago
Yes, this sounds ok for me.

> nsIHttpChannel::getTheOwningWebSocketSerial();
What about getWebSocketOwnerID(), or it could be a property, having the same name as used in WS API: webSocketSerialID

But, HTTP upgrade request (101) doesn't always have to end up with WebSockets protocol. So, perhaps the name should be more generic covering up also other possible protocols. In such case it could be something like: getOwnerProtocolID();


Honza
Flags: needinfo?(odvarko)
What about this:

interface nsIHttpChannelOwnerProtocolData {
  const unsigned short WEBSOCKET = 1;
  readonly attribute unsigned short type;
}

interface nsIHttpChannelOwnerProtocolDataWebSocket : nsIHttpChannelOwnerProtocolData {
  readonly attribute unsigned long serialID;
}

and in nsIHttpChannel:

readonly attribute nsIHttpChannelOwnerProtocolData ownerProtocolData;

We can do it if we have more then 1 protocol. but for now, I'll go for getWebSocketOwnerID() and in case necko folks want something more complex, we can do it.
(Reporter)

Comment 6

2 years ago
(In reply to Andrea Marchesini (:baku) from comment #5)
> We can do it if we have more then 1 protocol. but for now, I'll go for
> getWebSocketOwnerID() and in case necko folks want something more complex,
> we can do it.
Sounds good to me.

Honza
jduell, feedback about what we are proposing here?
Flags: needinfo?(jduell.mcbugs)
I think the basic idea in comment 5 is fine.  I'd name them something like nsIHttpUpgradeData and nsIWebsocketUpgradeData, and the field in nsIHttpChannel could be channel.upgradeData.

But I think Patrick should have bikeshed rights here :)  Plus he may have other ideas of how we might use Upgrade that might affect the API here (do you think the new field belongs in nsIHttpChannel, or nsIHttpChannelInternal?)
Flags: needinfo?(jduell.mcbugs) → needinfo?(mcmanus)
Flags: needinfo?(mcmanus)
Whiteboard: [necko-active]
Are you OK with comment 8? Who is going to implement this?
Flags: needinfo?(mcmanus)
(Assignee)

Updated

2 years ago
Assignee: amarchesini → michal.novotny
The names are fine
Flags: needinfo?(mcmanus)
Honza, can you help me to prioritize this feature? It seems quite low. Is it?
Flags: needinfo?(odvarko)
(Reporter)

Comment 12

2 years ago
Correct, this is not high on our priority list at the moment.

Honza
Flags: needinfo?(odvarko)
Whiteboard: [necko-active] → [necko-backlog]
You need to log in before you can comment on or make changes to this bug.