Restructure to make subclassing Flow unnecessary.
This commit is contained in:
parent
1619d164ff
commit
152b97fa0b
|
@ -44,6 +44,55 @@ def format_keyvals(lst, key="key", val="text", space=5, indent=0):
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
def format_flow(flow, focus, padding=3):
|
||||||
|
if not flow.request and not flow.response:
|
||||||
|
txt = [
|
||||||
|
("title", " Connection from %s..."%(flow.connection.address)),
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
txt = [
|
||||||
|
("ack", "!") if flow.intercepting and not flow.request.acked else " ",
|
||||||
|
("method", flow.request.method),
|
||||||
|
" ",
|
||||||
|
(
|
||||||
|
"text" if (flow.response or flow.error) else "title",
|
||||||
|
flow.request.url(),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
if flow.response or flow.error or flow.is_replay():
|
||||||
|
txt.append("\n" + " "*(padding+2))
|
||||||
|
if flow.is_replay():
|
||||||
|
txt.append(("method", "[replay] "))
|
||||||
|
if not (flow.response or flow.error):
|
||||||
|
txt.append(("text", "waiting for response..."))
|
||||||
|
|
||||||
|
if flow.response:
|
||||||
|
txt.append(
|
||||||
|
("ack", "!") if flow.intercepting and not flow.response.acked else " "
|
||||||
|
)
|
||||||
|
txt.append("<- ")
|
||||||
|
if flow.response.code in [200, 304]:
|
||||||
|
txt.append(("goodcode", str(flow.response.code)))
|
||||||
|
else:
|
||||||
|
txt.append(("error", str(flow.response.code)))
|
||||||
|
t = flow.response.headers.get("content-type")
|
||||||
|
if t:
|
||||||
|
t = t[0].split(";")[0]
|
||||||
|
txt.append(("text", " %s"%t))
|
||||||
|
if flow.response.content:
|
||||||
|
txt.append(", %s"%utils.pretty_size(len(flow.response.content)))
|
||||||
|
elif flow.error:
|
||||||
|
txt.append(
|
||||||
|
("error", flow.error.msg)
|
||||||
|
)
|
||||||
|
if focus:
|
||||||
|
txt.insert(0, ("focus", ">>" + " "*(padding-2)))
|
||||||
|
else:
|
||||||
|
txt.insert(0, " "*padding)
|
||||||
|
return txt
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#begin nocover
|
#begin nocover
|
||||||
|
|
||||||
def int_version(v):
|
def int_version(v):
|
||||||
|
@ -67,8 +116,9 @@ class WWrap(urwid.WidgetWrap):
|
||||||
|
|
||||||
|
|
||||||
class ConnectionItem(WWrap):
|
class ConnectionItem(WWrap):
|
||||||
def __init__(self, master, state, flow):
|
def __init__(self, master, state, flow, focus):
|
||||||
self.master, self.state, self.flow = master, state, flow
|
self.master, self.state, self.flow = master, state, flow
|
||||||
|
self.focus = focus
|
||||||
w = self.get_text()
|
w = self.get_text()
|
||||||
WWrap.__init__(self, w)
|
WWrap.__init__(self, w)
|
||||||
|
|
||||||
|
@ -77,7 +127,7 @@ class ConnectionItem(WWrap):
|
||||||
self.w = self.get_text()
|
self.w = self.get_text()
|
||||||
|
|
||||||
def get_text(self):
|
def get_text(self):
|
||||||
return urwid.Text(self.flow.get_text())
|
return urwid.Text(format_flow(self.flow, self.focus))
|
||||||
|
|
||||||
def selectable(self):
|
def selectable(self):
|
||||||
return True
|
return True
|
||||||
|
@ -123,7 +173,7 @@ class ConnectionListView(urwid.ListWalker):
|
||||||
|
|
||||||
def get_focus(self):
|
def get_focus(self):
|
||||||
f, i = self.state.get_focus()
|
f, i = self.state.get_focus()
|
||||||
f = ConnectionItem(self.master, self.state, f) if f else None
|
f = ConnectionItem(self.master, self.state, f, True) if f else None
|
||||||
return f, i
|
return f, i
|
||||||
|
|
||||||
def set_focus(self, focus):
|
def set_focus(self, focus):
|
||||||
|
@ -133,23 +183,24 @@ class ConnectionListView(urwid.ListWalker):
|
||||||
|
|
||||||
def get_next(self, pos):
|
def get_next(self, pos):
|
||||||
f, i = self.state.get_next(pos)
|
f, i = self.state.get_next(pos)
|
||||||
f = ConnectionItem(self.master, self.state, f) if f else None
|
f = ConnectionItem(self.master, self.state, f, False) if f else None
|
||||||
return f, i
|
return f, i
|
||||||
|
|
||||||
def get_prev(self, pos):
|
def get_prev(self, pos):
|
||||||
f, i = self.state.get_prev(pos)
|
f, i = self.state.get_prev(pos)
|
||||||
f = ConnectionItem(self.master, self.state, f) if f else None
|
f = ConnectionItem(self.master, self.state, f, False) if f else None
|
||||||
return f, i
|
return f, i
|
||||||
|
|
||||||
|
|
||||||
class ConnectionViewHeader(WWrap):
|
class ConnectionViewHeader(WWrap):
|
||||||
def __init__(self, flow):
|
def __init__(self, master, flow):
|
||||||
self.flow = flow
|
self.master, self.flow = master, flow
|
||||||
self.w = urwid.Text(flow.get_text(nofocus=True, padding=0))
|
self.w = urwid.Text(format_flow(flow, False, padding=0))
|
||||||
|
|
||||||
def refresh_connection(self, f):
|
def refresh_connection(self, flow):
|
||||||
if f == self.flow:
|
if f == self.flow:
|
||||||
self.w = urwid.Text(f.get_text(nofocus=True, padding=0))
|
self.w = urwid.Text(format_flow(flow, False, padding=0))
|
||||||
|
|
||||||
|
|
||||||
VIEW_BODY_RAW = 0
|
VIEW_BODY_RAW = 0
|
||||||
VIEW_BODY_BINARY = 1
|
VIEW_BODY_BINARY = 1
|
||||||
|
@ -602,59 +653,6 @@ class StatusBar(WWrap):
|
||||||
|
|
||||||
#end nocover
|
#end nocover
|
||||||
|
|
||||||
class ConsoleFlow(flow.Flow):
|
|
||||||
def __init__(self, connection):
|
|
||||||
flow.Flow.__init__(self, connection)
|
|
||||||
self.focus = False
|
|
||||||
|
|
||||||
def get_text(self, nofocus=False, padding=3):
|
|
||||||
if not self.request and not self.response:
|
|
||||||
txt = [
|
|
||||||
("title", " Connection from %s..."%(self.connection.address)),
|
|
||||||
]
|
|
||||||
else:
|
|
||||||
txt = [
|
|
||||||
("ack", "!") if self.intercepting and not self.request.acked else " ",
|
|
||||||
("method", self.request.method),
|
|
||||||
" ",
|
|
||||||
(
|
|
||||||
"text" if (self.response or self.error) else "title",
|
|
||||||
self.request.url(),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
if self.response or self.error or self.is_replay():
|
|
||||||
txt.append("\n" + " "*(padding+2))
|
|
||||||
if self.is_replay():
|
|
||||||
txt.append(("method", "[replay] "))
|
|
||||||
if not (self.response or self.error):
|
|
||||||
txt.append(("text", "waiting for response..."))
|
|
||||||
|
|
||||||
if self.response:
|
|
||||||
txt.append(
|
|
||||||
("ack", "!") if self.intercepting and not self.response.acked else " "
|
|
||||||
)
|
|
||||||
txt.append("<- ")
|
|
||||||
if self.response.code in [200, 304]:
|
|
||||||
txt.append(("goodcode", str(self.response.code)))
|
|
||||||
else:
|
|
||||||
txt.append(("error", str(self.response.code)))
|
|
||||||
t = self.response.headers.get("content-type")
|
|
||||||
if t:
|
|
||||||
t = t[0].split(";")[0]
|
|
||||||
txt.append(("text", " %s"%t))
|
|
||||||
if self.response.content:
|
|
||||||
txt.append(", %s"%utils.pretty_size(len(self.response.content)))
|
|
||||||
elif self.error:
|
|
||||||
txt.append(
|
|
||||||
("error", self.error.msg)
|
|
||||||
)
|
|
||||||
if self.focus and not nofocus:
|
|
||||||
txt.insert(0, ("focus", ">>" + " "*(padding-2)))
|
|
||||||
else:
|
|
||||||
txt.insert(0, " "*padding)
|
|
||||||
return txt
|
|
||||||
|
|
||||||
|
|
||||||
class ConsoleState(flow.State):
|
class ConsoleState(flow.State):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
flow.State.__init__(self)
|
flow.State.__init__(self)
|
||||||
|
@ -694,13 +692,10 @@ class ConsoleState(flow.State):
|
||||||
|
|
||||||
def set_focus(self, idx):
|
def set_focus(self, idx):
|
||||||
if self.view:
|
if self.view:
|
||||||
for i in self.view:
|
|
||||||
i.focus = False
|
|
||||||
if idx >= len(self.view):
|
if idx >= len(self.view):
|
||||||
idx = len(self.view) - 1
|
idx = len(self.view) - 1
|
||||||
elif idx < 0:
|
elif idx < 0:
|
||||||
idx = 0
|
idx = 0
|
||||||
self.view[idx].focus = True
|
|
||||||
self.focus = idx
|
self.focus = idx
|
||||||
|
|
||||||
def get_from_pos(self, pos):
|
def get_from_pos(self, pos):
|
||||||
|
@ -817,7 +812,6 @@ class ConsoleMaster(controller.Master):
|
||||||
sys.stderr.flush()
|
sys.stderr.flush()
|
||||||
self.shutdown()
|
self.shutdown()
|
||||||
|
|
||||||
|
|
||||||
def make_view(self):
|
def make_view(self):
|
||||||
self.view = urwid.Frame(
|
self.view = urwid.Frame(
|
||||||
self.body,
|
self.body,
|
||||||
|
@ -850,7 +844,7 @@ class ConsoleMaster(controller.Master):
|
||||||
def view_flow(self, flow):
|
def view_flow(self, flow):
|
||||||
self.statusbar = StatusBar(self, self.footer_text_connview)
|
self.statusbar = StatusBar(self, self.footer_text_connview)
|
||||||
self.body = ConnectionView(self, self.state, flow)
|
self.body = ConnectionView(self, self.state, flow)
|
||||||
self.header = ConnectionViewHeader(flow)
|
self.header = ConnectionViewHeader(self, flow)
|
||||||
self.viewstate = VIEW_FLOW
|
self.viewstate = VIEW_FLOW
|
||||||
self.currentflow = flow
|
self.currentflow = flow
|
||||||
self.make_view()
|
self.make_view()
|
||||||
|
@ -903,7 +897,7 @@ class ConsoleMaster(controller.Master):
|
||||||
f.close()
|
f.close()
|
||||||
except IOError, v:
|
except IOError, v:
|
||||||
return v.strerror
|
return v.strerror
|
||||||
self.state.load_flows(data, ConsoleFlow)
|
self.state.load_flows(data)
|
||||||
if self.conn_list_view:
|
if self.conn_list_view:
|
||||||
self.conn_list_view.set_focus(0)
|
self.conn_list_view.set_focus(0)
|
||||||
self.sync_list_view()
|
self.sync_list_view()
|
||||||
|
@ -1209,7 +1203,7 @@ class ConsoleMaster(controller.Master):
|
||||||
|
|
||||||
# Handlers
|
# Handlers
|
||||||
def handle_browserconnection(self, r):
|
def handle_browserconnection(self, r):
|
||||||
f = ConsoleFlow(r)
|
f = flow.Flow(r)
|
||||||
self.state.add_browserconnect(f)
|
self.state.add_browserconnect(f)
|
||||||
r.ack()
|
r.ack()
|
||||||
self.sync_list_view()
|
self.sync_list_view()
|
||||||
|
|
|
@ -33,6 +33,12 @@ class Flow:
|
||||||
self.intercepting = False
|
self.intercepting = False
|
||||||
self._backup = None
|
self._backup = None
|
||||||
|
|
||||||
|
def run_script(self):
|
||||||
|
"""
|
||||||
|
Run a script on a flow, returning the modified flow.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
def dump(self):
|
def dump(self):
|
||||||
data = dict(
|
data = dict(
|
||||||
flows = [self.get_state()]
|
flows = [self.get_state()]
|
||||||
|
@ -160,9 +166,9 @@ class State:
|
||||||
)
|
)
|
||||||
return bson.dumps(data)
|
return bson.dumps(data)
|
||||||
|
|
||||||
def load_flows(self, js, klass):
|
def load_flows(self, js):
|
||||||
data = bson.loads(js)
|
data = bson.loads(js)
|
||||||
data = [klass.from_state(i) for i in data["flows"]]
|
data = [Flow.from_state(i) for i in data["flows"]]
|
||||||
self.flow_list.extend(data)
|
self.flow_list.extend(data)
|
||||||
|
|
||||||
def set_limit(self, limit):
|
def set_limit(self, limit):
|
||||||
|
|
|
@ -19,14 +19,14 @@ def tresp(req=None):
|
||||||
|
|
||||||
def tflow():
|
def tflow():
|
||||||
bc = proxy.BrowserConnection("address", 22)
|
bc = proxy.BrowserConnection("address", 22)
|
||||||
return console.ConsoleFlow(bc)
|
return flow.Flow(bc)
|
||||||
|
|
||||||
|
|
||||||
class uState(libpry.AutoTree):
|
class uState(libpry.AutoTree):
|
||||||
def test_backup(self):
|
def test_backup(self):
|
||||||
bc = proxy.BrowserConnection("address", 22)
|
bc = proxy.BrowserConnection("address", 22)
|
||||||
c = console.ConsoleState()
|
c = console.ConsoleState()
|
||||||
f = console.ConsoleFlow(bc)
|
f = flow.Flow(bc)
|
||||||
c.add_browserconnect(f)
|
c.add_browserconnect(f)
|
||||||
|
|
||||||
f.backup()
|
f.backup()
|
||||||
|
@ -40,7 +40,7 @@ class uState(libpry.AutoTree):
|
||||||
"""
|
"""
|
||||||
bc = proxy.BrowserConnection("address", 22)
|
bc = proxy.BrowserConnection("address", 22)
|
||||||
c = console.ConsoleState()
|
c = console.ConsoleState()
|
||||||
f = console.ConsoleFlow(bc)
|
f = flow.Flow(bc)
|
||||||
c.add_browserconnect(f)
|
c.add_browserconnect(f)
|
||||||
assert c.lookup(bc)
|
assert c.lookup(bc)
|
||||||
assert c.get_focus() == (f, 0)
|
assert c.get_focus() == (f, 0)
|
||||||
|
@ -66,7 +66,7 @@ class uState(libpry.AutoTree):
|
||||||
def test_err(self):
|
def test_err(self):
|
||||||
bc = proxy.BrowserConnection("address", 22)
|
bc = proxy.BrowserConnection("address", 22)
|
||||||
c = console.ConsoleState()
|
c = console.ConsoleState()
|
||||||
f = console.ConsoleFlow(bc)
|
f = flow.Flow(bc)
|
||||||
c.add_browserconnect(f)
|
c.add_browserconnect(f)
|
||||||
e = proxy.Error(bc, "message")
|
e = proxy.Error(bc, "message")
|
||||||
assert c.add_error(e)
|
assert c.add_error(e)
|
||||||
|
@ -104,7 +104,7 @@ class uState(libpry.AutoTree):
|
||||||
c = console.ConsoleState()
|
c = console.ConsoleState()
|
||||||
|
|
||||||
bc = proxy.BrowserConnection("address", 22)
|
bc = proxy.BrowserConnection("address", 22)
|
||||||
f = console.ConsoleFlow(bc)
|
f = flow.Flow(bc)
|
||||||
c.add_browserconnect(f)
|
c.add_browserconnect(f)
|
||||||
assert c.get_focus() == (f, 0)
|
assert c.get_focus() == (f, 0)
|
||||||
assert c.get_from_pos(0) == (f, 0)
|
assert c.get_from_pos(0) == (f, 0)
|
||||||
|
@ -112,7 +112,7 @@ class uState(libpry.AutoTree):
|
||||||
assert c.get_next(0) == (None, None)
|
assert c.get_next(0) == (None, None)
|
||||||
|
|
||||||
bc2 = proxy.BrowserConnection("address", 22)
|
bc2 = proxy.BrowserConnection("address", 22)
|
||||||
f2 = console.ConsoleFlow(bc2)
|
f2 = flow.Flow(bc2)
|
||||||
c.add_browserconnect(f2)
|
c.add_browserconnect(f2)
|
||||||
assert c.get_focus() == (f, 1)
|
assert c.get_focus() == (f, 1)
|
||||||
assert c.get_next(0) == (f, 1)
|
assert c.get_next(0) == (f, 1)
|
||||||
|
@ -193,8 +193,8 @@ class uState(libpry.AutoTree):
|
||||||
|
|
||||||
dump = c.dump_flows()
|
dump = c.dump_flows()
|
||||||
c.clear()
|
c.clear()
|
||||||
c.load_flows(dump, console.ConsoleFlow)
|
c.load_flows(dump)
|
||||||
assert isinstance(c.flow_list[0], console.ConsoleFlow)
|
assert isinstance(c.flow_list[0], flow.Flow)
|
||||||
|
|
||||||
|
|
||||||
class uFlow(libpry.AutoTree):
|
class uFlow(libpry.AutoTree):
|
||||||
|
@ -212,36 +212,44 @@ class uFlow(libpry.AutoTree):
|
||||||
def test_getset_state(self):
|
def test_getset_state(self):
|
||||||
f = tflow()
|
f = tflow()
|
||||||
state = f.get_state()
|
state = f.get_state()
|
||||||
assert f == console.ConsoleFlow.from_state(state)
|
assert f == flow.Flow.from_state(state)
|
||||||
f.response = tresp()
|
f.response = tresp()
|
||||||
f.request = f.response.request
|
f.request = f.response.request
|
||||||
state = f.get_state()
|
state = f.get_state()
|
||||||
assert f == console.ConsoleFlow.from_state(state)
|
assert f == flow.Flow.from_state(state)
|
||||||
|
|
||||||
def test_simple(self):
|
def test_simple(self):
|
||||||
f = tflow()
|
f = tflow()
|
||||||
assert f.get_text()
|
assert console.format_flow(f, True)
|
||||||
|
assert console.format_flow(f, False)
|
||||||
|
|
||||||
f.request = treq()
|
f.request = treq()
|
||||||
assert f.get_text()
|
assert console.format_flow(f, True)
|
||||||
|
assert console.format_flow(f, False)
|
||||||
|
|
||||||
f.response = tresp()
|
f.response = tresp()
|
||||||
f.response.headers["content-type"] = ["text/html"]
|
f.response.headers["content-type"] = ["text/html"]
|
||||||
assert f.get_text()
|
assert console.format_flow(f, True)
|
||||||
|
assert console.format_flow(f, False)
|
||||||
f.response.code = 404
|
f.response.code = 404
|
||||||
assert f.get_text()
|
assert console.format_flow(f, True)
|
||||||
|
assert console.format_flow(f, False)
|
||||||
|
|
||||||
f.focus = True
|
f.focus = True
|
||||||
assert f.get_text()
|
assert console.format_flow(f, True)
|
||||||
|
assert console.format_flow(f, False)
|
||||||
|
|
||||||
f.connection = flow.ReplayConnection()
|
f.connection = flow.ReplayConnection()
|
||||||
assert f.get_text()
|
assert console.format_flow(f, True)
|
||||||
|
assert console.format_flow(f, False)
|
||||||
|
|
||||||
f.response = None
|
f.response = None
|
||||||
assert f.get_text()
|
assert console.format_flow(f, True)
|
||||||
|
assert console.format_flow(f, False)
|
||||||
|
|
||||||
f.error = proxy.Error(200, "test")
|
f.error = proxy.Error(200, "test")
|
||||||
assert f.get_text()
|
assert console.format_flow(f, True)
|
||||||
|
assert console.format_flow(f, False)
|
||||||
|
|
||||||
def test_kill(self):
|
def test_kill(self):
|
||||||
f = tflow()
|
f = tflow()
|
||||||
|
@ -274,7 +282,7 @@ class uFlow(libpry.AutoTree):
|
||||||
assert f.response.acked
|
assert f.response.acked
|
||||||
|
|
||||||
def test_serialization(self):
|
def test_serialization(self):
|
||||||
f = console.ConsoleFlow(None)
|
f = flow.Flow(None)
|
||||||
f.request = treq()
|
f.request = treq()
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue