aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libmproxy/console/__init__.py4
-rw-r--r--libmproxy/console/flowview.py12
-rw-r--r--libmproxy/contentview.py66
-rw-r--r--libmproxy/contrib/wbxml/ASCommandResponse.py5
-rw-r--r--libmproxy/utils.py2
-rw-r--r--test/test_console_contentview.py29
6 files changed, 59 insertions, 59 deletions
diff --git a/libmproxy/console/__init__.py b/libmproxy/console/__init__.py
index 2133f97f..b75fa5d8 100644
--- a/libmproxy/console/__init__.py
+++ b/libmproxy/console/__init__.py
@@ -14,9 +14,9 @@ import traceback
import urwid
import weakref
-from .. import controller, flow, script
+from .. import controller, flow, script, contentview
from . import flowlist, flowview, help, window, signals, options
-from . import grideditor, palettes, contentview, statusbar, palettepicker
+from . import grideditor, palettes, statusbar, palettepicker
EVENTLOG_SIZE = 500
diff --git a/libmproxy/console/flowview.py b/libmproxy/console/flowview.py
index 4946ed9c..c0720652 100644
--- a/libmproxy/console/flowview.py
+++ b/libmproxy/console/flowview.py
@@ -181,7 +181,7 @@ class FlowView(tabs.Tabs):
limit = sys.maxsize
else:
limit = contentview.VIEW_CUTOFF
- description, text_objects = cache.get(
+ return cache.get(
self._get_content_view,
viewmode,
conn.headers,
@@ -189,21 +189,21 @@ class FlowView(tabs.Tabs):
limit,
isinstance(conn, HTTPRequest)
)
- return (description, text_objects)
def _get_content_view(self, viewmode, headers, content, limit, is_request):
try:
- return contentview.get_content_view(
+ description, lines = contentview.get_content_view(
viewmode, headers, content, limit, is_request
)
except ContentViewException:
s = "Content viewer failed: \n" + traceback.format_exc()
signals.add_event(s, "error")
- msg, view = contentview.get_content_view(
+ description, lines = contentview.get_content_view(
viewmode, headers, content, limit, is_request
)
- msg = msg.replace("Raw", "Couldn't parse: falling back to Raw")
- return msg, view
+ description = description.replace("Raw", "Couldn't parse: falling back to Raw")
+ text_objects = [urwid.Text(l) for l in lines]
+ return description, text_objects
def viewmode_get(self):
override = self.state.get_flow_setting(
diff --git a/libmproxy/contentview.py b/libmproxy/contentview.py
index 1b41066b..219adfb7 100644
--- a/libmproxy/contentview.py
+++ b/libmproxy/contentview.py
@@ -3,21 +3,23 @@ import cStringIO
import json
import logging
import subprocess
+import sys
import lxml.html
import lxml.etree
from PIL import Image
+
from PIL.ExifTags import TAGS
import html2text
import six
-import sys
-from libmproxy.exceptions import ContentViewException
+from netlib.odict import ODict
+from netlib import encoding
import netlib.utils
from . import utils
+from .exceptions import ContentViewException
from .contrib import jsbeautifier
from .contrib.wbxml.ASCommandResponse import ASCommandResponse
-from netlib import encoding
try:
import pyamf
@@ -53,10 +55,10 @@ def format_dict(d):
for key, value in d.items():
key += ":"
key = key.ljust(max_key_len + 2)
- yield (
+ yield [
("header", key),
("text", value)
- )
+ ]
def format_text(content, limit):
@@ -66,7 +68,7 @@ def format_text(content, limit):
content = netlib.utils.cleanBin(content)
for line in content[:limit].splitlines():
- yield ("text", line)
+ yield [("text", line)]
for msg in trailer(content, limit):
yield msg
@@ -75,10 +77,9 @@ def format_text(content, limit):
def trailer(content, limit):
bytes_removed = len(content) - limit
if bytes_removed > 0:
- yield (
- "cutoff",
- "... {} of data not shown.".format(netlib.utils.pretty_size(bytes_removed))
- )
+ yield [
+ ("cutoff", "... {} of data not shown.".format(netlib.utils.pretty_size(bytes_removed)))
+ ]
class View(object):
@@ -89,7 +90,10 @@ class View(object):
def __call__(self, hdrs, content, limit):
"""
Returns:
- A (mode name, content generator) tuple.
+ A (description, content generator) tuple.
+
+ The content generator yields lists of (style, text) tuples.
+ Iit must not yield tuples of tuples, because urwid cannot process that.
"""
raise NotImplementedError()
@@ -128,11 +132,11 @@ class ViewHex(View):
@staticmethod
def _format(content, limit):
for offset, hexa, s in netlib.utils.hexdump(content[:limit]):
- yield (
+ yield [
("offset", offset + " "),
("text", hexa + " "),
- ("text", s),
- )
+ ("text", s)
+ ]
for msg in trailer(content, limit):
yield msg
@@ -189,7 +193,8 @@ class ViewJSON(View):
def __call__(self, hdrs, content, limit):
pretty_json = utils.pretty_json(content)
- return "JSON", format_text(pretty_json, limit)
+ if pretty_json:
+ return "JSON", format_text(pretty_json, limit)
class ViewHTML(View):
@@ -234,7 +239,7 @@ class ViewURLEncoded(View):
def __call__(self, hdrs, content, limit):
d = netlib.utils.urldecode(content)
- return "URLEncoded form", format_dict(d)
+ return "URLEncoded form", format_dict(ODict(d))
class ViewMultipart(View):
@@ -244,8 +249,8 @@ class ViewMultipart(View):
@staticmethod
def _format(v):
- yield (("highlight", "Form data:\n"))
- for message in format_dict({key:val for key,val in v}):
+ yield [("highlight", "Form data:\n")]
+ for message in format_dict(ODict(v)):
yield message
def __call__(self, hdrs, content, limit):
@@ -306,15 +311,15 @@ if pyamf:
def _format(self, envelope, limit):
for target, message in iter(envelope):
if isinstance(message, pyamf.remoting.Request):
- yield (
+ yield [
("header", "Request: "),
("text", str(target)),
- )
+ ]
else:
- yield (
+ yield [
("header", "Response: "),
("text", "%s, code %s" % (target, message.status)),
- )
+ ]
s = json.dumps(self.unpack(message), indent=4)
for msg in format_text(s, limit):
@@ -322,10 +327,8 @@ if pyamf:
def __call__(self, hdrs, content, limit):
envelope = remoting.decode(content, strict=False)
- if not envelope:
- return None
-
- return "AMF v%s" % envelope.amfVersion, self._format(envelope, limit)
+ if envelope:
+ return "AMF v%s" % envelope.amfVersion, self._format(envelope, limit)
class ViewJavaScript(View):
@@ -401,7 +404,7 @@ class ViewImage(View):
clean.append(
[netlib.utils.cleanBin(i[0]), netlib.utils.cleanBin(i[1])]
)
- fmt = format_dict({k:v for k,v in clean})
+ fmt = format_dict(ODict(clean))
return "%s image" % img.format, fmt
@@ -460,7 +463,8 @@ class ViewWBXML(View):
try:
parser = ASCommandResponse(content)
parsedContent = parser.xmlString
- return "WBXML", format_text(parsedContent, limit)
+ if parsedContent:
+ return "WBXML", format_text(parsedContent, limit)
except:
return None
@@ -510,16 +514,16 @@ def get(name):
def get_content_view(viewmode, headers, content, limit, is_request):
"""
Returns:
- A (msg, body) tuple.
+ A (description, content generator) tuple.
Raises:
ContentViewException, if the content view threw an error.
"""
if not content:
if is_request:
- return "No request content (press tab to view response)", ""
+ return "No request content (press tab to view response)", []
else:
- return "No content", ""
+ return "No content", []
msg = []
enc = headers.get("content-encoding")
diff --git a/libmproxy/contrib/wbxml/ASCommandResponse.py b/libmproxy/contrib/wbxml/ASCommandResponse.py
index 7bd31409..08d03445 100644
--- a/libmproxy/contrib/wbxml/ASCommandResponse.py
+++ b/libmproxy/contrib/wbxml/ASCommandResponse.py
@@ -38,10 +38,10 @@ class ASCommandResponse:
if ( len(response) > 0):
self.xmlString = self.decodeWBXML(self.wbxmlBody)
else:
- logging.error("Empty WBXML body passed")
+ raise ValueError("Empty WBXML body passed")
except Exception as e:
- logging.error("Error: {0}".format(e.message))
self.xmlString = None
+ raise ValueError("Error: {0}".format(e.message))
def getWBXMLBytes(self):
return self.wbxmlBytes
@@ -70,4 +70,3 @@ if __name__ == "__main__":
logging.info("-"*100)
instance = ASCommandResponse(byteWBXML)
logging.info(instance.xmlString)
- \ No newline at end of file
diff --git a/libmproxy/utils.py b/libmproxy/utils.py
index a6ca55f7..4b591250 100644
--- a/libmproxy/utils.py
+++ b/libmproxy/utils.py
@@ -54,7 +54,7 @@ def pretty_json(s):
p = json.loads(s)
except ValueError:
return None
- return json.dumps(p, sort_keys=True, indent=4).split("\n")
+ return json.dumps(p, sort_keys=True, indent=4)
def pretty_duration(secs):
diff --git a/test/test_console_contentview.py b/test/test_console_contentview.py
index d44a3cf4..ec1b4930 100644
--- a/test/test_console_contentview.py
+++ b/test/test_console_contentview.py
@@ -1,16 +1,12 @@
-import os
-from nose.plugins.skip import SkipTest
+from libmproxy.exceptions import ContentViewException
from netlib.http import Headers
-if os.name == "nt":
- raise SkipTest("Skipped on Windows.")
import sys
import netlib.utils
from netlib import encoding
import libmproxy.contentview as cv
-from libmproxy import utils, flow
import tutils
try:
@@ -26,11 +22,11 @@ except:
class TestContentView:
def test_trailer(self):
- txt = []
- cv.trailer(5, txt, 1000)
- assert not txt
- cv.trailer(cv.VIEW_CUTOFF + 10, txt, cv.VIEW_CUTOFF)
- assert txt
+ txt = "X"*10
+ lines = cv.trailer(txt, 1000)
+ assert not list(lines)
+ lines = cv.trailer(txt, 5)
+ assert list(lines)
def test_view_auto(self):
v = cv.ViewAuto()
@@ -124,16 +120,16 @@ class TestContentView:
result = v([], 'a', 100)
if cssutils:
- assert len(result[1]) == 0
+ assert len(list(result[1])) == 0
else:
- assert len(result[1]) == 1
+ assert len(list(result[1])) == 1
result = v([], fixture_1, 100)
if cssutils:
- assert len(result[1]) > 1
+ assert len(list(result[1])) > 1
else:
- assert len(result[1]) == 1
+ assert len(list(result[1])) == 1
def test_view_hex(self):
v = cv.ViewHex()
@@ -204,14 +200,15 @@ Larry
)
assert "Raw" in r[0]
- r = cv.get_content_view(
+ tutils.raises(
+ ContentViewException,
+ cv.get_content_view,
cv.get("AMF"),
Headers(),
"[1, 2",
1000,
False
)
- assert "Raw" in r[0]
r = cv.get_content_view(
cv.get("Auto"),