aboutsummaryrefslogtreecommitdiffstats
path: root/libmproxy
diff options
context:
space:
mode:
authorAldo Cortesi <aldo@nullcube.com>2011-06-27 15:59:17 +1200
committerAldo Cortesi <aldo@nullcube.com>2011-06-27 15:59:17 +1200
commitf004326855126e01e7a095fc65562c41060ffbed (patch)
tree976f800bd830cec66581b02066f20cdd24b1d492 /libmproxy
parent2ae7808ca9c83cb69fe6606051edd43e417281c7 (diff)
downloadmitmproxy-f004326855126e01e7a095fc65562c41060ffbed.tar.gz
mitmproxy-f004326855126e01e7a095fc65562c41060ffbed.tar.bz2
mitmproxy-f004326855126e01e7a095fc65562c41060ffbed.zip
Try not to hang when user views large request & response bodies
Two different strategies here: - Use a simple heuristic to detect if we're looking at XML data when indent mode is used. On non-XML data we can hang even on small documents. - Only view partial data for large bodies. At the moment the cutoff is 100k. I might finetune this later.
Diffstat (limited to 'libmproxy')
-rw-r--r--libmproxy/console.py31
-rw-r--r--libmproxy/utils.py13
2 files changed, 39 insertions, 5 deletions
diff --git a/libmproxy/console.py b/libmproxy/console.py
index 0aab9ad0..d1e27be6 100644
--- a/libmproxy/console.py
+++ b/libmproxy/console.py
@@ -20,6 +20,8 @@ import urwid.raw_display
import urwid
import controller, utils, filt, proxy, flow
+VIEW_CUTOFF = 1024*100
+
class Stop(Exception): pass
@@ -879,14 +881,27 @@ class ConsoleMaster(flow.FlowMaster):
self.spawn_external_viewer(serr, None)
self.refresh_connection(f)
+ def _trailer(self, content, txt):
+ rem = len(content) - VIEW_CUTOFF
+ if rem > 0:
+ txt.append(urwid.Text(""))
+ txt.append(
+ urwid.Text(
+ [
+ ("highlight", "... %s of data not shown"%utils.pretty_size(rem))
+ ]
+ )
+ )
+
def _view_conn_normal(self, content, txt):
- for i in content.splitlines():
+ for i in content[:VIEW_CUTOFF].splitlines():
txt.append(
urwid.Text(("text", i))
)
+ self._trailer(content, txt)
def _view_conn_binary(self, content, txt):
- for offset, hex, s in utils.hexdump(content):
+ for offset, hex, s in utils.hexdump(content[:VIEW_CUTOFF]):
txt.append(urwid.Text([
("offset", offset),
" ",
@@ -894,12 +909,14 @@ class ConsoleMaster(flow.FlowMaster):
" ",
("text", s),
]))
+ self._trailer(content, txt)
def _view_conn_pretty(self, content, txt):
- for i in utils.pretty_xmlish(content):
+ for i in utils.pretty_xmlish(content[:VIEW_CUTOFF]):
txt.append(
urwid.Text(("text", i)),
)
+ self._trailer(content, txt)
@utils.LRUCache(20)
def _cached_conn_text(self, content, hdrItems, viewmode):
@@ -918,7 +935,13 @@ class ConsoleMaster(flow.FlowMaster):
if viewmode == VIEW_BODY_BINARY:
self._view_conn_binary(content, txt)
elif viewmode == VIEW_BODY_INDENT:
- self._view_conn_pretty(content, txt)
+ if utils.isXML(content):
+ self._view_conn_pretty(content, txt)
+ else:
+ if utils.isBin(content):
+ self._view_conn_binary(content, txt)
+ else:
+ self._view_conn_normal(content, txt)
else:
if utils.isBin(content):
self._view_conn_binary(content, txt)
diff --git a/libmproxy/utils.py b/libmproxy/utils.py
index 209ec27a..6c9f3288 100644
--- a/libmproxy/utils.py
+++ b/libmproxy/utils.py
@@ -44,6 +44,16 @@ def isBin(s):
return False
+def isXML(s):
+ for i in s:
+ if i in "\n \t":
+ continue
+ elif i == "<":
+ return True
+ else:
+ return False
+
+
def cleanBin(s):
parts = []
for i in s:
@@ -51,7 +61,8 @@ def cleanBin(s):
if o > 31 and o < 127:
parts.append(i)
else:
- parts.append(".")
+ if i not in "\n\r\t":
+ parts.append(".")
return "".join(parts)