diff --git a/libmproxy/flow.py b/libmproxy/flow.py index 93bb6ab06..a2b069edc 100644 --- a/libmproxy/flow.py +++ b/libmproxy/flow.py @@ -13,7 +13,7 @@ import urlparse from netlib import wsgi from netlib.exceptions import HttpException from netlib.http import CONTENT_MISSING, Headers, http1 -from . import controller, tnetstring, filt, script, version +from . import controller, tnetstring, filt, script, version, flow_format_compat from .onboarding import app from .proxy.config import HostMatcher from .protocol.http_replay import RequestReplayThread @@ -1112,14 +1112,13 @@ class FlowReader: try: while True: data = tnetstring.load(self.fo) - if tuple(data["version"][:2]) != version.IVERSION[:2]: - v = ".".join(str(i) for i in data["version"]) - raise FlowReadError( - "Incompatible serialized data version: %s" % v - ) + try: + data = flow_format_compat.migrate_flow(data) + except ValueError as e: + raise FlowReadError(str(e)) off = self.fo.tell() yield HTTPFlow.from_state(data) - except ValueError as v: + except ValueError: # Error is due to EOF if self.fo.tell() == off and self.fo.read() == '': return diff --git a/libmproxy/flow_format_compat.py b/libmproxy/flow_format_compat.py new file mode 100644 index 000000000..02fa41a32 --- /dev/null +++ b/libmproxy/flow_format_compat.py @@ -0,0 +1,33 @@ +""" +This module handles the import of mitmproxy flows generated by old versions. +""" +from __future__ import absolute_import, print_function, division +from . 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"]["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"] = version.IVERSION + return data + +converters = { + (0, 13): convert_013_014 +} + + +def migrate_flow(flow_data): + while True: + flow_version = tuple(flow_data["version"][:2]) + if flow_version == version.IVERSION[:2]: + break + elif flow_version in converters: + flow_data = converters[flow_version](flow_data) + else: + v = ".".join(str(i) for i in flow_data["version"]) + raise ValueError("Incompatible serialized data version: {}".format(v)) + return flow_data