aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAldo Cortesi <aldo@corte.si>2018-04-06 10:02:02 +1200
committerGitHub <noreply@github.com>2018-04-06 10:02:02 +1200
commit506ccc5693284a66ff186306509217282868e48b (patch)
tree744cbd80a7e355d51a1d02dedd79dce9d1da52be
parent4177f50a0fe177eb15e1adaf1d7941f3ae1dbdbc (diff)
parent29f41643442cd11f638fa14c1d9c297c083c7e8a (diff)
downloadmitmproxy-506ccc5693284a66ff186306509217282868e48b.tar.gz
mitmproxy-506ccc5693284a66ff186306509217282868e48b.tar.bz2
mitmproxy-506ccc5693284a66ff186306509217282868e48b.zip
Merge pull request #3031 from itzikBraun/add-httpie-export
added option to export request as httpie command
-rw-r--r--mitmproxy/addons/export.py26
-rw-r--r--test/mitmproxy/addons/test_export.py30
2 files changed, 52 insertions, 4 deletions
diff --git a/mitmproxy/addons/export.py b/mitmproxy/addons/export.py
index 4bb44548..f3300079 100644
--- a/mitmproxy/addons/export.py
+++ b/mitmproxy/addons/export.py
@@ -11,9 +11,13 @@ import mitmproxy.types
import pyperclip
-def curl_command(f: flow.Flow) -> str:
+def raise_if_missing_request(f: flow.Flow) -> None:
if not hasattr(f, "request"):
raise exceptions.CommandError("Can't export flow with no request.")
+
+
+def curl_command(f: flow.Flow) -> str:
+ raise_if_missing_request(f)
data = "curl "
request = f.request.copy() # type: ignore
request.decode(strict=False)
@@ -30,14 +34,30 @@ def curl_command(f: flow.Flow) -> str:
return data
+def httpie_command(f: flow.Flow) -> str:
+ raise_if_missing_request(f)
+ request = f.request.copy() # type: ignore
+ data = "http %s " % request.method
+ request.decode(strict=False)
+ data += "%s" % request.url
+ for k, v in request.headers.items(multi=True):
+ data += " '%s:%s'" % (k, v)
+ if request.content:
+ data += " <<< '%s'" % strutils.bytes_to_escaped_str(
+ request.content,
+ escape_single_quotes=True
+ )
+ return data
+
+
def raw(f: flow.Flow) -> bytes:
- if not hasattr(f, "request"):
- raise exceptions.CommandError("Can't export flow with no request.")
+ raise_if_missing_request(f)
return assemble.assemble_request(f.request) # type: ignore
formats = dict(
curl = curl_command,
+ httpie = httpie_command,
raw = raw,
)
diff --git a/test/mitmproxy/addons/test_export.py b/test/mitmproxy/addons/test_export.py
index 07227a7a..b625df56 100644
--- a/test/mitmproxy/addons/test_export.py
+++ b/test/mitmproxy/addons/test_export.py
@@ -65,6 +65,26 @@ class TestExportCurlCommand:
export.curl_command(tcp_flow)
+class TestExportHttpieCommand:
+ def test_get(self, get_request):
+ result = """http GET http://address:22/path?a=foo&a=bar&b=baz 'header:qvalue' 'content-length:0'"""
+ assert export.httpie_command(get_request) == result
+
+ def test_post(self, post_request):
+ result = "http POST http://address:22/path 'content-length:256' <<< '{}'".format(
+ str(bytes(range(256)))[2:-1]
+ )
+ assert export.httpie_command(post_request) == result
+
+ def test_patch(self, patch_request):
+ result = """http PATCH http://address:22/path?query=param 'header:qvalue' 'content-length:7' <<< 'content'"""
+ assert export.httpie_command(patch_request) == result
+
+ def test_tcp(self, tcp_flow):
+ with pytest.raises(exceptions.CommandError):
+ export.httpie_command(tcp_flow)
+
+
class TestRaw:
def test_get(self, get_request):
assert b"header: qvalue" in export.raw(get_request)
@@ -83,7 +103,7 @@ def test_export(tmpdir):
f = str(tmpdir.join("path"))
e = export.Export()
with taddons.context():
- assert e.formats() == ["curl", "raw"]
+ assert e.formats() == ["curl", "httpie", "raw"]
with pytest.raises(exceptions.CommandError):
e.file("nonexistent", tflow.tflow(resp=True), f)
@@ -95,6 +115,10 @@ def test_export(tmpdir):
assert qr(f)
os.unlink(f)
+ e.file("httpie", tflow.tflow(resp=True), f)
+ assert qr(f)
+ os.unlink(f)
+
@pytest.mark.parametrize("exception, log_message", [
(PermissionError, "Permission denied"),
@@ -126,6 +150,10 @@ def test_clip(tmpdir):
assert pc.called
with mock.patch('pyperclip.copy') as pc:
+ e.clip("httpie", tflow.tflow(resp=True))
+ assert pc.called
+
+ with mock.patch('pyperclip.copy') as pc:
log_message = "Pyperclip could not find a " \
"copy/paste mechanism for your system."
pc.side_effect = pyperclip.PyperclipException(log_message)