mirror of
https://github.com/mitmproxy/mitmproxy.git
synced 2024-11-24 21:59:44 +00:00
Add flow detail view as a tab in the flow view
This commit is contained in:
parent
cacd09fafc
commit
8f5cf833d0
@ -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()
|
||||
|
@ -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()
|
||||
cc = flow.client_conn
|
||||
sc = flow.server_conn
|
||||
req = flow.request
|
||||
resp = flow.response
|
||||
|
||||
if sc:
|
||||
text.append(urwid.Text([("head", "Server Connection:")]))
|
||||
parts = [
|
||||
["Address", "%s:%s" % sc.address()],
|
||||
]
|
||||
|
||||
text.extend(
|
||||
common.format_keyvals(parts, key="key", val="text", indent=4)
|
||||
)
|
||||
|
||||
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 = []
|
||||
|
||||
title = urwid.Text("Flow details")
|
||||
title = urwid.Padding(title, align="left", width=("relative", 100))
|
||||
title = urwid.AttrWrap(title, "heading")
|
||||
text.append(title)
|
||||
|
||||
cc = self.flow.client_conn
|
||||
sc = self.flow.server_conn
|
||||
req = self.flow.request
|
||||
resp = self.flow.response
|
||||
|
||||
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()],
|
||||
]
|
||||
|
||||
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)
|
||||
)
|
||||
],
|
||||
[
|
||||
"Issuer",
|
||||
urwid.BoxAdapter(
|
||||
urwid.ListBox(common.format_keyvals(c.issuer, key="highlight", val="text")),
|
||||
len(c.issuer)
|
||||
)
|
||||
]
|
||||
]
|
||||
|
||||
if c.altnames:
|
||||
parts.append(
|
||||
[
|
||||
"Alt names",
|
||||
", ".join(c.altnames)
|
||||
]
|
||||
["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)
|
||||
)
|
||||
text.extend(common.format_keyvals(parts, key="key", val="text", indent=4))
|
||||
|
||||
if cc:
|
||||
text.append(urwid.Text([("head", "Client Connection:")]))
|
||||
|
||||
parts = [
|
||||
["Address", "%s:%s" % cc.address()],
|
||||
# ["Requests", "%s"%cc.requestcount],
|
||||
],
|
||||
[
|
||||
"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))
|
||||
if c.altnames:
|
||||
parts.append(
|
||||
[
|
||||
"Alt names",
|
||||
", ".join(c.altnames)
|
||||
]
|
||||
)
|
||||
text.extend(
|
||||
common.format_keyvals(parts, key="key", val="text", indent=4)
|
||||
)
|
||||
|
||||
parts = []
|
||||
if cc:
|
||||
text.append(urwid.Text([("head", "Client Connection:")]))
|
||||
|
||||
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"])
|
||||
parts = [
|
||||
["Address", "%s:%s" % cc.address()],
|
||||
# ["Requests", "%s"%cc.requestcount],
|
||||
]
|
||||
|
||||
# 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)
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user