From ac252064208b65381b2c2a68e373538c3b2130ce Mon Sep 17 00:00:00 2001 From: Shadab Zafar Date: Sun, 21 Feb 2016 20:44:03 +0530 Subject: Indent JSON body while exporting it as code Fixes #968 --- mitmproxy/flow_export.py | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/mitmproxy/flow_export.py b/mitmproxy/flow_export.py index 52145516..97d5f403 100644 --- a/mitmproxy/flow_export.py +++ b/mitmproxy/flow_export.py @@ -1,7 +1,25 @@ import urllib -import netlib.http from textwrap import dedent +import netlib.http +from . import contentviews + + +def prettify(data, headers=None): + if not headers: + return data + + cv = contentviews.get_content_view( + contentviews.get("Auto"), + data, + headers=headers, + ) + + if cv[0] == "JSON": + return "\n".join(l[0][1] for l in cv[1]) + else: + return data + def curl_command(flow): data = "curl " @@ -53,7 +71,7 @@ def python_code(flow): data = "" if flow.request.body: - data = "\ndata = '''%s'''\n" % flow.request.body + data = "\ndata = '''%s'''\n" % prettify(flow.request.body, flow.request.headers) args += "\n data=data," code = code.format( -- cgit v1.2.3 From 1548185a17a824273f28a9a20298b2f4a8df4569 Mon Sep 17 00:00:00 2001 From: Shadab Zafar Date: Tue, 1 Mar 2016 18:38:55 +0530 Subject: Use requests' json parameter --- mitmproxy/flow_export.py | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/mitmproxy/flow_export.py b/mitmproxy/flow_export.py index 97d5f403..b3bef62f 100644 --- a/mitmproxy/flow_export.py +++ b/mitmproxy/flow_export.py @@ -5,22 +5,6 @@ import netlib.http from . import contentviews -def prettify(data, headers=None): - if not headers: - return data - - cv = contentviews.get_content_view( - contentviews.get("Auto"), - data, - headers=headers, - ) - - if cv[0] == "JSON": - return "\n".join(l[0][1] for l in cv[1]) - else: - return data - - def curl_command(flow): data = "curl " @@ -71,8 +55,18 @@ def python_code(flow): data = "" if flow.request.body: - data = "\ndata = '''%s'''\n" % prettify(flow.request.body, flow.request.headers) - args += "\n data=data," + cv = contentviews.get_content_view( + viewmode=contentviews.get("Auto"), + data=flow.request.body, + headers=flow.request.headers, + ) + + if cv[0] == "JSON": + data = "\njson = %s\n" % "\n".join(l[0][1] for l in cv[1]) + args += "\n json=json," + else: + data = "\ndata = '''%s'''\n" % flow.request.body + args += "\n data=data," code = code.format( url=url, -- cgit v1.2.3 From ec61cfddfd284a13d7bcf2807ba2e95c1a7f1d51 Mon Sep 17 00:00:00 2001 From: Shadab Zafar Date: Thu, 3 Mar 2016 06:41:26 +0530 Subject: Use json instead of contentviews --- mitmproxy/flow_export.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/mitmproxy/flow_export.py b/mitmproxy/flow_export.py index b3bef62f..f5b3e2ec 100644 --- a/mitmproxy/flow_export.py +++ b/mitmproxy/flow_export.py @@ -1,8 +1,9 @@ +import json import urllib from textwrap import dedent import netlib.http -from . import contentviews +from netlib.utils import parse_content_type def curl_command(flow): @@ -55,14 +56,9 @@ def python_code(flow): data = "" if flow.request.body: - cv = contentviews.get_content_view( - viewmode=contentviews.get("Auto"), - data=flow.request.body, - headers=flow.request.headers, - ) - - if cv[0] == "JSON": - data = "\njson = %s\n" % "\n".join(l[0][1] for l in cv[1]) + if is_json(flow.request.headers): + data = json.dumps(json.loads(flow.request.body), indent=4) + data = "\njson = %s\n" % data args += "\n json=json," else: data = "\ndata = '''%s'''\n" % flow.request.body @@ -83,3 +79,10 @@ def python_code(flow): def raw_request(flow): data = netlib.http.http1.assemble_request(flow.request) return data + + +def is_json(headers): + if headers: + ct = parse_content_type(headers.get("content-type", "")) + return ct and "%s/%s" % (ct[0], ct[1]) == "application/json" + return False -- cgit v1.2.3 From 01a99f2b252c2a4b467d26c795173a026df6d4d7 Mon Sep 17 00:00:00 2001 From: Shadab Zafar Date: Fri, 4 Mar 2016 01:01:16 +0530 Subject: Handle the case of correct json content-type but malformed body --- mitmproxy/flow_export.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/mitmproxy/flow_export.py b/mitmproxy/flow_export.py index f5b3e2ec..49e2d704 100644 --- a/mitmproxy/flow_export.py +++ b/mitmproxy/flow_export.py @@ -56,8 +56,9 @@ def python_code(flow): data = "" if flow.request.body: - if is_json(flow.request.headers): - data = json.dumps(json.loads(flow.request.body), indent=4) + json_obj = is_json(flow.request.headers, flow.request.body) + if json_obj: + data = json.dumps(json_obj, indent=4) data = "\njson = %s\n" % data args += "\n json=json," else: @@ -81,8 +82,12 @@ def raw_request(flow): return data -def is_json(headers): +def is_json(headers, content): if headers: ct = parse_content_type(headers.get("content-type", "")) - return ct and "%s/%s" % (ct[0], ct[1]) == "application/json" + if ct and "%s/%s" % (ct[0], ct[1]) == "application/json": + try: + return json.loads(content) + except ValueError: + return False return False -- cgit v1.2.3 From 9540ede11222cf1e0d796d34b82481173405c520 Mon Sep 17 00:00:00 2001 From: Shadab Zafar Date: Fri, 4 Mar 2016 01:05:35 +0530 Subject: Use separators param in json.dumps() to avoid trailing whitespace --- mitmproxy/flow_export.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mitmproxy/flow_export.py b/mitmproxy/flow_export.py index 49e2d704..6333de57 100644 --- a/mitmproxy/flow_export.py +++ b/mitmproxy/flow_export.py @@ -58,7 +58,9 @@ def python_code(flow): if flow.request.body: json_obj = is_json(flow.request.headers, flow.request.body) if json_obj: - data = json.dumps(json_obj, indent=4) + # Without the separators field json.dumps() produces + # trailing white spaces: https://bugs.python.org/issue16333 + data = json.dumps(json_obj, indent=4, separators=(',', ': ')) data = "\njson = %s\n" % data args += "\n json=json," else: -- cgit v1.2.3 From 48f1c9afc2e5d02c8de717e2fc9030a7884d493b Mon Sep 17 00:00:00 2001 From: Shadab Zafar Date: Fri, 4 Mar 2016 01:06:09 +0530 Subject: Add a test for json request --- test/mitmproxy/test_flow_export.py | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/test/mitmproxy/test_flow_export.py b/test/mitmproxy/test_flow_export.py index 2dce3fd6..3dc07427 100644 --- a/test/mitmproxy/test_flow_export.py +++ b/test/mitmproxy/test_flow_export.py @@ -1,6 +1,8 @@ +import json from textwrap import dedent import netlib.tutils +from netlib.http import Headers from mitmproxy import flow_export from . import tutils @@ -81,6 +83,35 @@ class TestExportPythonCode(): """).strip() assert flow_export.python_code(flow) == result + def test_post_json(self): + req_post.content = '{"name": "example", "email": "example@example.com"}' + req_post.headers = Headers(content_type="application/json") + flow = tutils.tflow(req=req_post) + result = dedent(""" + import requests + + url = 'http://address/path' + + headers = { + 'content-type': 'application/json', + } + + json = { + "name": "example", + "email": "example@example.com" + } + + response = requests.request( + method='POST', + url=url, + headers=headers, + json=json, + ) + + print(response.text) + """).strip() + assert flow_export.python_code(flow) == result + def test_patch(self): flow = tutils.tflow(req=req_patch) result = dedent(""" -- cgit v1.2.3