aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAldo Cortesi <aldo@nullcube.com>2015-03-29 19:21:54 +1300
committerAldo Cortesi <aldo@nullcube.com>2015-03-29 19:24:37 +1300
commit8f5cf833d08aba685263554d0bd89f922cd6afae (patch)
tree798361e6411a8a284c48844dbd2cd20fb6a08d7a
parentcacd09fafc19b323c46c4c565d0044593b677e17 (diff)
downloadmitmproxy-8f5cf833d08aba685263554d0bd89f922cd6afae.tar.gz
mitmproxy-8f5cf833d08aba685263554d0bd89f922cd6afae.tar.bz2
mitmproxy-8f5cf833d08aba685263554d0bd89f922cd6afae.zip
Add flow detail view as a tab in the flow view
-rw-r--r--libmproxy/console/__init__.py9
-rw-r--r--libmproxy/console/flowdetailview.py176
-rw-r--r--libmproxy/console/flowview.py11
-rw-r--r--libmproxy/console/searchable.py2
-rw-r--r--libmproxy/console/tabs.py8
5 files changed, 95 insertions, 111 deletions
diff --git a/libmproxy/console/__init__.py b/libmproxy/console/__init__.py
index 35126eba..6e9d227b 100644
--- a/libmproxy/console/__init__.py
+++ b/libmproxy/console/__init__.py
@@ -453,15 +453,6 @@ class ConsoleMaster(flow.FlowMaster):
statusbar.StatusBar(self, help.footer)
)
- def view_flowdetails(self, flow):
- signals.push_view_state.send(self)
- self.loop.widget = window.Window(
- self,
- flowdetailview.FlowDetailsView(flow),
- None,
- statusbar.StatusBar(self, flowdetailview.footer)
- )
-
def view_grideditor(self, ge):
signals.push_view_state.send(self)
self.help_context = ge.make_help()
diff --git a/libmproxy/console/flowdetailview.py b/libmproxy/console/flowdetailview.py
index 8bfdae4a..99f2a262 100644
--- a/libmproxy/console/flowdetailview.py
+++ b/libmproxy/console/flowdetailview.py
@@ -1,110 +1,100 @@
from __future__ import absolute_import
import urwid
-from . import common, signals
+from . import common, signals, searchable
from .. import utils
-footer = [
- ('heading_key', "q"), ":back ",
-]
+def flowdetails(state, flow):
+ text = []
-class FlowDetailsView(urwid.ListBox):
- def __init__(self, flow):
- self.flow = flow
- urwid.ListBox.__init__(
- self,
- self.flowtext()
- )
-
- def keypress(self, size, key):
- key = common.shortcuts(key)
- if key == "q":
- signals.pop_view_state.send(self)
- return None
- elif key == "?":
- key = None
- return urwid.ListBox.keypress(self, size, key)
-
- def flowtext(self):
- text = []
+ cc = flow.client_conn
+ sc = flow.server_conn
+ req = flow.request
+ resp = flow.response
- title = urwid.Text("Flow details")
- title = urwid.Padding(title, align="left", width=("relative", 100))
- title = urwid.AttrWrap(title, "heading")
- text.append(title)
+ if sc:
+ text.append(urwid.Text([("head", "Server Connection:")]))
+ parts = [
+ ["Address", "%s:%s" % sc.address()],
+ ]
- cc = self.flow.client_conn
- sc = self.flow.server_conn
- req = self.flow.request
- resp = self.flow.response
+ text.extend(
+ common.format_keyvals(parts, key="key", val="text", indent=4)
+ )
- if sc:
- text.append(urwid.Text([("head", "Server Connection:")]))
+ c = sc.cert
+ if c:
+ text.append(urwid.Text([("head", "Server Certificate:")]))
parts = [
- ["Address", "%s:%s" % sc.address()],
+ ["Type", "%s, %s bits"%c.keyinfo],
+ ["SHA1 digest", c.digest("sha1")],
+ ["Valid to", str(c.notafter)],
+ ["Valid from", str(c.notbefore)],
+ ["Serial", str(c.serial)],
+ [
+ "Subject",
+ urwid.BoxAdapter(
+ urwid.ListBox(
+ common.format_keyvals(
+ c.subject,
+ key="highlight",
+ val="text"
+ )
+ ),
+ len(c.subject)
+ )
+ ],
+ [
+ "Issuer",
+ urwid.BoxAdapter(
+ urwid.ListBox(
+ common.format_keyvals(
+ c.issuer, key="highlight", val="text"
+ )
+ ),
+ len(c.issuer)
+ )
+ ]
]
- text.extend(common.format_keyvals(parts, key="key", val="text", indent=4))
-
- c = sc.cert
- if c:
- text.append(urwid.Text([("head", "Server Certificate:")]))
- parts = [
- ["Type", "%s, %s bits"%c.keyinfo],
- ["SHA1 digest", c.digest("sha1")],
- ["Valid to", str(c.notafter)],
- ["Valid from", str(c.notbefore)],
- ["Serial", str(c.serial)],
- [
- "Subject",
- urwid.BoxAdapter(
- urwid.ListBox(common.format_keyvals(c.subject, key="highlight", val="text")),
- len(c.subject)
- )
- ],
+ if c.altnames:
+ parts.append(
[
- "Issuer",
- urwid.BoxAdapter(
- urwid.ListBox(common.format_keyvals(c.issuer, key="highlight", val="text")),
- len(c.issuer)
- )
+ "Alt names",
+ ", ".join(c.altnames)
]
- ]
-
- if c.altnames:
- parts.append(
- [
- "Alt names",
- ", ".join(c.altnames)
- ]
- )
- text.extend(common.format_keyvals(parts, key="key", val="text", indent=4))
+ )
+ text.extend(
+ common.format_keyvals(parts, key="key", val="text", indent=4)
+ )
- if cc:
- text.append(urwid.Text([("head", "Client Connection:")]))
+ if cc:
+ text.append(urwid.Text([("head", "Client Connection:")]))
- parts = [
- ["Address", "%s:%s" % cc.address()],
- # ["Requests", "%s"%cc.requestcount],
- ]
+ parts = [
+ ["Address", "%s:%s" % cc.address()],
+ # ["Requests", "%s"%cc.requestcount],
+ ]
- text.extend(common.format_keyvals(parts, key="key", val="text", indent=4))
-
- parts = []
-
- parts.append(["Client conn. established", utils.format_timestamp_with_milli(cc.timestamp_start) if (cc and cc.timestamp_start) else "active"])
- parts.append(["Server conn. initiated", utils.format_timestamp_with_milli(sc.timestamp_start) if sc else "active" ])
- parts.append(["Server conn. TCP handshake", utils.format_timestamp_with_milli(sc.timestamp_tcp_setup) if (sc and sc.timestamp_tcp_setup) else "active"])
- if sc.ssl_established:
- parts.append(["Server conn. SSL handshake", utils.format_timestamp_with_milli(sc.timestamp_ssl_setup) if sc.timestamp_ssl_setup else "active"])
- parts.append(["Client conn. SSL handshake", utils.format_timestamp_with_milli(cc.timestamp_ssl_setup) if (cc and cc.timestamp_ssl_setup) else "active"])
- parts.append(["First request byte", utils.format_timestamp_with_milli(req.timestamp_start)])
- parts.append(["Request complete", utils.format_timestamp_with_milli(req.timestamp_end) if req.timestamp_end else "active"])
- parts.append(["First response byte", utils.format_timestamp_with_milli(resp.timestamp_start) if resp else "active"])
- parts.append(["Response complete", utils.format_timestamp_with_milli(resp.timestamp_end) if (resp and resp.timestamp_end) else "active"])
-
- # sort operations by timestamp
- parts = sorted(parts, key=lambda p: p[1])
+ text.extend(
+ common.format_keyvals(parts, key="key", val="text", indent=4)
+ )
- text.append(urwid.Text([("head", "Timing:")]))
- text.extend(common.format_keyvals(parts, key="key", val="text", indent=4))
- return text
+ parts = []
+
+ parts.append(["Client conn. established", utils.format_timestamp_with_milli(cc.timestamp_start) if (cc and cc.timestamp_start) else "active"])
+ parts.append(["Server conn. initiated", utils.format_timestamp_with_milli(sc.timestamp_start) if sc else "active" ])
+ parts.append(["Server conn. TCP handshake", utils.format_timestamp_with_milli(sc.timestamp_tcp_setup) if (sc and sc.timestamp_tcp_setup) else "active"])
+ if sc.ssl_established:
+ parts.append(["Server conn. SSL handshake", utils.format_timestamp_with_milli(sc.timestamp_ssl_setup) if sc.timestamp_ssl_setup else "active"])
+ parts.append(["Client conn. SSL handshake", utils.format_timestamp_with_milli(cc.timestamp_ssl_setup) if (cc and cc.timestamp_ssl_setup) else "active"])
+ parts.append(["First request byte", utils.format_timestamp_with_milli(req.timestamp_start)])
+ parts.append(["Request complete", utils.format_timestamp_with_milli(req.timestamp_end) if req.timestamp_end else "active"])
+ parts.append(["First response byte", utils.format_timestamp_with_milli(resp.timestamp_start) if resp else "active"])
+ parts.append(["Response complete", utils.format_timestamp_with_milli(resp.timestamp_end) if (resp and resp.timestamp_end) else "active"])
+
+ # sort operations by timestamp
+ parts = sorted(parts, key=lambda p: p[1])
+
+ text.append(urwid.Text([("head", "Timing:")]))
+ text.extend(common.format_keyvals(parts, key="key", val="text", indent=4))
+ return searchable.Searchable(state, text)
diff --git a/libmproxy/console/flowview.py b/libmproxy/console/flowview.py
index ffe499d7..514340c9 100644
--- a/libmproxy/console/flowview.py
+++ b/libmproxy/console/flowview.py
@@ -2,6 +2,7 @@ from __future__ import absolute_import
import os, sys, copy
import urwid
from . import common, grideditor, contentview, signals, searchable, tabs
+from . import flowdetailview
from .. import utils, flow, controller
from ..protocol.http import HTTPRequest, HTTPResponse, CONTENT_MISSING, decoded
@@ -65,7 +66,6 @@ def _mkhelp():
("w", "save all flows matching current limit"),
("W", "save this flow"),
("x", "delete body"),
- ("X", "view flow details"),
("z", "encode/decode a request/response"),
("tab", "toggle request/response view"),
("space", "next flow"),
@@ -121,6 +121,7 @@ class FlowView(tabs.Tabs):
[
(self.tab_request, self.view_request),
(self.tab_response, self.view_response),
+ (self.tab_details, self.view_details),
],
tab_offset
)
@@ -140,13 +141,17 @@ class FlowView(tabs.Tabs):
else:
return "Response"
+ def tab_details(self):
+ return "Detail"
+
def view_request(self):
return self.conn_text(self.flow.request)
def view_response(self):
return self.conn_text(self.flow.response)
-
+ def view_details(self):
+ return flowdetailview.flowdetails(self.state, self.flow)
def sig_flow_change(self, sender, flow):
if flow == self.flow:
@@ -568,8 +573,6 @@ class FlowView(tabs.Tabs):
callback = self.delete_body
)
key = None
- elif key == "X":
- self.master.view_flowdetails(self.flow)
elif key == "z":
if conn:
self.flow.backup()
diff --git a/libmproxy/console/searchable.py b/libmproxy/console/searchable.py
index 8f63c3f5..9d66c718 100644
--- a/libmproxy/console/searchable.py
+++ b/libmproxy/console/searchable.py
@@ -36,7 +36,7 @@ class Searchable(urwid.ListBox):
if key == "N":
self.find_next(True)
else:
- return super(self.__class__, self).keypress(size, key)
+ return key
def set_search(self, text):
self.state.last_search = text
diff --git a/libmproxy/console/tabs.py b/libmproxy/console/tabs.py
index 3245f430..b8943ad4 100644
--- a/libmproxy/console/tabs.py
+++ b/libmproxy/console/tabs.py
@@ -8,8 +8,8 @@ class Tabs(urwid.WidgetWrap):
self.show()
def _tab(self, content, attr):
- p = urwid.Text(content)
- p = urwid.Padding(p, align="left", width=("relative", 100))
+ p = urwid.Text(content, align="center")
+ p = urwid.Padding(p, align="center", width=("relative", 100))
p = urwid.AttrWrap(p, attr)
return p
@@ -18,7 +18,7 @@ class Tabs(urwid.WidgetWrap):
self.tab_offset = (self.tab_offset + 1)%(len(self.tabs))
self.show()
else:
- return key
+ return self._w.keypress(size, key)
def show(self):
headers = []
@@ -28,7 +28,7 @@ class Tabs(urwid.WidgetWrap):
headers.append(self._tab(txt, "heading"))
else:
headers.append(self._tab(txt, "heading_inactive"))
- headers = urwid.Columns(headers)
+ headers = urwid.Columns(headers, dividechars=1)
self._w = urwid.Frame(
body = self.tabs[self.tab_offset][1](),
header = headers