Open Bug 1659903 Opened 4 years ago Updated 4 years ago

Web sockets frames not getting parsed to JSON. Only Raw Data option is available

Categories

(DevTools :: Netmonitor, defect, P3)

80 Branch
defect

Tracking

(Not tracked)

People

(Reporter: dev.rohit.chaubey, Assigned: bomsy)

References

(Blocks 1 open bug)

Details

Attachments

(1 file)

Attached image vgwdrprn3sh51.png (deleted) —

User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:80.0) Gecko/20100101 Firefox/80.0

Steps to reproduce:

I opened Network tab in console to inspect Web Sockets frames by clicking on WS tab.

Actual results:

Web socket frames can only be viewed in Raw Data format. JSON format is now available.

Expected results:

There should have been JSON format option to inspect Web Sockets frame

Bugbug thinks this bug should belong to this component, but please revert this change in case of error.

Component: Untriaged → Netmonitor
Product: Firefox → DevTools

Thanks for reporting!

Adding STR

  1. Go to https://www.websocket.org/echo.html
  2. Open the Network panel
  3. Click "connect" to connect to the default location "wss://echo.websocket.org"
  4. Select the request in the network panel to open the details panel
  5. Go to the Response side panel
  6. On the webpage Replace the content of the Message textbox with json e.g { a: "3", b: "4", c: "6" }
  7. Click send
  8. Select the message
Severity: -- → S3
Priority: -- → P3

(In reply to Hubert Boma Manilla (:bomsy) from comment #2)

  1. On the webpage Replace the content of the Message textbox with json e.g { a: "3", b: "4", c: "6" }

:bomsy your payload is not valid JSON, you need quotes round the keys which is why it is not parsing correctly.
This works fine: { "a": "3", "b": "4", "c": "6" }

(In reply to Sand Man from comment #0)

I opened Network tab in console to inspect Web Sockets frames by clicking on WS tab.

Do you have an example of the payload I can see/use please?

I'm also facing a similar issue:

  1. Go to https://www.websocket.org/echo.html
  2. Send {"a":5}
  3. The receive message in the Response tab parses correctly as JSON and Raw Data. All good.
  4. Now send {"data":5}.
  5. This message does not parse correctly. In fact clicking this message does not update the Raw Data or JSON sections at all. For some reason the presence of a "data" property bugs it.

(In reply to decademoon.bugzilla from comment #4)

  1. Now send {"data":5}.
  2. This message does not parse correctly. In fact clicking this message does not update the Raw Data or JSON sections at all. For some reason the presence of a "data" property bugs it.

By having a "data" (or "identifier") property the parseActionCable parser gets triggered. It attempts a JSON parse "data" on the data value. If that value isn't a string (doesnt have a match method) then it breaks/throws an error and the parsing completely fails.

{ "data": "[]"}  // Parses
{ "data": [] }   // Breaks

parseJSON could check payloadUnclean is a string before continuing. Or have a try/catch around the match.
parseActionCable could benefit from an extra try/catch but that wouldn't be needed if parseJSON didn't error.

Looking at the payloads in @Sand Man's image I don't think this is the same bug but it's definitely a bug.

Flags: needinfo?(odvarko)

@Ben, thanks for the analysis!

@bomsy: could you please look at this? Some notes:

  • The following patch fixes the problem for me (based on Ben's analysis)
diff --git a/devtools/client/netmonitor/src/components/messages/MessagePayload.js b/devtools/client/netmonitor/src/components/messages/MessagePayload.js
--- a/devtools/client/netmonitor/src/components/messages/MessagePayload.js
+++ b/devtools/client/netmonitor/src/components/messages/MessagePayload.js
@@ -281,18 +281,18 @@ class MessagePayload extends Component {
         return json;
       }
     }

     return null;
   }

   parseActionCable(payload) {
-    const identifier = payload.identifier && parseJSON(payload.identifier).json;
-    const data = payload.data && parseJSON(payload.data).json;
+    const identifier = payload.identifier && parseJSON(payload.identifier)?.json;
+    const data = payload.data && parseJSON(payload.data)?.json;
     if (!data && !identifier) {
       return null;
     }
     if (identifier) {
       payload.identifier = identifier;
     }
     if (data) {
       payload.data = data;
diff --git a/devtools/client/netmonitor/src/utils/request-utils.js b/devtools/client/netmonitor/src/utils/request-utils.js
--- a/devtools/client/netmonitor/src/utils/request-utils.js
+++ b/devtools/client/netmonitor/src/utils/request-utils.js
@@ -632,16 +632,20 @@ function isBase64(payload) {

 /**
  * Checks if the payload is of JSON type.
  * This function also handles JSON with XSSI-escaping characters by skipping them.
  * This function also handles Base64 encoded JSON.
  */
 function parseJSON(payloadUnclean) {
   let json, error;
+  if (typeof payloadUnclean !== "string") {
+    return {};
+  }
+
   const jsonpRegex = /^\s*([\w$]+)\s*\(\s*([^]*)\s*\)\s*;?\s*$/;
   const [, jsonpCallback, jsonp] = payloadUnclean.match(jsonpRegex) || [];
   if (jsonpCallback && jsonp) {
     try {
       json = parseJSON(jsonp).json;
     } catch (err) {
       error = err;
     }
  • We also need a test. I think we can clone browser_net_ws-json-stomp-payload.js and use content.wrappedJSObject.sendData( to send the following JSON:

{ "data": [] , "identifier": []}

The test checks the tree using:

  ok(
    document.querySelector("#message-formattedData .treeTable"),
    "A tree table should be used to display the formatted payload"
  );

So, we can keep that condition and remove all the others.

Honza

Status: UNCONFIRMED → NEW
Has STR: --- → yes
Ever confirmed: true
Flags: needinfo?(odvarko) → needinfo?(hmanilla)
Assignee: nobody → hmanilla
Flags: needinfo?(hmanilla)
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: