aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mitmproxy/mitmproxy/console/flowview.py5
-rw-r--r--mitmproxy/mitmproxy/contentviews.py27
-rw-r--r--test/mitmproxy/test_contentview.py21
3 files changed, 47 insertions, 6 deletions
diff --git a/mitmproxy/mitmproxy/console/flowview.py b/mitmproxy/mitmproxy/console/flowview.py
index d2b98b68..f490732e 100644
--- a/mitmproxy/mitmproxy/console/flowview.py
+++ b/mitmproxy/mitmproxy/console/flowview.py
@@ -193,8 +193,11 @@ class FlowView(tabs.Tabs):
def _get_content_view(self, viewmode, message, max_lines, _):
try:
+ query = None
+ if isinstance(message, HTTPRequest):
+ query = message.query
description, lines = contentviews.get_content_view(
- viewmode, message.content, headers=message.headers
+ viewmode, message.content, headers=message.headers, query=query
)
except ContentViewException:
s = "Content viewer failed: \n" + traceback.format_exc()
diff --git a/mitmproxy/mitmproxy/contentviews.py b/mitmproxy/mitmproxy/contentviews.py
index c0652c18..5335b59c 100644
--- a/mitmproxy/mitmproxy/contentviews.py
+++ b/mitmproxy/mitmproxy/contentviews.py
@@ -8,7 +8,8 @@ in the future, e.g. to decode protobuf messages sent as WebSocket frames.
Thus, the View API is very minimalistic. The only arguments are `data` and `**metadata`,
where `data` is the actual content (as bytes). The contents on metadata depend on the protocol in
-use. For HTTP, the message headers are passed as the ``headers`` keyword argument.
+use. For HTTP, the message headers are passed as the ``headers`` keyword argument. For HTTP
+requests, the query parameters are passed as the ``query`` keyword argument.
"""
from __future__ import (absolute_import, print_function, division)
@@ -118,15 +119,19 @@ class ViewAuto(View):
def __call__(self, data, **metadata):
headers = metadata.get("headers", {})
ctype = headers.get("content-type")
- if ctype:
+ if data and ctype:
ct = parse_content_type(ctype) if ctype else None
ct = "%s/%s" % (ct[0], ct[1])
if ct in content_types_map:
return content_types_map[ct][0](data, **metadata)
elif utils.isXML(data):
return get("XML")(data, **metadata)
- if utils.isMostlyBin(data):
+ if metadata.get("query"):
+ return get("Query")(data, **metadata)
+ if data and utils.isMostlyBin(data):
return get("Hex")(data)
+ if not data:
+ return "No content", []
return get("Raw")(data)
@@ -460,6 +465,19 @@ class ViewProtobuf(View):
return "Protobuf", format_text(decoded)
+class ViewQuery(View):
+ name = "Query"
+ prompt = ("query", "q")
+ content_types = []
+
+ def __call__(self, data, **metadata):
+ query = metadata.get("query")
+ if query:
+ return "Query", format_dict(query)
+ else:
+ return "Query", format_text("")
+
+
class ViewWBXML(View):
name = "WBXML"
prompt = ("wbxml", "w")
@@ -541,6 +559,7 @@ add(ViewCSS())
add(ViewURLEncoded())
add(ViewMultipart())
add(ViewImage())
+add(ViewQuery())
if pyamf:
add(ViewAMF())
@@ -577,8 +596,6 @@ def get_content_view(viewmode, data, **metadata):
Raises:
ContentViewException, if the content view threw an error.
"""
- if not data:
- return "No content", []
msg = []
headers = metadata.get("headers", {})
diff --git a/test/mitmproxy/test_contentview.py b/test/mitmproxy/test_contentview.py
index 7f1d735e..c00afa5f 100644
--- a/test/mitmproxy/test_contentview.py
+++ b/test/mitmproxy/test_contentview.py
@@ -1,5 +1,6 @@
from mitmproxy.exceptions import ContentViewException
from netlib.http import Headers
+from netlib.odict import ODict
import netlib.utils
from netlib import encoding
@@ -45,6 +46,19 @@ class TestContentView:
)
assert f[0].startswith("XML")
+ f = v(
+ "",
+ headers=Headers()
+ )
+ assert f[0] == "No content"
+
+ f = v(
+ "",
+ headers=Headers(),
+ query=ODict([("foo", "bar")]),
+ )
+ assert f[0] == "Query"
+
def test_view_urlencoded(self):
d = netlib.utils.urlencode([("one", "two"), ("three", "four")])
v = cv.ViewURLEncoded()
@@ -158,6 +172,13 @@ Larry
h = Headers(content_type="unparseable")
assert not view(v, headers=h)
+ def test_view_query(self):
+ d = ""
+ v = cv.ViewQuery()
+ f = v(d, query=ODict([("foo", "bar")]))
+ assert f[0] == "Query"
+ assert [x for x in f[1]] == [[("header", "foo: "), ("text", "bar")]]
+
def test_get_content_view(self):
r = cv.get_content_view(
cv.get("Raw"),