From 99605653593eb13aa0746e70b43f480fbfc67bf2 Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Sat, 4 Jul 2015 15:46:45 +0200 Subject: fix #653 --- libmproxy/script.py | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) (limited to 'libmproxy') diff --git a/libmproxy/script.py b/libmproxy/script.py index 46edb86b..6167ae05 100644 --- a/libmproxy/script.py +++ b/libmproxy/script.py @@ -128,15 +128,17 @@ class Script: class ReplyProxy(object): - def __init__(self, original_reply): - self._ignore_calls = 1 - self.lock = threading.Lock() + def __init__(self, original_reply, script_thread): self.original_reply = original_reply + self.script_thread = script_thread + self._ignore_call = True + self.lock = threading.Lock() def __call__(self, *args, **kwargs): with self.lock: - if self._ignore_calls > 0: - self._ignore_calls -= 1 + if self._ignore_call: + self.script_thread.start() + self._ignore_call = False return self.original_reply(*args, **kwargs) @@ -145,16 +147,19 @@ class ReplyProxy(object): def _handle_concurrent_reply(fn, o, *args, **kwargs): - # Make first call to o.reply a no op - - reply_proxy = ReplyProxy(o.reply) - o.reply = reply_proxy + # Make first call to o.reply a no op and start the script thread. + # We must not start the script thread before, as this may lead to a nasty race condition + # where the script thread replies a different response before the normal reply, which then gets swallowed. def run(): fn(*args, **kwargs) # If the script did not call .reply(), we have to do it now. reply_proxy() - ScriptThread(target=run).start() + + script_thread = ScriptThread(target=run) + + reply_proxy = ReplyProxy(o.reply, script_thread) + o.reply = reply_proxy class ScriptThread(threading.Thread): -- cgit v1.2.3