Merge pull request #3970 from nikitastupin/master

Integrate contentviews to TCP flow details
This commit is contained in:
Maximilian Hils 2020-05-03 10:51:10 +02:00 committed by GitHub
commit f4aa3ee11c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 77 additions and 9 deletions

View File

@ -116,6 +116,19 @@ def get_message_content_view(viewname, message, flow):
return description, lines, error return description, lines, error
def get_tcp_content_view(viewname: str, data: bytes):
viewmode = get(viewname)
if not viewmode:
viewmode = get("auto")
# https://github.com/mitmproxy/mitmproxy/pull/3970#issuecomment-623024447
assert viewmode
description, lines, error = get_content_view(viewmode, data)
return description, lines, error
def get_content_view(viewmode: View, data: bytes, **metadata): def get_content_view(viewmode: View, data: bytes, **metadata):
""" """
Args: Args:

View File

@ -104,6 +104,8 @@ if urwid.util.detected_encoding:
SYMBOL_UP = u"\u21E7" SYMBOL_UP = u"\u21E7"
SYMBOL_DOWN = u"\u21E9" SYMBOL_DOWN = u"\u21E9"
SYMBOL_ELLIPSIS = u"\u2026" SYMBOL_ELLIPSIS = u"\u2026"
SYMBOL_FROM_CLIENT = u"\u21d2"
SYMBOL_TO_CLIENT = u"\u21d0"
else: else:
SYMBOL_REPLAY = u"[r]" SYMBOL_REPLAY = u"[r]"
SYMBOL_RETURN = u"<-" SYMBOL_RETURN = u"<-"
@ -111,6 +113,8 @@ else:
SYMBOL_UP = "^" SYMBOL_UP = "^"
SYMBOL_DOWN = " " SYMBOL_DOWN = " "
SYMBOL_ELLIPSIS = "~" SYMBOL_ELLIPSIS = "~"
SYMBOL_FROM_CLIENT = u"->"
SYMBOL_TO_CLIENT = u"<-"
SCHEME_STYLES = { SCHEME_STYLES = {
'http': 'scheme_http', 'http': 'scheme_http',

View File

@ -108,6 +108,26 @@ class FlowDetails(tabs.Tabs):
assert isinstance(flow, http.HTTPFlow) assert isinstance(flow, http.HTTPFlow)
return self.conn_text(flow.response) return self.conn_text(flow.response)
def _contentview_status_bar(self, description: str, viewmode: str):
cols = [
urwid.Text(
[
("heading", description),
]
),
urwid.Text(
[
" ",
('heading', "["),
('heading_key', "m"),
('heading', (":%s]" % viewmode)),
],
align="right"
)
]
contentview_status_bar = urwid.AttrWrap(urwid.Columns(cols), "heading")
return contentview_status_bar
def view_tcp_stream(self) -> urwid.Widget: def view_tcp_stream(self) -> urwid.Widget:
flow = self.flow flow = self.flow
assert isinstance(flow, tcp.TCPFlow) assert isinstance(flow, tcp.TCPFlow)
@ -115,6 +135,10 @@ class FlowDetails(tabs.Tabs):
if not flow.messages: if not flow.messages:
return searchable.Searchable([urwid.Text(("highlight", "No messages."))]) return searchable.Searchable([urwid.Text(("highlight", "No messages."))])
viewmode = self.master.commands.call("console.flowview.mode")
# Merge adjacent TCP "messages". For detailed explanation of this code block see:
# https://github.com/mitmproxy/mitmproxy/pull/3970/files/469bd32582f764f9a29607efa4f5b04bd87961fb#r418670880
from_client = None from_client = None
messages = [] messages = []
for message in flow.messages: for message in flow.messages:
@ -124,17 +148,25 @@ class FlowDetails(tabs.Tabs):
else: else:
messages[-1] += message.content messages[-1] += message.content
widget_lines = []
from_client = flow.messages[0].from_client from_client = flow.messages[0].from_client
parts = [] for m in messages:
for message in messages: _, lines, _ = contentviews.get_tcp_content_view(viewmode, m)
parts.append(
( for line in lines:
"head" if from_client else "key", if from_client:
message line.insert(0, ("from_client", f"{common.SYMBOL_FROM_CLIENT} "))
) else:
) line.insert(0, ("to_client", f"{common.SYMBOL_TO_CLIENT} "))
widget_lines.append(urwid.Text(line))
from_client = not from_client from_client = not from_client
return searchable.Searchable([urwid.Text(parts)])
widget_lines.insert(0, self._contentview_status_bar(viewmode.capitalize(), viewmode))
return searchable.Searchable(widget_lines)
def view_details(self): def view_details(self):
return flowdetailview.flowdetails(self.view, self.flow) return flowdetailview.flowdetails(self.view, self.flow)

View File

@ -37,6 +37,9 @@ class Palette:
# JSON view # JSON view
'json_string', 'json_number', 'json_boolean', 'json_string', 'json_number', 'json_boolean',
# TCP flow details
'from_client', 'to_client',
# Grid Editor # Grid Editor
'focusfield', 'focusfield_error', 'field_error', 'editfield', 'focusfield', 'focusfield_error', 'field_error', 'editfield',
@ -177,6 +180,10 @@ class LowDark(Palette):
json_number = ('light magenta', 'default'), json_number = ('light magenta', 'default'),
json_boolean = ('dark magenta', 'default'), json_boolean = ('dark magenta', 'default'),
# TCP flow details
from_client = ('light blue', 'default'),
to_client = ('light red', 'default'),
# Grid Editor # Grid Editor
focusfield = ('black', 'light gray'), focusfield = ('black', 'light gray'),
focusfield_error = ('dark red', 'light gray'), focusfield_error = ('dark red', 'light gray'),
@ -282,6 +289,10 @@ class LowLight(Palette):
json_number = ('light magenta', 'default'), json_number = ('light magenta', 'default'),
json_boolean = ('dark magenta', 'default'), json_boolean = ('dark magenta', 'default'),
# TCP flow details
from_client = ('dark blue', 'default'),
to_client = ('dark red', 'default'),
# Grid Editor # Grid Editor
focusfield = ('black', 'light gray'), focusfield = ('black', 'light gray'),
focusfield_error = ('dark red', 'light gray'), focusfield_error = ('dark red', 'light gray'),
@ -397,6 +408,10 @@ class SolarizedLight(LowLight):
json_number = (sol_blue, 'default'), json_number = (sol_blue, 'default'),
json_boolean = (sol_magenta, 'default'), json_boolean = (sol_magenta, 'default'),
# TCP flow details
from_client = (sol_blue, 'default'),
to_client = (sol_red, 'default'),
# Grid Editor # Grid Editor
focusfield = (sol_base00, sol_base2), focusfield = (sol_base00, sol_base2),
focusfield_error = (sol_red, sol_base2), focusfield_error = (sol_red, sol_base2),
@ -475,6 +490,10 @@ class SolarizedDark(LowDark):
json_number = (sol_blue, 'default'), json_number = (sol_blue, 'default'),
json_boolean = (sol_magenta, 'default'), json_boolean = (sol_magenta, 'default'),
# TCP flow details
from_client = (sol_blue, 'default'),
to_client = (sol_red, 'default'),
# Grid Editor # Grid Editor
focusfield = (sol_base0, sol_base02), focusfield = (sol_base0, sol_base02),
focusfield_error = (sol_red, sol_base02), focusfield_error = (sol_red, sol_base02),