mirror of
https://github.com/Grasscutters/mitmproxy.git
synced 2024-11-26 18:18:25 +00:00
several fixes on command exports has several problems: #3676
* authority can usually rely on actual URL. as `:authority` headers will break curl command. (advise if it's better to change them to Host, or if it should be reported on curl side) * `content-length`: 0 is added for each request. if it's found in the curl argument list, it'll try to fetch an empty body (and crash). also trying to guess on accept-encoding header to add the `--compress` option when fetching potentially compressed content. * ditto for httpie
This commit is contained in:
parent
eb7ed1dc40
commit
3370740361
@ -11,6 +11,15 @@ import mitmproxy.types
|
|||||||
import pyperclip
|
import pyperclip
|
||||||
|
|
||||||
|
|
||||||
|
def cleanup_for_commands(request):
|
||||||
|
if ('content-length' in request.headers.keys() and
|
||||||
|
request.headers['content-length'] == '0' and
|
||||||
|
request.method == 'GET'):
|
||||||
|
request.headers.pop('content-length')
|
||||||
|
request.headers.pop(':authority', None)
|
||||||
|
return request
|
||||||
|
|
||||||
|
|
||||||
def raise_if_missing_request(f: flow.Flow) -> None:
|
def raise_if_missing_request(f: flow.Flow) -> None:
|
||||||
if not hasattr(f, "request"):
|
if not hasattr(f, "request"):
|
||||||
raise exceptions.CommandError("Can't export flow with no request.")
|
raise exceptions.CommandError("Can't export flow with no request.")
|
||||||
@ -21,10 +30,15 @@ def curl_command(f: flow.Flow) -> str:
|
|||||||
data = "curl "
|
data = "curl "
|
||||||
request = f.request.copy() # type: ignore
|
request = f.request.copy() # type: ignore
|
||||||
request.decode(strict=False)
|
request.decode(strict=False)
|
||||||
|
request = cleanup_for_commands(request)
|
||||||
for k, v in request.headers.items(multi=True):
|
for k, v in request.headers.items(multi=True):
|
||||||
data += "-H '%s:%s' " % (k, v)
|
data += "-H '%s:%s' " % (k, v)
|
||||||
if request.method != "GET":
|
if request.method != "GET":
|
||||||
data += "-X %s " % request.method
|
data += "-X %s " % request.method
|
||||||
|
for header in request.headers.keys():
|
||||||
|
if ('accept-encoding' == header.lower() and
|
||||||
|
any(comp in request.headers[header] for comp in ['gzip', 'deflate'])):
|
||||||
|
data += "--compressed "
|
||||||
data += "'%s'" % request.url
|
data += "'%s'" % request.url
|
||||||
if request.content:
|
if request.content:
|
||||||
data += " --data-binary '%s'" % strutils.bytes_to_escaped_str(
|
data += " --data-binary '%s'" % strutils.bytes_to_escaped_str(
|
||||||
@ -39,6 +53,7 @@ def httpie_command(f: flow.Flow) -> str:
|
|||||||
request = f.request.copy() # type: ignore
|
request = f.request.copy() # type: ignore
|
||||||
data = "http %s " % request.method
|
data = "http %s " % request.method
|
||||||
request.decode(strict=False)
|
request.decode(strict=False)
|
||||||
|
request = cleanup_for_commands(request)
|
||||||
data += "%s" % request.url
|
data += "%s" % request.url
|
||||||
for k, v in request.headers.items(multi=True):
|
for k, v in request.headers.items(multi=True):
|
||||||
data += " '%s:%s'" % (k, v)
|
data += " '%s:%s'" % (k, v)
|
||||||
|
@ -14,29 +14,23 @@ from unittest import mock
|
|||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def get_request():
|
def get_request():
|
||||||
return tflow.tflow(
|
return tflow.tflow(
|
||||||
req=tutils.treq(
|
req=tutils.treq(method=b'GET', content=b'', path=b"/path?a=foo&a=bar&b=baz"))
|
||||||
method=b'GET',
|
|
||||||
content=b'',
|
|
||||||
path=b"/path?a=foo&a=bar&b=baz"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def post_request():
|
def post_request():
|
||||||
return tflow.tflow(
|
return tflow.tflow(
|
||||||
req=tutils.treq(
|
req=tutils.treq(method=b'POST', headers=(), content=bytes(range(256))))
|
||||||
method=b'POST',
|
|
||||||
headers=(),
|
|
||||||
content=bytes(range(256))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def patch_request():
|
def patch_request():
|
||||||
return tflow.tflow(
|
return tflow.tflow(
|
||||||
req=tutils.treq(method=b'PATCH', path=b"/path?query=param")
|
req=tutils.treq(
|
||||||
|
method=b'PATCH',
|
||||||
|
content=b'content',
|
||||||
|
path=b"/path?query=param"
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -47,7 +41,7 @@ def tcp_flow():
|
|||||||
|
|
||||||
class TestExportCurlCommand:
|
class TestExportCurlCommand:
|
||||||
def test_get(self, get_request):
|
def test_get(self, get_request):
|
||||||
result = """curl -H 'header:qvalue' -H 'content-length:0' 'http://address:22/path?a=foo&a=bar&b=baz'"""
|
result = """curl -H 'header:qvalue' 'http://address:22/path?a=foo&a=bar&b=baz'"""
|
||||||
assert export.curl_command(get_request) == result
|
assert export.curl_command(get_request) == result
|
||||||
|
|
||||||
def test_post(self, post_request):
|
def test_post(self, post_request):
|
||||||
@ -67,7 +61,7 @@ class TestExportCurlCommand:
|
|||||||
|
|
||||||
class TestExportHttpieCommand:
|
class TestExportHttpieCommand:
|
||||||
def test_get(self, get_request):
|
def test_get(self, get_request):
|
||||||
result = """http GET http://address:22/path?a=foo&a=bar&b=baz 'header:qvalue' 'content-length:0'"""
|
result = """http GET http://address:22/path?a=foo&a=bar&b=baz 'header:qvalue'"""
|
||||||
assert export.httpie_command(get_request) == result
|
assert export.httpie_command(get_request) == result
|
||||||
|
|
||||||
def test_post(self, post_request):
|
def test_post(self, post_request):
|
||||||
|
Loading…
Reference in New Issue
Block a user