Introduce short form object state, and connect the ends to send data to web app

This commit is contained in:
Aldo Cortesi 2014-09-17 13:58:56 +12:00
parent 51db9a5612
commit b4ecd96beb
8 changed files with 67 additions and 21 deletions

View File

@ -106,6 +106,7 @@ class HTTPMessage(stateobject.StateObject):
timestamp_start=float,
timestamp_end=float
)
_stateobject_long_attributes = set(["content"])
def get_decoded_content(self):
"""

View File

@ -78,8 +78,8 @@ class Flow(stateobject.StateObject):
conntype=str
)
def get_state(self):
d = super(Flow, self).get_state()
def get_state(self, short=False):
d = super(Flow, self).get_state(short)
d.update(version=version.IVERSION)
return d

View File

@ -36,8 +36,8 @@ class ClientConnection(tcp.BaseHandler, stateobject.StateObject):
timestamp_ssl_setup=float
)
def get_state(self):
d = super(ClientConnection, self).get_state()
def get_state(self, short=False):
d = super(ClientConnection, self).get_state(short)
d.update(
address={"address": self.address(), "use_ipv6": self.address.use_ipv6},
clientcert=self.cert.to_pem() if self.clientcert else None
@ -107,8 +107,8 @@ class ServerConnection(tcp.TCPClient, stateobject.StateObject):
sni=str
)
def get_state(self):
d = super(ServerConnection, self).get_state()
def get_state(self, short=False):
d = super(ServerConnection, self).get_state(short)
d.update(
address={"address": self.address(),
"use_ipv6": self.address.use_ipv6},

View File

@ -9,27 +9,35 @@ class StateObject(object):
or StateObject instances themselves.
"""
# An attribute-name -> class-or-type dict containing all attributes that
# should be serialized. If the attribute is a class, it must be a subclass
# of StateObject.
# should be serialized. If the attribute is a class, it must implement the
# StateObject protocol.
_stateobject_attributes = None
def _get_state_attr(self, attr, cls):
val = getattr(self, attr)
if hasattr(val, "get_state"):
return val.get_state()
else:
return val
# A set() of attributes that should be ignored for short state
_stateobject_long_attributes = frozenset([])
def from_state(self):
raise NotImplementedError
def get_state(self):
def get_state(self, short=False):
"""
Retrieve object state. If short is true, return an abbreviated
format with long data elided.
"""
state = {}
for attr, cls in self._stateobject_attributes.iteritems():
state[attr] = self._get_state_attr(attr, cls)
if short and attr in self._stateobject_long_attributes:
continue
val = getattr(self, attr)
if hasattr(val, "get_state"):
state[attr] = val.get_state(short)
else:
state[attr] = val
return state
def load_state(self, state):
"""
Load object state from data returned by a get_state call.
"""
for attr, cls in self._stateobject_attributes.iteritems():
if state.get(attr, None) is None:
setattr(self, attr, None)

View File

@ -81,18 +81,31 @@ class WebMaster(flow.FlowMaster):
self.shutdown()
def handle_request(self, f):
pprint.pprint(f.get_state())
app.ClientConnection.broadcast("flow", f.get_state(True))
flow.FlowMaster.handle_request(self, f)
if f:
f.reply()
return f
def handle_response(self, f):
app.ClientConnection.broadcast("flow", f.get_state(True))
flow.FlowMaster.handle_response(self, f)
if f:
f.reply()
return f
def handle_error(self, f):
app.ClientConnection.broadcast("flow", f.get_state(True))
flow.FlowMaster.handle_error(self, f)
return f
def handle_log(self, l):
app.ClientConnection.broadcast(
"event", {
"message": l.msg,
"level": l.level
}
)
self.add_event(l.msg, l.level)
l.reply()

View File

@ -2,6 +2,7 @@ import os.path
import tornado.web
import tornado.websocket
import logging
import json
class IndexHandler(tornado.web.RequestHandler):
@ -22,7 +23,14 @@ class ClientConnection(tornado.websocket.WebSocketHandler):
def broadcast(cls, type, data):
for conn in cls.connections:
try:
conn.write_message(type, data)
conn.write_message(
json.dumps(
{
"type": type,
"data": data
}
)
)
except:
logging.error("Error sending message", exc_info=True)

View File

@ -221,7 +221,15 @@ _Connection.prototype.onopen = function (open) {
};
_Connection.prototype.onmessage = function (message) {
//AppDispatcher.dispatchServerAction(...);
console.log("onmessage", this, arguments);
var m = JSON.parse(message.data);
switch (m.type){
case "flow":
console.log("flow", m.data);
break;
case "event":
console.log("event", m.data.message)
break;
}
};
_Connection.prototype.onerror = function (error) {
console.log("onerror", this, arguments);

View File

@ -18,7 +18,15 @@ _Connection.prototype.onopen = function (open) {
};
_Connection.prototype.onmessage = function (message) {
//AppDispatcher.dispatchServerAction(...);
console.log("onmessage", this, arguments);
var m = JSON.parse(message.data);
switch (m.type){
case "flow":
console.log("flow", m.data);
break;
case "event":
console.log("event", m.data.message)
break;
}
};
_Connection.prototype.onerror = function (error) {
console.log("onerror", this, arguments);