From 7283054cd50336c2bde0807c376feae3106478c0 Mon Sep 17 00:00:00 2001 From: Espen Henriksen Date: Mon, 11 Jul 2016 22:25:31 +0200 Subject: [PATCH] Add query string frame parsing --- .../locale/en-US/websocket-monitor.properties | 4 ++ data/components/frame-list.js | 7 ++++ data/components/frame-table.js | 6 +++ data/components/query-string-tab.js | 39 +++++++++++++++++++ data/components/sidebar.js | 9 +++++ data/view.js | 1 + lib/wsm-panel.js | 31 +++++++++++++++ package.json | 7 ++++ 8 files changed, 104 insertions(+) create mode 100644 data/components/query-string-tab.js diff --git a/chrome/locale/en-US/websocket-monitor.properties b/chrome/locale/en-US/websocket-monitor.properties index fadcbd9..7d1bc1f 100644 --- a/chrome/locale/en-US/websocket-monitor.properties +++ b/chrome/locale/en-US/websocket-monitor.properties @@ -47,6 +47,10 @@ websocketmonitor.WAMP=WAMP # panel that displays MQTT messages. websocketmonitor.MQTT=MQTT +# LOCALIZATION NOTE (websocketmonitor.QueryString): A label used as a title for +# side panel that displays messages formatted as a Query String (foo?bar=baz). +websocketmonitor.QueryString=Query String + # LOCALIZATION NOTE (websocketmonitor.option.tabularView): A label and tooltip # used for a toolbar button that allows switching the frame list to # Tabular view diff --git a/data/components/frame-list.js b/data/components/frame-list.js index d0df411..ad65c2d 100644 --- a/data/components/frame-list.js +++ b/data/components/frame-list.js @@ -211,6 +211,13 @@ define(function (require, exports) { data: {"MQTT": mqtt}, mode: "tiny" }); + } else if (this.props.config.enableQueryString !== false + && frame.queryString) { + preview = TreeView({ + key: "preview-query", + data: {"Query String": frame.queryString}, + mode: "tiny" + }); } const label = (type == "send") ? diff --git a/data/components/frame-table.js b/data/components/frame-table.js index 05b92e7..b9569d9 100644 --- a/data/components/frame-table.js +++ b/data/components/frame-table.js @@ -208,6 +208,12 @@ define(function (require, exports) { key: "preview-mqtt", data: {"MQTT": frame.mqtt}, }); + } else if (this.props.config.enableQueryString !== false + && frame.queryString) { + payload = TreeView({ + key: "preview-query", + data: {"Query String": frame.queryString}, + }); } else { // Fall back to showing a string payload = Str.cropString(frame.data.payload, 50); diff --git a/data/components/query-string-tab.js b/data/components/query-string-tab.js new file mode 100644 index 0000000..79ef14e --- /dev/null +++ b/data/components/query-string-tab.js @@ -0,0 +1,39 @@ +/* See license.txt for terms of usage */ + +"use strict"; + +define(function (require, exports) { + // Dependencies + const React = require("react"); + + // Firebug SDK + const { Reps } = require("reps/repository"); + const { TreeView } = require("reps/tree-view"); + + // Shortcuts + const { DIV } = Reps.DOM; + + /** + * Component responsible for rendering the Query String tab. + */ + let QueryStringTab = React.createClass({ + /** @lends QueryStringTab */ + + displayName: "QueryStringTab", + + render: function () { + let selectedFrame = this.props.selection || {}; + let data = selectedFrame.queryString; + + return ( + DIV({className: "details"}, + TreeView({key: "QueryStringTabTree", data: data}) + ) + ); + } + }); + + // Exports from this module + exports.QueryStringTab = QueryStringTab; +}); + diff --git a/data/components/sidebar.js b/data/components/sidebar.js index 00e1dc0..4ac0102 100644 --- a/data/components/sidebar.js +++ b/data/components/sidebar.js @@ -18,6 +18,7 @@ define(function (require, exports) { const { JSONTab } = createFactories(require("./json-tab")); const { WampTab } = createFactories(require("./wamp-tab")); const { MQTTTab } = createFactories(require("./mqtt-tab")); + const { QueryStringTab } = createFactories(require("./query-string-tab")); /** * @template This template represents a list of packets displayed @@ -93,6 +94,14 @@ define(function (require, exports) { )); } + if (selectedFrame && selectedFrame.queryString) { + tabs.push( + TabPanel({className: "mqtt", key: "queryString", + title: Locale.$STR("websocketmonitor.QueryString")}, + QueryStringTab(this.props) + )); + } + tabActive = Math.min(tabActive, tabs.length); return ( diff --git a/data/view.js b/data/view.js index f7e10ad..5564fac 100644 --- a/data/view.js +++ b/data/view.js @@ -61,6 +61,7 @@ define(function (require) { enableSockJs: Options.get("enableSockJs"), enableJson: Options.get("enableJson"), enableMqtt: Options.get("enableMqtt"), + enableQueryString: Options.get("enableQueryString"), } }); diff --git a/lib/wsm-panel.js b/lib/wsm-panel.js index 0907e0a..f302fb8 100644 --- a/lib/wsm-panel.js +++ b/lib/wsm-panel.js @@ -223,6 +223,7 @@ const WsmPanel = Class( data.wamp = this.decodeWampPacket(payload); data.json = this.decodeJsonPacket(payload); data.mqtt = this.decodeMqttPacket(payload); + data.queryString = this.decodeQueryString(payload); }, // Socket.IO Parser @@ -335,6 +336,36 @@ const WsmPanel = Class( } }, + /** + * Parse query strings + */ + decodeQueryString: function(data) { + if (!prefs.enableQueryString) { + return; + } + + // Check if the data matches foo?bar + if (!/\w+\?.+/.test(data)) { + return; + } + + const result = {}; + + var vars = data.substr(data.indexOf('?') + 1).split('&'); + vars.forEach(function(item) { + var pair = item.split('='); + + // ?foo&bar&baz is valid + if (pair.length === 2) { + result[pair[0]] = decodeURIComponent(pair[1]); + } else { + result[pair[0]] = undefined; + } + }); + + return result; + }, + // NetMonitor Overlay /** diff --git a/package.json b/package.json index 5c32faf..114afd0 100644 --- a/package.json +++ b/package.json @@ -82,6 +82,13 @@ "description": "Parse MQTT frames", "type": "bool", "value": true + }, + { + "name": "enableQueryString", + "title": "Query string support", + "description": "Parse query string frames (frames that look like foo&bar=baz)", + "type": "bool", + "value": true } ] }