diff options
author | Maximilian Hils <git@maximilianhils.com> | 2014-12-09 18:55:16 +0100 |
---|---|---|
committer | Maximilian Hils <git@maximilianhils.com> | 2014-12-09 18:55:16 +0100 |
commit | 05bc7e8cd8382aabdd44f7bc569d2fd421c26f21 (patch) | |
tree | 754fc4ad2c21c833fdf06949a30a412161353ccb /libmproxy/web | |
parent | 14a8d2f5b83a1ea28abbb490f6c94c43b4e1f960 (diff) | |
download | mitmproxy-05bc7e8cd8382aabdd44f7bc569d2fd421c26f21.tar.gz mitmproxy-05bc7e8cd8382aabdd44f7bc569d2fd421c26f21.tar.bz2 mitmproxy-05bc7e8cd8382aabdd44f7bc569d2fd421c26f21.zip |
generalize store
Diffstat (limited to 'libmproxy/web')
-rw-r--r-- | libmproxy/web/__init__.py | 26 | ||||
-rw-r--r-- | libmproxy/web/app.py | 9 | ||||
-rw-r--r-- | libmproxy/web/static/js/app.js | 241 |
3 files changed, 145 insertions, 131 deletions
diff --git a/libmproxy/web/__init__.py b/libmproxy/web/__init__.py index 50c4b843..8f9fffdd 100644 --- a/libmproxy/web/__init__.py +++ b/libmproxy/web/__init__.py @@ -15,19 +15,34 @@ class WebFlowView(flow.FlowView): def _add(self, f): super(WebFlowView, self)._add(f) - app.ClientConnection.broadcast("add_flow", f.get_state(short=True)) + app.ClientConnection.broadcast( + type="flows", + cmd="add", + data=f.get_state(short=True) + ) def _update(self, f): super(WebFlowView, self)._update(f) - app.ClientConnection.broadcast("update_flow", f.get_state(short=True)) + app.ClientConnection.broadcast( + type="flows", + cmd="update", + data=f.get_state(short=True) + ) def _remove(self, f): super(WebFlowView, self)._remove(f) - app.ClientConnection.broadcast("remove_flow", f.get_state(short=True)) + app.ClientConnection.broadcast( + type="flows", + cmd="remove", + data=f.get_state(short=True) + ) def _recalculate(self, flows): super(WebFlowView, self)._recalculate(flows) - app.ClientConnection.broadcast("reset_flows", None) + app.ClientConnection.broadcast( + type="flows", + cmd="reset" + ) class WebState(flow.State): @@ -120,7 +135,8 @@ class WebMaster(flow.FlowMaster): def handle_log(self, l): self.last_log_id += 1 app.ClientConnection.broadcast( - "add_event", { + type="add_event", + data={ "id": self.last_log_id, "message": l.msg, "level": l.level diff --git a/libmproxy/web/app.py b/libmproxy/web/app.py index 3fce9d64..d5638c10 100644 --- a/libmproxy/web/app.py +++ b/libmproxy/web/app.py @@ -23,13 +23,8 @@ class WebSocketEventBroadcaster(tornado.websocket.WebSocketHandler): self.connections.remove(self) @classmethod - def broadcast(cls, type, data): - message = json.dumps( - { - "type": type, - "data": data - } - ) + def broadcast(cls, **kwargs): + message = json.dumps(kwargs) for conn in cls.connections: try: conn.write_message(message) diff --git a/libmproxy/web/static/js/app.js b/libmproxy/web/static/js/app.js index 16c7ffba..6596b121 100644 --- a/libmproxy/web/static/js/app.js +++ b/libmproxy/web/static/js/app.js @@ -102,10 +102,10 @@ AppDispatcher.dispatchServerAction = function (action) { }; var ActionTypes = { - // Channel - CHANNEL_OPEN: "channel_open", - CHANNEL_CLOSE: "channel_close", - CHANNEL_ERROR: "channel_error", + // Connection + CONNECTION_OPEN: "connection_open", + CONNECTION_CLOSE: "connection_close", + CONNECTION_ERROR: "connection_error", // Settings UPDATE_SETTINGS: "update_settings", @@ -123,17 +123,17 @@ var ActionTypes = { var ConnectionActions = { open: function () { AppDispatcher.dispatchViewAction({ - type: ActionTypes.CHANNEL_OPEN + type: ActionTypes.CONNECTION_OPEN }); }, close: function () { AppDispatcher.dispatchViewAction({ - type: ActionTypes.CHANNEL_CLOSE + type: ActionTypes.CONNECTION_CLOSE }); }, error: function () { AppDispatcher.dispatchViewAction({ - type: ActionTypes.CHANNEL_ERROR + type: ActionTypes.CONNECTION_ERROR }); } }; @@ -241,6 +241,117 @@ EventEmitter.prototype.removeListener = function (events, f) { }.bind(this)); }; + +function Store() { + this._views = []; + this.reset(); +} +_.extend(Store.prototype, { + add: function (elem) { + if (elem.id in this._pos_map) { + return; + } + + this._pos_map[elem.id] = this._list.length; + this._list.push(elem); + for (var i = 0; i < this._views.length; i++) { + this._views[i].add(elem); + } + }, + update: function (elem) { + if (!(elem.id in this._pos_map)) { + return; + } + + this._list[this._pos_map[elem.id]] = elem; + for (var i = 0; i < this._views.length; i++) { + this._views[i].update(elem); + } + }, + remove: function (elem_id) { + if (!(elem.id in this._pos_map)) { + return; + } + + this._list.splice(this._pos_map[elem_id], 1); + this._build_map(); + for (var i = 0; i < this._views.length; i++) { + this._views[i].remove(elem_id); + } + }, + reset: function (elems) { + this._list = elems || []; + this._build_map(); + for (var i = 0; i < this._views.length; i++) { + this._views[i].recalculate(this._list); + } + }, + _build_map: function () { + this._pos_map = {}; + for (var i = 0; i < this._list.length; i++) { + var elem = this._list[i]; + this._pos_map[elem.id] = i; + } + }, + get: function (elem_id) { + return this._list[this._pos_map[elem_id]]; + } +}); + + +function LiveStore(type) { + Store.call(this); + this.type = type; + + this._updates_before_fetch = undefined; + this._fetchxhr = false; + + this.handle = this.handle.bind(this); + AppDispatcher.register(this.handle); + + // Avoid double-fetch on startup. + if (!(window.ws && window.ws.readyState === WebSocket.CONNECTING)) { + this.fetch(); + } +} +_.extend(LiveStore.prototype, Store.prototype, { + handle: function (event) { + if (event.type === ActionTypes.CONNECTION_OPEN) { + return this.fetch(); + } + if (event.type === this.type) { + if (event.cmd === "reset") { + this.fetch(); + } else if (this._updates_before_fetch) { + console.log("defer update", event); + this._updates_before_fetch.push(event); + } else { + this[event.cmd](event.data); + } + } + }, + close: function () { + AppDispatcher.unregister(this.handle); + }, + fetch: function () { + console.log("fetch " + this.type); + if (this._fetchxhr) { + this._fetchxhr.abort(); + } + this._fetchxhr = $.getJSON("/" + this.type, this.handle_fetch.bind(this)); + this._updates_before_fetch = []; // (JS: empty array is true) + }, + handle_fetch: function (data) { + this._fetchxhr = false; + console.log(this.type + " fetched.", this._updates_before_fetch); + this.reset(data.flows); + var updates = this._updates_before_fetch; + this._updates_before_fetch = false; + for (var i = 0; i < updates.length; i++) { + this.handle(updates[i]); + } + }, +}); function _SettingsStore() { EventEmitter.call(this); @@ -369,117 +480,9 @@ _.extend(_EventLogStore.prototype, EventEmitter.prototype, { var EventLogStore = new _EventLogStore(); AppDispatcher.register(EventLogStore.handle.bind(EventLogStore)); -function FlowStore() { - this._views = []; - this.reset(); -} -_.extend(FlowStore.prototype, { - add: function (flow) { - this._pos_map[flow.id] = this._flow_list.length; - this._flow_list.push(flow); - for (var i = 0; i < this._views.length; i++) { - this._views[i].add(flow); - } - }, - update: function (flow) { - this._flow_list[this._pos_map[flow.id]] = flow; - for (var i = 0; i < this._views.length; i++) { - this._views[i].update(flow); - } - }, - remove: function (flow_id) { - this._flow_list.splice(this._pos_map[flow_id], 1); - this._build_map(); - for (var i = 0; i < this._views.length; i++) { - this._views[i].remove(flow_id); - } - }, - reset: function (flows) { - this._flow_list = flows || []; - this._build_map(); - for (var i = 0; i < this._views.length; i++) { - this._views[i].recalculate(this._flow_list); - } - }, - _build_map: function () { - this._pos_map = {}; - for (var i = 0; i < this._flow_list.length; i++) { - var flow = this._flow_list[i]; - this._pos_map[flow.id] = i; - } - }, - get: function (flow_id) { - return this._flow_list[this._pos_map[flow_id]]; - } -}); - - function LiveFlowStore() { - FlowStore.call(this); - this.updates_before_fetch = undefined; - this._fetchxhr = false; - - this.handle = this.handle.bind(this); - AppDispatcher.register(this.handle); - - // Avoid double-fetch on startup. - if(!(window.ws && window.ws.readyState === WebSocket.CONNECTING)) { - this.fetch(); - } + return new LiveStore("flows"); } -_.extend(LiveFlowStore.prototype, FlowStore.prototype, { - handle: function (event) { - switch (event.type) { - case ActionTypes.CHANNEL_OPEN: - case ActionTypes.RESET_FLOWS: - this.fetch(); - break; - case ActionTypes.ADD_FLOW: - case ActionTypes.UPDATE_FLOW: - case ActionTypes.REMOVE_FLOW: - if (this.updates_before_fetch) { - console.log("defer update", type, data); - this.updates_before_fetch.push(event); - } else { - if(event.type === ActionTypes.ADD_FLOW){ - this.add(event.data); - } else if (event.type === ActionTypes.UPDATE_FLOW){ - this.update(event.data); - } else { - this.remove(event.data); - } - } - break; - } - }, - close: function () { - AppDispatcher.unregister(this.handle); - }, - add: function (flow) { - // Make sure that deferred adds don't add an element twice. - if (!(flow.id in this._pos_map)) { - FlowStore.prototype.add.call(this, flow); - } - }, - fetch: function () { - console.log("fetch"); - if (this._fetchxhr) { - this._fetchxhr.abort(); - } - this._fetchxhr = $.getJSON("/flows", this.handle_fetch.bind(this)); - this.updates_before_fetch = []; // (JS: empty array is true) - }, - handle_fetch: function (data) { - this._fetchxhr = false; - console.log("Flows fetched.", this.updates_before_fetch); - this.reset(data.flows); - var updates = this.updates_before_fetch; - this.updates_before_fetch = false; - for (var i = 0; i < updates.length; i++) { - this.handle(updates[i]); - } - }, -}); function SortByInsertionOrder() { this.i = 0; @@ -505,7 +508,7 @@ function FlowView(store, filt, sortfun) { this.store = store; this.store._views.push(this); - this.recalculate(this.store._flow_list, filt, sortfun); + this.recalculate(this.store._list, filt, sortfun); } _.extend(FlowView.prototype, EventEmitter.prototype, { @@ -582,7 +585,7 @@ _.extend(FlowView.prototype, EventEmitter.prototype, { } } }); -function Channel(url) { +function Connection(url) { if (url[0] === "/") { url = location.origin.replace("http", "ws") + url; @@ -1859,7 +1862,7 @@ var routes = ( ) ); $(function () { - window.ws = new Channel("/updates"); + window.ws = new Connection("/updates"); ReactRouter.run(routes, function (Handler) { React.render(React.createElement(Handler, null), document.body); |