1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
"""
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, strutils
def convert_013_014(data):
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[b"version"] = (0, 15)
return data
def convert_015_016(data):
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[b"server_conn"][b"peer_address"] = None
data[b"version"] = (0, 17)
return data
def convert_017_018(data):
# convert_unicode needs to be called for every dual release and the first py3-only release
data = convert_unicode(data)
data["server_conn"]["ip_address"] = data["server_conn"].pop("peer_address")
data["version"] = (0, 18)
return data
def _convert_dict_keys(o):
# type: (Any) -> Any
if isinstance(o, dict):
return {strutils.native(k): _convert_dict_keys(v) for k, v in o.items()}
else:
return o
def _convert_dict_vals(o, values_to_convert):
# type: (dict, dict) -> dict
for k, v in values_to_convert.items():
if not o or k not in o:
continue
if v is True:
o[k] = strutils.native(o[k])
else:
_convert_dict_vals(o[k], v)
return o
def convert_unicode(data):
# type: (dict) -> dict
"""
The Python 2 version of mitmproxy serializes everything as bytes.
This method converts between Python 3 and Python 2 dumpfiles.
"""
if not six.PY2:
data = _convert_dict_keys(data)
data = _convert_dict_vals(
data, {
"type": True,
"id": True,
"request": {
"first_line_format": True
},
"error": {
"msg": True
}
}
)
return data
converters = {
(0, 13): convert_013_014,
(0, 14): convert_014_015,
(0, 15): convert_015_016,
(0, 16): convert_016_017,
(0, 17): convert_017_018,
}
def migrate_flow(flow_data):
while True:
flow_version = tuple(flow_data.get(b"version", flow_data.get("version")))
if flow_version[:2] == version.IVERSION[:2]:
break
elif flow_version[:2] in converters:
flow_data = converters[flow_version[:2]](flow_data)
else:
v = ".".join(str(i) for i in flow_version)
raise ValueError(
"{} cannot read files serialized with version {}.".format(version.MITMPROXY, v)
)
# TODO: This should finally be moved in the converter for the first py3-only release.
# It's here so that a py2 0.18 dump can be read by py3 0.18 and vice versa.
flow_data = convert_unicode(flow_data)
return flow_data
|