aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mitmproxy/contrib/tnetstring.py14
-rw-r--r--mitmproxy/flow/io.py7
-rw-r--r--mitmproxy/flow/io_compat.py76
-rw-r--r--mitmproxy/models/connections.py2
-rw-r--r--test/mitmproxy/test_contrib_tnetstring.py8
5 files changed, 66 insertions, 41 deletions
diff --git a/mitmproxy/contrib/tnetstring.py b/mitmproxy/contrib/tnetstring.py
index 5fc26b45..0383f98e 100644
--- a/mitmproxy/contrib/tnetstring.py
+++ b/mitmproxy/contrib/tnetstring.py
@@ -96,7 +96,7 @@ def _rdumpq(q, size, value):
elif value is False:
write(b'5:false!')
return size + 8
- elif isinstance(value, int):
+ elif isinstance(value, six.integer_types):
data = str(value).encode()
ldata = len(data)
span = str(ldata).encode()
@@ -119,7 +119,7 @@ def _rdumpq(q, size, value):
write(b'%s:%s,' % (span, data))
return size + 2 + len(span) + ldata
elif isinstance(value, six.text_type):
- data = value.encode()
+ data = value.encode("utf8")
ldata = len(data)
span = str(ldata).encode()
write(b'%s:%s;' % (span, data))
@@ -137,8 +137,6 @@ def _rdumpq(q, size, value):
write(b'}')
init_size = size = size + 1
for (k, v) in value.items():
- if isinstance(k, str):
- k = k.encode("ascii", "strict")
size = _rdumpq(q, size, v)
size = _rdumpq(q, size, k)
span = str(size - init_size).encode()
@@ -184,13 +182,17 @@ def load(file_handle):
def parse(data_type, data):
+ if six.PY2:
+ data_type = ord(data_type)
# type: (int, bytes) -> TSerializable
if data_type == ord(b','):
return data
if data_type == ord(b';'):
- return data.decode()
+ return data.decode("utf8")
if data_type == ord(b'#'):
try:
+ if six.PY2:
+ return long(data)
return int(data)
except ValueError:
raise ValueError("not a tnetstring: invalid integer literal: {}".format(data))
@@ -220,8 +222,6 @@ def parse(data_type, data):
d = {}
while data:
key, data = pop(data)
- if isinstance(key, bytes):
- key = key.decode("ascii", "strict")
val, data = pop(data)
d[key] = val
return d
diff --git a/mitmproxy/flow/io.py b/mitmproxy/flow/io.py
index e5716940..276d7a5b 100644
--- a/mitmproxy/flow/io.py
+++ b/mitmproxy/flow/io.py
@@ -44,10 +44,9 @@ class FlowReader:
raise exceptions.FlowReadException(str(e))
if can_tell:
off = self.fo.tell()
- data_type = data["type"].decode()
- if data_type not in models.FLOW_TYPES:
- raise exceptions.FlowReadException("Unknown flow type: {}".format(data_type))
- yield models.FLOW_TYPES[data_type].from_state(data)
+ if data["type"] not in models.FLOW_TYPES:
+ raise exceptions.FlowReadException("Unknown flow type: {}".format(data["type"]))
+ yield models.FLOW_TYPES[data["type"]].from_state(data)
except ValueError:
# Error is due to EOF
if can_tell and self.fo.tell() == off and self.fo.read() == b'':
diff --git a/mitmproxy/flow/io_compat.py b/mitmproxy/flow/io_compat.py
index 55971f5e..1e67dde4 100644
--- a/mitmproxy/flow/io_compat.py
+++ b/mitmproxy/flow/io_compat.py
@@ -3,44 +3,74 @@ This module handles the import of mitmproxy flows generated by old versions.
"""
from __future__ import absolute_import, print_function, division
+import six
+
from netlib import version
def convert_013_014(data):
- data["request"]["first_line_format"] = data["request"].pop("form_in")
- data["request"]["http_version"] = "HTTP/" + ".".join(str(x) for x in data["request"].pop("httpversion"))
- data["response"]["http_version"] = "HTTP/" + ".".join(str(x) for x in data["response"].pop("httpversion"))
- data["response"]["status_code"] = data["response"].pop("code")
- data["response"]["body"] = data["response"].pop("content")
- data["server_conn"].pop("state")
- data["server_conn"]["via"] = None
- data["version"] = (0, 14)
+ data[b"request"][b"first_line_format"] = data[b"request"].pop(b"form_in")
+ data[b"request"][b"http_version"] = b"HTTP/" + ".".join(str(x) for x in data[b"request"].pop(b"httpversion")).encode()
+ data[b"response"][b"http_version"] = b"HTTP/" + ".".join(str(x) for x in data[b"response"].pop(b"httpversion")).encode()
+ data[b"response"][b"status_code"] = data[b"response"].pop(b"code")
+ data[b"response"][b"body"] = data[b"response"].pop(b"content")
+ data[b"server_conn"].pop(b"state")
+ data[b"server_conn"][b"via"] = None
+ data[b"version"] = (0, 14)
return data
def convert_014_015(data):
- data["version"] = (0, 15)
+ data[b"version"] = (0, 15)
return data
def convert_015_016(data):
- for m in ("request", "response"):
- if "body" in data[m]:
- data[m]["content"] = data[m].pop("body")
- if "msg" in data["response"]:
- data["response"]["reason"] = data["response"].pop("msg")
- data["request"].pop("form_out", None)
- data["version"] = (0, 16)
+ for m in (b"request", b"response"):
+ if b"body" in data[m]:
+ data[m][b"content"] = data[m].pop(b"body")
+ if b"msg" in data[b"response"]:
+ data[b"response"][b"reason"] = data[b"response"].pop(b"msg")
+ data[b"request"].pop(b"form_out", None)
+ data[b"version"] = (0, 16)
return data
def convert_016_017(data):
- data["server_conn"]["peer_address"] = None
- data["version"] = (0, 17)
+ data[b"server_conn"][b"peer_address"] = None
+ data[b"version"] = (0, 17)
return data
def convert_017_018(data):
+ if not six.PY2:
+ # Python 2 versions of mitmproxy did not support serializing unicode.
+ def dict_keys_to_str(o):
+ if isinstance(o, dict):
+ return {k.decode(): dict_keys_to_str(v) for k, v in o.items()}
+ else:
+ return o
+ data = dict_keys_to_str(data)
+
+ def dict_vals_to_str(o, decode):
+ for k, v in decode.items():
+ if not o or k not in o:
+ continue
+ if v is True:
+ o[k] = o[k].decode()
+ else:
+ dict_vals_to_str(o[k], v)
+ dict_vals_to_str(data, {
+ "type": True,
+ "id": True,
+ "request": {
+ "first_line_format": True
+ },
+ "error": {
+ "msg": True
+ }
+ })
+
data["server_conn"]["ip_address"] = data["server_conn"].pop("peer_address")
data["version"] = (0, 18)
return data
@@ -57,13 +87,13 @@ converters = {
def migrate_flow(flow_data):
while True:
- flow_version = tuple(flow_data["version"][:2])
- if flow_version == version.IVERSION[:2]:
+ flow_version = tuple(flow_data.get(b"version", flow_data.get("version")))
+ if flow_version[:2] == version.IVERSION[:2]:
break
- elif flow_version in converters:
- flow_data = converters[flow_version](flow_data)
+ elif flow_version[:2] in converters:
+ flow_data = converters[flow_version[:2]](flow_data)
else:
- v = ".".join(str(i) for i in flow_data["version"])
+ v = ".".join(str(i) for i in flow_version)
raise ValueError(
"{} cannot read files serialized with version {}.".format(version.MITMPROXY, v)
)
diff --git a/mitmproxy/models/connections.py b/mitmproxy/models/connections.py
index d71379bc..3e1a0928 100644
--- a/mitmproxy/models/connections.py
+++ b/mitmproxy/models/connections.py
@@ -162,7 +162,7 @@ class ServerConnection(tcp.TCPClient, stateobject.StateObject):
source_address=tcp.Address,
ssl_established=bool,
cert=certutils.SSLCert,
- sni=str,
+ sni=bytes,
timestamp_start=float,
timestamp_tcp_setup=float,
timestamp_ssl_setup=float,
diff --git a/test/mitmproxy/test_contrib_tnetstring.py b/test/mitmproxy/test_contrib_tnetstring.py
index 8ae35a25..908cec27 100644
--- a/test/mitmproxy/test_contrib_tnetstring.py
+++ b/test/mitmproxy/test_contrib_tnetstring.py
@@ -15,7 +15,9 @@ FORMAT_EXAMPLES = {
{'hello': [12345678901, b'this', True, None, b'\x00\x00\x00\x00']},
b'5:12345#': 12345,
b'12:this is cool,': b'this is cool',
+ b'19:this is unicode \xe2\x98\x85;': u'this is unicode \u2605',
b'0:,': b'',
+ b'0:;': u'',
b'0:~': None,
b'4:true!': True,
b'5:false!': False,
@@ -78,12 +80,6 @@ class Test_Format(unittest.TestCase):
self.assertEqual(v, tnetstring.loads(tnetstring.dumps(v)))
self.assertEqual((v, b""), tnetstring.pop(tnetstring.dumps(v)))
- def test_unicode_handling(self):
- with self.assertRaises(ValueError):
- tnetstring.dumps(u"hello")
- self.assertEqual(tnetstring.dumps(u"hello".encode()), b"5:hello,")
- self.assertEqual(type(tnetstring.loads(b"5:hello,")), bytes)
-
def test_roundtrip_format_unicode(self):
for _ in range(500):
v = get_random_object()