From 7314081b8232ac8da8f0f893bad065806454c374 Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Thu, 26 Oct 2017 19:56:59 +0200 Subject: [PATCH] make safecall threadsafe. --- mitmproxy/addonmanager.py | 9 ++++++++- test/mitmproxy/addons/test_script.py | 5 +++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/mitmproxy/addonmanager.py b/mitmproxy/addonmanager.py index 316655480..70cfda309 100644 --- a/mitmproxy/addonmanager.py +++ b/mitmproxy/addonmanager.py @@ -8,6 +8,7 @@ from mitmproxy import exceptions from mitmproxy import eventsequence from mitmproxy import controller from mitmproxy import flow +from mitmproxy import log from . import ctx import pprint @@ -54,7 +55,13 @@ class StreamLog: @contextlib.contextmanager def safecall(): - stdout_replacement = StreamLog(ctx.log.warn) + # resolve ctx.master here. + # we want to be threadsafe, and ctx.master may already be cleared when an addon prints(). + tell = ctx.master.tell + # don't use master.add_log (which is not thread-safe). Instead, put on event queue. + stdout_replacement = StreamLog( + lambda message: tell("log", log.LogEntry(message, "warn")) + ) try: with contextlib.redirect_stdout(stdout_replacement): yield diff --git a/test/mitmproxy/addons/test_script.py b/test/mitmproxy/addons/test_script.py index aa7ca68e0..c4fe6b430 100644 --- a/test/mitmproxy/addons/test_script.py +++ b/test/mitmproxy/addons/test_script.py @@ -7,6 +7,7 @@ import pytest from mitmproxy import addonmanager from mitmproxy import exceptions +from mitmproxy import log from mitmproxy.addons import script from mitmproxy.test import taddons from mitmproxy.test import tflow @@ -50,7 +51,7 @@ def test_load_fullname(): def test_script_print_stdout(): with taddons.context() as tctx: - with mock.patch('mitmproxy.ctx.log.warn') as mock_warn: + with mock.patch('mitmproxy.ctx.master.tell') as mock_warn: with addonmanager.safecall(): ns = script.load_script( tutils.test_data.path( @@ -58,7 +59,7 @@ def test_script_print_stdout(): ) ) ns.load(addonmanager.Loader(tctx.master)) - mock_warn.assert_called_once_with("stdoutprint") + mock_warn.assert_called_once_with("log", log.LogEntry("stdoutprint", "warn")) class TestScript: