aboutsummaryrefslogtreecommitdiffstats
path: root/libmproxy/console
diff options
context:
space:
mode:
authorAldo Cortesi <aldo@nullcube.com>2012-04-08 19:23:05 +1200
committerAldo Cortesi <aldo@nullcube.com>2012-04-08 19:44:01 +1200
commit4e2d19714c8c0f801ba58fccece8e658bc321c4e (patch)
tree07b62518bb8d54e41d9234b9d62f496e05d6bb19 /libmproxy/console
parent618a9c0e2b447f200afec8b2dcdba3c3426a17fa (diff)
downloadmitmproxy-4e2d19714c8c0f801ba58fccece8e658bc321c4e.tar.gz
mitmproxy-4e2d19714c8c0f801ba58fccece8e658bc321c4e.tar.bz2
mitmproxy-4e2d19714c8c0f801ba58fccece8e658bc321c4e.zip
Add an "f" shortcut key to load full body contents.
Diffstat (limited to 'libmproxy/console')
-rw-r--r--libmproxy/console/__init__.py1
-rw-r--r--libmproxy/console/contentview.py60
-rw-r--r--libmproxy/console/flowview.py53
3 files changed, 69 insertions, 45 deletions
diff --git a/libmproxy/console/__init__.py b/libmproxy/console/__init__.py
index f1622c0a..6f1a3d32 100644
--- a/libmproxy/console/__init__.py
+++ b/libmproxy/console/__init__.py
@@ -234,6 +234,7 @@ class StatusBar(common.WWrap):
else:
self.expire = None
self.ab.message(msg)
+ self.master.drawscreen()
#end nocover
diff --git a/libmproxy/console/contentview.py b/libmproxy/console/contentview.py
index 1abb3172..a56a94c5 100644
--- a/libmproxy/console/contentview.py
+++ b/libmproxy/console/contentview.py
@@ -7,7 +7,7 @@ import common
from .. import utils, encoding, flow
from ..contrib import jsbeautifier
-VIEW_CUTOFF = 1024*100
+VIEW_CUTOFF = 1024*50
VIEW_AUTO = 0
VIEW_JSON = 1
@@ -76,20 +76,22 @@ CONTENT_TYPES_MAP = {
"image/x-icon": VIEW_IMAGE,
}
-def trailer(clen, txt):
- rem = clen - VIEW_CUTOFF
+def trailer(clen, txt, limit):
+ rem = clen - limit
if rem > 0:
txt.append(urwid.Text(""))
txt.append(
urwid.Text(
[
- ("highlight", "... %s of data not shown"%utils.pretty_size(rem))
+ ("highlight", "... %s of data not shown. Press "%utils.pretty_size(rem)),
+ ("key", "f"),
+ ("highlight", " to load all data.")
]
)
)
-def _view_text(content, total):
+def _view_text(content, total, limit):
"""
Generates a body for a chunk of text.
"""
@@ -98,18 +100,18 @@ def _view_text(content, total):
txt.append(
urwid.Text(("text", i), wrap="any")
)
- trailer(total, txt)
+ trailer(total, txt, limit)
return txt
-def view_raw(hdrs, content):
- txt = _view_text(content[:VIEW_CUTOFF], len(content))
+def view_raw(hdrs, content, limit):
+ txt = _view_text(content[:limit], len(content), limit)
return "Raw", txt
-def view_hex(hdrs, content):
+def view_hex(hdrs, content, limit):
txt = []
- for offset, hexa, s in utils.hexdump(content[:VIEW_CUTOFF]):
+ for offset, hexa, s in utils.hexdump(content[:limit]):
txt.append(urwid.Text([
("offset", offset),
" ",
@@ -117,11 +119,11 @@ def view_hex(hdrs, content):
" ",
("text", s),
]))
- trailer(len(content), txt)
+ trailer(len(content), txt, limit)
return "Hex", txt
-def view_xml(hdrs, content):
+def view_xml(hdrs, content, limit):
parser = lxml.etree.XMLParser(remove_blank_text=True, resolve_entities=False, strip_cdata=False, recover=False)
try:
document = lxml.etree.fromstring(content, parser)
@@ -151,24 +153,24 @@ def view_xml(hdrs, content):
)
txt = []
- for i in s[:VIEW_CUTOFF].strip().split("\n"):
+ for i in s[:limit].strip().split("\n"):
txt.append(
urwid.Text(("text", i)),
)
- trailer(len(content), txt)
+ trailer(len(content), txt, limit)
return "XML-like data", txt
-def view_html(hdrs, content):
+def view_html(hdrs, content, limit):
if utils.isXML(content):
parser = lxml.etree.HTMLParser(strip_cdata=True, remove_blank_text=True)
d = lxml.html.fromstring(content, parser=parser)
docinfo = d.getroottree().docinfo
s = lxml.etree.tostring(d, pretty_print=True, doctype=docinfo.doctype)
- return "HTML", _view_text(s[:VIEW_CUTOFF], len(s))
+ return "HTML", _view_text(s[:limit], len(s), limit)
-def view_json(hdrs, content):
+def view_json(hdrs, content, limit):
lines = utils.pretty_json(content)
if lines:
txt = []
@@ -178,13 +180,13 @@ def view_json(hdrs, content):
txt.append(
urwid.Text(("text", i)),
)
- if sofar > VIEW_CUTOFF:
+ if sofar > limit:
break
- trailer(sum(len(i) for i in lines), txt)
+ trailer(sum(len(i) for i in lines), txt, limit)
return "JSON", txt
-def view_multipart(hdrs, content):
+def view_multipart(hdrs, content, limit):
v = hdrs.get("content-type")
if v:
v = utils.parse_content_type(v[0])
@@ -218,7 +220,7 @@ def view_multipart(hdrs, content):
return "Multipart form", r
-def view_urlencoded(hdrs, content):
+def view_urlencoded(hdrs, content, limit):
lines = utils.urldecode(content)
if lines:
body = common.format_keyvals(
@@ -229,18 +231,20 @@ def view_urlencoded(hdrs, content):
return "URLEncoded form", body
-def view_javascript(hdrs, content):
+def view_javascript(hdrs, content, limit):
opts = jsbeautifier.default_options()
opts.indent_size = 2
try:
- res = jsbeautifier.beautify(content[:VIEW_CUTOFF], opts)
+ res = jsbeautifier.beautify(content[:limit], opts)
+ # begin nocover
except:
# Bugs in jsbeautifier mean that it can trhow arbitrary errors.
return None
- return "JavaScript", _view_text(res, len(content))
+ # end nocover
+ return "JavaScript", _view_text(res, len(content), limit)
-def view_image(hdrs, content):
+def view_image(hdrs, content, limit):
try:
img = Image.open(cStringIO.StringIO(content))
except IOError:
@@ -302,7 +306,7 @@ def get_view_func(viewmode, hdrs, content):
return PRETTY_FUNCTION_MAP.get(viewmode, view_raw)
-def get_content_view(viewmode, hdrItems, content):
+def get_content_view(viewmode, hdrItems, content, limit):
"""
Returns a (msg, body) tuple.
"""
@@ -317,10 +321,10 @@ def get_content_view(viewmode, hdrItems, content):
content = decoded
msg.append("[decoded %s]"%enc[0])
func = get_view_func(viewmode, hdrs, content)
- ret = func(hdrs, content)
+ ret = func(hdrs, content, limit)
if not ret:
viewmode = VIEW_RAW
- ret = view_raw(hdrs, content)
+ ret = view_raw(hdrs, content, limit)
msg.append("Couldn't parse: falling back to Raw")
else:
msg.append(ret[0])
diff --git a/libmproxy/console/flowview.py b/libmproxy/console/flowview.py
index f84b6b84..1599421f 100644
--- a/libmproxy/console/flowview.py
+++ b/libmproxy/console/flowview.py
@@ -13,7 +13,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-import os, re
+import os, re, sys
import urwid
import common, grideditor, contentview
from .. import utils, encoding, flow
@@ -125,15 +125,25 @@ class FlowView(common.WWrap):
else:
self.view_request()
- def _cached_content_view(self, viewmode, hdrItems, content):
- return contentview.get_content_view(viewmode, hdrItems, content)
+ def _cached_content_view(self, viewmode, hdrItems, content, limit):
+ return contentview.get_content_view(viewmode, hdrItems, content, limit)
def content_view(self, viewmode, conn):
+ full = self.state.get_flow_setting(
+ self.flow,
+ (self.state.view_flow_mode, "fullcontents"),
+ False
+ )
+ if full:
+ limit = sys.maxint
+ else:
+ limit = contentview.VIEW_CUTOFF
return cache.callback(
self, "_cached_content_view",
viewmode,
tuple(tuple(i) for i in conn.headers.lst),
conn.content,
+ limit
)
def conn_text(self, conn):
@@ -407,6 +417,20 @@ class FlowView(common.WWrap):
elif key == "A":
self.master.accept_all()
self.master.view_flow(self.flow)
+ elif key == "b":
+ if conn:
+ if self.state.view_flow_mode == common.VIEW_FLOW_REQUEST:
+ self.master.path_prompt(
+ "Save request body: ",
+ self.state.last_saveload,
+ self.save_body
+ )
+ else:
+ self.master.path_prompt(
+ "Save response body: ",
+ self.state.last_saveload,
+ self.save_body
+ )
elif key == "d":
if self.state.flow_count() == 1:
self.master.view_flowlist()
@@ -448,6 +472,15 @@ class FlowView(common.WWrap):
self.edit
)
key = None
+ elif key == "f":
+ self.master.statusbar.message("Loading all body data...")
+ self.state.add_flow_setting(
+ self.flow,
+ (self.state.view_flow_mode, "fullcontents"),
+ True
+ )
+ self.master.refresh_flow(self.flow)
+ self.master.statusbar.message("")
elif key == "m":
p = list(contentview.VIEW_PROMPT)
p.insert(0, ("clear", "c"))
@@ -484,20 +517,6 @@ class FlowView(common.WWrap):
t = conn.headers["content-type"] or [None]
t = t[0]
self.master.spawn_external_viewer(conn.content, t)
- elif key == "b":
- if conn:
- if self.state.view_flow_mode == common.VIEW_FLOW_REQUEST:
- self.master.path_prompt(
- "Save request body: ",
- self.state.last_saveload,
- self.save_body
- )
- else:
- self.master.path_prompt(
- "Save response body: ",
- self.state.last_saveload,
- self.save_body
- )
elif key == "|":
self.master.path_prompt(
"Send flow to script: ", self.state.last_script,