From 6c89749f0a0c77e3a56a68df8709daf9c9f2f33c Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Thu, 3 Feb 2011 13:30:47 +1300 Subject: Add timestamps to flows. For now, these are only displayed on the connection view screen, with second granularity. --- libmproxy/console.py | 24 ++++++++++++++++++++---- libmproxy/proxy.py | 21 +++++++++++++++------ libmproxy/utils.py | 8 +++++++- 3 files changed, 42 insertions(+), 11 deletions(-) (limited to 'libmproxy') diff --git a/libmproxy/console.py b/libmproxy/console.py index 8151ccea..eac2823a 100644 --- a/libmproxy/console.py +++ b/libmproxy/console.py @@ -44,13 +44,19 @@ def format_keyvals(lst, key="key", val="text", space=5, indent=0): return ret -def format_flow(f, focus, padding=3): +def format_flow(f, focus, extended=False, padding=3): if not f.request and not f.response: txt = [ ("title", " Connection from %s..."%(f.connection.address)), ] else: + if extended: + ts = ("highlight", utils.format_timestamp(f.request.timestamp)) + else: + ts = "" + txt = [ + ts, ("ack", "!") if f.intercepting and not f.request.acked else " ", ("method", f.request.method), " ", @@ -60,7 +66,16 @@ def format_flow(f, focus, padding=3): ), ] if f.response or f.error or f.is_replay(): - txt.append("\n" + " "*(padding+2)) + + tsr = f.response or f.error + if extended and tsr: + ts = ("highlight", utils.format_timestamp(tsr.timestamp)) + else: + ts = "" + + txt.append("\n") + txt.append(("text", ts)) + txt.append(" "*(padding+2)) met = "" if f.is_replay(): txt.append(("method", "[replay] ")) @@ -198,11 +213,11 @@ class ConnectionListView(urwid.ListWalker): class ConnectionViewHeader(WWrap): def __init__(self, master, f): self.master, self.flow = master, f - self.w = urwid.Text(format_flow(f, False, padding=0)) + self.w = urwid.Text(format_flow(f, False, extended=True, padding=0)) def refresh_connection(self, f): if f == self.flow: - self.w = urwid.Text(format_flow(f, False, padding=0)) + self.w = urwid.Text(format_flow(f, False, extended=True, padding=0)) VIEW_BODY_RAW = 0 @@ -810,6 +825,7 @@ class ConsoleMaster(controller.Master): ('error', 'light red', 'default'), ('header', 'dark cyan', 'default'), ('heading', 'white', 'dark blue'), + ('highlight', 'white', 'default'), ('inactive', 'dark gray', 'default'), ('ack', 'light red', 'default'), diff --git a/libmproxy/proxy.py b/libmproxy/proxy.py index 00b9e0ba..5110a71a 100644 --- a/libmproxy/proxy.py +++ b/libmproxy/proxy.py @@ -84,10 +84,11 @@ def parse_proxy_request(request): class Request(controller.Msg): FMT = '%s %s HTTP/1.0\r\n%s\r\n%s' - def __init__(self, connection, host, port, scheme, method, path, headers, content): + def __init__(self, connection, host, port, scheme, method, path, headers, content, timestamp=None): self.connection = connection self.host, self.port, self.scheme = host, port, scheme self.method, self.path, self.headers, self.content = method, path, headers, content + self.timestamp = timestamp or time.time() controller.Msg.__init__(self) def get_state(self): @@ -98,7 +99,8 @@ class Request(controller.Msg): method = self.method, path = self.path, headers = self.headers.get_state(), - content = self.content + content = self.content, + timestamp = self.timestamp, ) @classmethod @@ -111,7 +113,8 @@ class Request(controller.Msg): state["method"], state["path"], utils.Headers.from_state(state["headers"]), - state["content"] + state["content"], + state["timestamp"] ) def __eq__(self, other): @@ -159,10 +162,11 @@ class Request(controller.Msg): class Response(controller.Msg): FMT = '%s\r\n%s\r\n%s' - def __init__(self, request, code, proto, msg, headers, content): + def __init__(self, request, code, proto, msg, headers, content, timestamp=None): self.request = request self.code, self.proto, self.msg = code, proto, msg self.headers, self.content = headers, content + self.timestamp = timestamp or time.time() controller.Msg.__init__(self) def get_state(self): @@ -171,6 +175,7 @@ class Response(controller.Msg): proto = self.proto, msg = self.msg, headers = self.headers.get_state(), + timestamp = self.timestamp, content = self.content ) @@ -182,7 +187,8 @@ class Response(controller.Msg): state["proto"], state["msg"], utils.Headers.from_state(state["headers"]), - state["content"] + state["content"], + state["timestamp"], ) def __eq__(self, other): @@ -225,8 +231,9 @@ class BrowserConnection(controller.Msg): class Error(controller.Msg): - def __init__(self, connection, msg): + def __init__(self, connection, msg, timestamp=None): self.connection, self.msg = connection, msg + self.timestamp = timestamp or time.time() controller.Msg.__init__(self) def copy(self): @@ -235,6 +242,7 @@ class Error(controller.Msg): def get_state(self): return dict( msg = self.msg, + timestamp = self.timestamp, ) @classmethod @@ -242,6 +250,7 @@ class Error(controller.Msg): return klass( None, state["msg"], + state["timestamp"], ) def __eq__(self, other): diff --git a/libmproxy/utils.py b/libmproxy/utils.py index 7b9d0e32..ee0d9b43 100644 --- a/libmproxy/utils.py +++ b/libmproxy/utils.py @@ -13,9 +13,15 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import re, os, subprocess +import re, os, subprocess, datetime from contrib import BeautifulSoup + +def format_timestamp(s): + d = datetime.datetime.fromtimestamp(s) + return d.strftime("%Y-%m-%d %H:%M:%S") + + def isBin(s): """ Does this string have any non-ASCII characters? -- cgit v1.2.3