From 276b467b0e012129da91c0069eebb64fdc4179b6 Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Fri, 23 Sep 2016 22:52:58 -0700 Subject: [PATCH] fix #1393 --- mitmproxy/console/flowlist.py | 6 +++++- mitmproxy/console/flowview.py | 6 +++++- mitmproxy/exceptions.py | 4 ---- mitmproxy/flow/master.py | 33 +++++++++++++++++++------------ mitmproxy/protocol/http_replay.py | 2 ++ 5 files changed, 32 insertions(+), 19 deletions(-) diff --git a/mitmproxy/console/flowlist.py b/mitmproxy/console/flowlist.py index c052de7be..a05ed6598 100644 --- a/mitmproxy/console/flowlist.py +++ b/mitmproxy/console/flowlist.py @@ -3,6 +3,7 @@ from __future__ import absolute_import, print_function, division import urwid import netlib.http.url +from mitmproxy import exceptions from mitmproxy.console import common from mitmproxy.console import signals from mitmproxy.flow import export @@ -180,7 +181,10 @@ class ConnectionItem(urwid.WidgetWrap): self.state.enable_marked_filter() signals.flowlist_change.send(self) elif key == "r": - self.master.replay_request(self.flow) + try: + self.master.replay_request(self.flow) + except exceptions.ReplayException as e: + signals.add_log("Replay error: %s" % e, "warn") signals.flowlist_change.send(self) elif key == "S": def stop_server_playback(response): diff --git a/mitmproxy/console/flowview.py b/mitmproxy/console/flowview.py index add105272..4643863c7 100644 --- a/mitmproxy/console/flowview.py +++ b/mitmproxy/console/flowview.py @@ -5,6 +5,7 @@ import os import sys import urwid +from mitmproxy import exceptions from typing import Optional, Union # noqa from mitmproxy import contentviews @@ -544,7 +545,10 @@ class FlowView(tabs.Tabs): elif key == "p": self.view_prev_flow(self.flow) elif key == "r": - self.master.replay_request(self.flow) + try: + self.master.replay_request(self.flow) + except exceptions.ReplayException as e: + signals.add_log("Replay error: %s" % e, "warn") signals.flow_change.send(self, flow = self.flow) elif key == "V": if self.flow.modified(): diff --git a/mitmproxy/exceptions.py b/mitmproxy/exceptions.py index 6873215c5..7fca584af 100644 --- a/mitmproxy/exceptions.py +++ b/mitmproxy/exceptions.py @@ -97,7 +97,3 @@ class OptionsError(Exception): class AddonError(Exception): pass - - -class ReplayError(Exception): - pass diff --git a/mitmproxy/flow/master.py b/mitmproxy/flow/master.py index 94b46f3f3..80f633cd6 100644 --- a/mitmproxy/flow/master.py +++ b/mitmproxy/flow/master.py @@ -3,7 +3,7 @@ from __future__ import absolute_import, print_function, division import os import sys -from typing import List, Optional, Set # noqa +from typing import Optional # noqa import netlib.exceptions from mitmproxy import controller @@ -138,37 +138,44 @@ class FlowMaster(controller.Master): def replay_request(self, f, block=False): """ - Returns an http_replay.RequestReplayThred object. - May raise exceptions.ReplayError. + Replay a HTTP request to receive a new response from the server. + + Args: + f: The flow to replay. + block: If True, this function will wait for the replay to finish. + This causes a deadlock if activated in the main thread. + + Returns: + The thread object doing the replay. + + Raises: + exceptions.ReplayException, if the flow is in a state + where it is ineligible for replay. """ + if f.live: - raise exceptions.ReplayError( + raise exceptions.ReplayException( "Can't replay live flow." ) if f.intercepted: - raise exceptions.ReplayError( + raise exceptions.ReplayException( "Can't replay intercepted flow." ) if f.request.raw_content is None: - raise exceptions.ReplayError( + raise exceptions.ReplayException( "Can't replay flow with missing content." ) if not f.request: - raise exceptions.ReplayError( + raise exceptions.ReplayException( "Can't replay flow with missing request." ) f.backup() f.request.is_replay = True - # TODO: We should be able to remove this. - if "Content-Length" in f.request.headers: - f.request.headers["Content-Length"] = str(len(f.request.raw_content)) - f.response = None f.error = None - # FIXME: process through all addons? - # self.process_new_request(f) + rt = http_replay.RequestReplayThread( self.server.config, f, diff --git a/mitmproxy/protocol/http_replay.py b/mitmproxy/protocol/http_replay.py index 877eaa22c..5e527f1d3 100644 --- a/mitmproxy/protocol/http_replay.py +++ b/mitmproxy/protocol/http_replay.py @@ -22,6 +22,7 @@ class RequestReplayThread(basethread.BaseThread): processed. """ self.config, self.flow = config, flow + flow.live = True if event_queue: self.channel = controller.Channel(event_queue, should_exit) else: @@ -104,5 +105,6 @@ class RequestReplayThread(basethread.BaseThread): self.channel.tell("log", Log(traceback.format_exc(), "error")) finally: r.first_line_format = first_line_format_backup + self.flow.live = False if server: server.finish()