From 4522a6f7b754be26084c40df5ecc7349023a692e Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Sat, 24 Feb 2018 12:13:52 +1300 Subject: [PATCH] Start moving addon options into /addons This takes the first few steps: - Extends taddons to make loading addon options easier - Removes dependencies in the test suite on options in addons - Tweaks command-line parser autocreation to ignore nonexistent options. This lets us load common options without over-depending on loaded addons. --- mitmproxy/addons/anticache.py | 9 +++++++++ mitmproxy/addons/anticomp.py | 6 ++++++ mitmproxy/options.py | 13 ------------- mitmproxy/optmanager.py | 7 +++++++ mitmproxy/test/taddons.py | 6 +++++- test/mitmproxy/addons/test_anticache.py | 2 +- test/mitmproxy/addons/test_anticomp.py | 2 +- test/mitmproxy/addons/test_core.py | 6 +++--- test/mitmproxy/test_optmanager.py | 7 ++++--- test/mitmproxy/tools/console/test_statusbar.py | 8 ++++---- 10 files changed, 40 insertions(+), 26 deletions(-) diff --git a/mitmproxy/addons/anticache.py b/mitmproxy/addons/anticache.py index 5b34d5a51..9f5c2dc1d 100644 --- a/mitmproxy/addons/anticache.py +++ b/mitmproxy/addons/anticache.py @@ -2,6 +2,15 @@ from mitmproxy import ctx class AntiCache: + def load(self, loader): + loader.add_option( + "anticache", bool, False, + """ + Strip out request headers that might cause the server to return + 304-not-modified. + """ + ) + def request(self, flow): if ctx.options.anticache: flow.request.anticache() diff --git a/mitmproxy/addons/anticomp.py b/mitmproxy/addons/anticomp.py index d7d1ca8da..3415302a6 100644 --- a/mitmproxy/addons/anticomp.py +++ b/mitmproxy/addons/anticomp.py @@ -2,6 +2,12 @@ from mitmproxy import ctx class AntiComp: + def load(self, loader): + loader.add_option( + "anticomp", bool, False, + "Try to convince servers to send us un-compressed data." + ) + def request(self, flow): if ctx.options.anticomp: flow.request.anticomp() diff --git a/mitmproxy/options.py b/mitmproxy/options.py index 76060548a..f31b4a036 100644 --- a/mitmproxy/options.py +++ b/mitmproxy/options.py @@ -31,8 +31,6 @@ class Options(optmanager.OptManager): # Autogenerated using test/helper_tools/typehints_for_options.py add_upstream_certs_to_client_chain = None # type: bool allow_remote = None # type: bool - anticache = None # type: bool - anticomp = None # type: bool body_size_limit = None # type: Optional[str] cadir = None # type: str certs = None # type: Sequence[str] @@ -121,17 +119,6 @@ class Options(optmanager.OptManager): "onboarding_port", int, APP_PORT, "Port to serve the onboarding app from." ) - self.add_option( - "anticache", bool, False, - """ - Strip out request headers that might cause the server to return - 304-not-modified. - """ - ) - self.add_option( - "anticomp", bool, False, - "Try to convince servers to send us un-compressed data." - ) self.add_option( "client_replay", Sequence[str], [], "Replay client requests from a saved file." diff --git a/mitmproxy/optmanager.py b/mitmproxy/optmanager.py index 01d97af31..bb9e30302 100644 --- a/mitmproxy/optmanager.py +++ b/mitmproxy/optmanager.py @@ -327,6 +327,13 @@ class OptManager: return d def make_parser(self, parser, optname, metavar=None, short=None): + """ + Auto-Create a command-line parser entry for a named option. If the + option does not exist, it is ignored. + """ + if optname not in self._options: + return + o = self._options[optname] def mkf(l, s): diff --git a/mitmproxy/test/taddons.py b/mitmproxy/test/taddons.py index d966f1d5d..12fc09861 100644 --- a/mitmproxy/test/taddons.py +++ b/mitmproxy/test/taddons.py @@ -59,7 +59,7 @@ class context: provides a number of helper methods for common testing scenarios. """ - def __init__(self, master=None, options=None): + def __init__(self, *addons, master=None, options=None): options = options or mitmproxy.options.Options() self.master = master or RecordingMaster( options @@ -67,6 +67,10 @@ class context: self.options = self.master.options self.wrapped = None + loader = addonmanager.Loader(self.master) + for a in addons: + self.master.addons.invoke_addon(a, "load", loader) + def ctx(self): """ Returns a new handler context. diff --git a/test/mitmproxy/addons/test_anticache.py b/test/mitmproxy/addons/test_anticache.py index 928f2180f..d1765fe07 100644 --- a/test/mitmproxy/addons/test_anticache.py +++ b/test/mitmproxy/addons/test_anticache.py @@ -7,7 +7,7 @@ from mitmproxy.test import taddons class TestAntiCache: def test_simple(self): sa = anticache.AntiCache() - with taddons.context() as tctx: + with taddons.context(sa) as tctx: f = tflow.tflow(resp=True) f.request.headers["if-modified-since"] = "test" f.request.headers["if-none-match"] = "test" diff --git a/test/mitmproxy/addons/test_anticomp.py b/test/mitmproxy/addons/test_anticomp.py index 2a6cf3ce3..92650332c 100644 --- a/test/mitmproxy/addons/test_anticomp.py +++ b/test/mitmproxy/addons/test_anticomp.py @@ -7,7 +7,7 @@ from mitmproxy.test import taddons class TestAntiComp: def test_simple(self): sa = anticomp.AntiComp() - with taddons.context() as tctx: + with taddons.context(sa) as tctx: f = tflow.tflow(resp=True) sa.request(f) diff --git a/test/mitmproxy/addons/test_core.py b/test/mitmproxy/addons/test_core.py index 5aa4ef376..5c9a8a0d2 100644 --- a/test/mitmproxy/addons/test_core.py +++ b/test/mitmproxy/addons/test_core.py @@ -10,9 +10,9 @@ def test_set(): with taddons.context() as tctx: tctx.master.addons.add(sa) - assert not tctx.master.options.anticomp - tctx.command(sa.set, "anticomp") - assert tctx.master.options.anticomp + assert tctx.master.options.server + tctx.command(sa.set, "server=false") + assert not tctx.master.options.server with pytest.raises(exceptions.CommandError): tctx.command(sa.set, "nonexistent") diff --git a/test/mitmproxy/test_optmanager.py b/test/mitmproxy/test_optmanager.py index d9b932277..cd8857cab 100644 --- a/test/mitmproxy/test_optmanager.py +++ b/test/mitmproxy/test_optmanager.py @@ -351,7 +351,7 @@ def test_dump_defaults(): def test_dump_dicts(): o = options.Options() assert optmanager.dump_dicts(o) - assert optmanager.dump_dicts(o, ['http2', 'anticomp']) + assert optmanager.dump_dicts(o, ['http2', 'listen_port']) class TTypes(optmanager.OptManager): @@ -375,8 +375,9 @@ def test_make_parser(): opts.make_parser(parser, "int", short="c") opts.make_parser(parser, "seqstr", short="d") opts.make_parser(parser, "bool_on", short="e") - with pytest.raises(ValueError): - opts.make_parser(parser, "unknown") + + # No error for nonexistent options + opts.make_parser(parser, "xxxxxxx") def test_set(): diff --git a/test/mitmproxy/tools/console/test_statusbar.py b/test/mitmproxy/tools/console/test_statusbar.py index 8522eb96a..ac17c5c08 100644 --- a/test/mitmproxy/tools/console/test_statusbar.py +++ b/test/mitmproxy/tools/console/test_statusbar.py @@ -3,7 +3,9 @@ from mitmproxy.tools.console import statusbar, master def test_statusbar(monkeypatch): - o = options.Options( + o = options.Options() + m = master.ConsoleMaster(o) + m.options.update( setheaders=[":~q:foo:bar"], replacements=[":~q:foo:bar"], ignore_hosts=["example.com", "example.org"], @@ -21,10 +23,8 @@ def test_statusbar(monkeypatch): upstream_cert=False, stream_large_bodies="3m", mode="transparent", - scripts=["nonexistent"], - save_stream_file="foo", ) - m = master.ConsoleMaster(o) + m.options.update(view_order='url', console_focus_follow=True) monkeypatch.setattr(m.addons.get("clientplayback"), "count", lambda: 42) monkeypatch.setattr(m.addons.get("serverplayback"), "count", lambda: 42)