From f276c7a80d63c0a464feca5f76096a23afdc69b2 Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Wed, 8 Mar 2017 00:52:37 +0100 Subject: change add_option parameter order name, type, value matches natural language ($x is a bool with a default value of $y) and also matches the python type annotation order of name: type = value --- mitmproxy/options.py | 163 +++++++++++++++++++------------------ mitmproxy/optmanager.py | 10 +-- test/mitmproxy/addons/test_core.py | 2 +- test/mitmproxy/test_optmanager.py | 46 +++++------ 4 files changed, 111 insertions(+), 110 deletions(-) diff --git a/mitmproxy/options.py b/mitmproxy/options.py index 1063bab9..6dd8616b 100644 --- a/mitmproxy/options.py +++ b/mitmproxy/options.py @@ -1,8 +1,7 @@ from typing import Optional, Sequence -from mitmproxy.net import tcp from mitmproxy import optmanager - +from mitmproxy.net import tcp # We redefine these here for now to avoid importing Urwid-related guff on # platforms that don't support it, and circular imports. We can do better using @@ -29,128 +28,130 @@ LISTEN_PORT = 8080 # We manually need to specify this, otherwise OpenSSL may select a non-HTTP2 cipher by default. # https://mozilla.github.io/server-side-tls/ssl-config-generator/?server=apache-2.2.15&openssl=1.0.2&hsts=yes&profile=old -DEFAULT_CLIENT_CIPHERS = "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:" \ - "ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:" \ - "ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:" \ - "ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:" \ - "DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:" \ - "DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:" \ - "AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:DES-CBC3-SHA:" \ - "HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:" \ +DEFAULT_CLIENT_CIPHERS = ( + "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:" + "ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:" + "ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:" + "ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:" + "DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:" + "DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:" + "AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:DES-CBC3-SHA:" + "HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:" "!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA" +) class Options(optmanager.OptManager): def __init__(self, **kwargs) -> None: super().__init__() self.add_option( - "onboarding", True, bool, + "onboarding", bool, True, "Toggle the mitmproxy onboarding app." ) self.add_option( - "onboarding_host", APP_HOST, str, + "onboarding_host", str, APP_HOST, """ Domain to serve the onboarding app from. For transparent mode, use an IP when a DNS entry for the app domain is not present. """ ) self.add_option( - "onboarding_port", APP_PORT, int, + "onboarding_port", int, APP_PORT, "Port to serve the onboarding app from." ) self.add_option( - "anticache", False, bool, + "anticache", bool, False, """ Strip out request headers that might cause the server to return 304-not-modified. """ ) self.add_option( - "anticomp", False, bool, + "anticomp", bool, False, "Try to convince servers to send us un-compressed data." ) self.add_option( - "client_replay", [], Sequence[str], + "client_replay", Sequence[str], [], "Replay client requests from a saved file." ) self.add_option( - "replay_kill_extra", False, bool, + "replay_kill_extra", bool, False, "Kill extra requests during replay." ) self.add_option( - "keepserving", True, bool, + "keepserving", bool, True, "Continue serving after client playback or file read." ) self.add_option( - "server", True, bool, + "server", bool, True, "Start a proxy server." ) self.add_option( - "server_replay_nopop", False, bool, + "server_replay_nopop", bool, False, """ Disable response pop from response flow. This makes it possible to replay same response multiple times. """ ) self.add_option( - "refresh_server_playback", True, bool, + "refresh_server_playback", bool, True, """ Refresh server replay responses by adjusting date, expires and last-modified headers, as well as adjusting cookie expiration. """ ) self.add_option( - "rfile", None, Optional[str], + "rfile", Optional[str], None, "Read flows from file." ) self.add_option( - "scripts", [], Sequence[str], + "scripts", Sequence[str], [], """ Execute a script. """ ) self.add_option( - "showhost", False, bool, + "showhost", bool, False, "Use the Host header to construct URLs for display." ) self.add_option( - "replacements", [], Sequence[str], + "replacements", Sequence[str], [], """ Replacement patterns of the form "/pattern/regex/replacement", where the separator can be any character. """ ) self.add_option( - "replacement_files", [], Sequence[str], + "replacement_files", Sequence[str], [], """ Replacement pattern, where the replacement clause is a path to a file. """ ) self.add_option( - "server_replay_use_headers", [], Sequence[str], + "server_replay_use_headers", Sequence[str], [], "Request headers to be considered during replay." ) self.add_option( - "setheaders", [], Sequence[str], + "setheaders", Sequence[str], [], """ Header set pattern of the form "/pattern/header/value", where the separator can be any character. """ ) self.add_option( - "server_replay", [], Sequence[str], + "server_replay", Sequence[str], [], "Replay server responses from a saved file." ) self.add_option( - "stickycookie", None, Optional[str], + "stickycookie", Optional[str], None, "Set sticky cookie filter. Matched against requests." ) self.add_option( - "stickyauth", None, Optional[str], + "stickyauth", Optional[str], None, "Set sticky auth filter. Matched against requests." ) self.add_option( - "stream_large_bodies", None, Optional[str], + "stream_large_bodies", Optional[str], None, """ Stream data to the client if response body exceeds the given threshold. If streamed, the body will not be stored in any way. @@ -158,30 +159,30 @@ class Options(optmanager.OptManager): """ ) self.add_option( - "verbosity", 2, int, + "verbosity", int, 2, "Log verbosity." ) self.add_option( - "default_contentview", "auto", str, + "default_contentview", str, "auto", "The default content view mode." ) self.add_option( - "streamfile", None, Optional[str], + "streamfile", Optional[str], None, "Write flows to file. Prefix path with + to append." ) self.add_option( - "server_replay_ignore_content", False, bool, + "server_replay_ignore_content", bool, False, "Ignore request's content while searching for a saved flow to replay." ) self.add_option( - "server_replay_ignore_params", [], Sequence[str], + "server_replay_ignore_params", Sequence[str], [], """ Request's parameters to be ignored while searching for a saved flow to replay. Can be passed multiple times. """ ) self.add_option( - "server_replay_ignore_payload_params", [], Sequence[str], + "server_replay_ignore_payload_params", Sequence[str], [], """ Request's payload parameters (application/x-www-form-urlencoded or multipart/form-data) to be ignored while searching for a saved flow @@ -189,7 +190,7 @@ class Options(optmanager.OptManager): """ ) self.add_option( - "server_replay_ignore_host", False, bool, + "server_replay_ignore_host", bool, False, """ Ignore request's destination host while searching for a saved flow to replay. @@ -198,7 +199,7 @@ class Options(optmanager.OptManager): # Proxy options self.add_option( - "proxyauth", None, Optional[str], + "proxyauth", Optional[str], None, """ Require authentication before proxying requests. If the value is "any", we prompt for authentication, but permit any values. If it @@ -208,25 +209,25 @@ class Options(optmanager.OptManager): """ ) self.add_option( - "add_upstream_certs_to_client_chain", False, bool, + "add_upstream_certs_to_client_chain", bool, False, """ Add all certificates of the upstream server to the certificate chain that will be served to the proxy client, as extras. """ ) self.add_option( - "body_size_limit", None, Optional[str], + "body_size_limit", Optional[str], None, """ Byte size limit of HTTP request and response bodies. Understands k/m/g suffixes, i.e. 3m for 3 megabytes. """ ) self.add_option( - "cadir", CA_DIR, str, + "cadir", str, CA_DIR, "Location of the default mitmproxy CA files." ) self.add_option( - "certs", [], Sequence[str], + "certs", Sequence[str], [], """ SSL certificates. SPEC is of the form "[domain=]path". The domain may include a wildcard, and is equal to "*" if not specified. @@ -238,19 +239,19 @@ class Options(optmanager.OptManager): """ ) self.add_option( - "ciphers_client", DEFAULT_CLIENT_CIPHERS, str, + "ciphers_client", str, DEFAULT_CLIENT_CIPHERS, "Set supported ciphers for client connections using OpenSSL syntax." ) self.add_option( - "ciphers_server", None, Optional[str], + "ciphers_server", Optional[str], None, "Set supported ciphers for server connections using OpenSSL syntax." ) self.add_option( - "client_certs", None, Optional[str], + "client_certs", Optional[str], None, "Client certificate file or directory." ) self.add_option( - "ignore_hosts", [], Sequence[str], + "ignore_hosts", Sequence[str], [], """ Ignore host and forward all traffic without processing it. In transparent mode, it is recommended to use an IP address (range), @@ -260,19 +261,19 @@ class Options(optmanager.OptManager): """ ) self.add_option( - "listen_host", "", str, + "listen_host", str, "", "Address to bind proxy to." ) self.add_option( - "listen_port", LISTEN_PORT, int, + "listen_port", int, LISTEN_PORT, "Proxy service port." ) self.add_option( - "upstream_bind_address", "", str, + "upstream_bind_address", str, "", "Address to bind upstream requests to." ) self.add_option( - "mode", "regular", str, + "mode", str, "regular", """ Mode can be "regular", "transparent", "socks5", "reverse:SPEC", or "upstream:SPEC". For reverse and upstream proxy modes, SPEC @@ -280,11 +281,11 @@ class Options(optmanager.OptManager): """ ) self.add_option( - "upstream_cert", True, bool, + "upstream_cert", bool, True, "Connect to upstream server to look up certificate details." ) self.add_option( - "keep_host_header", False, bool, + "keep_host_header", bool, False, """ Reverse Proxy: Keep the original host header instead of rewriting it to the reverse proxy target. @@ -292,12 +293,12 @@ class Options(optmanager.OptManager): ) self.add_option( - "http2", True, bool, + "http2", bool, True, "Enable/disable HTTP/2 support. " "HTTP/2 support is enabled by default.", ) self.add_option( - "http2_priority", False, bool, + "http2_priority", bool, False, """ PRIORITY forwarding for HTTP/2 connections. PRIORITY forwarding is disabled by default, because some webservers fail to implement the @@ -305,32 +306,32 @@ class Options(optmanager.OptManager): """ ) self.add_option( - "websocket", True, bool, + "websocket", bool, True, "Enable/disable WebSocket support. " "WebSocket support is enabled by default.", ) self.add_option( - "rawtcp", False, bool, + "rawtcp", bool, False, "Enable/disable experimental raw TCP support. " "Disabled by default. " ) self.add_option( - "spoof_source_address", False, bool, + "spoof_source_address", bool, False, """ Use the client's IP for server-side connections. Combine with --upstream-bind-address to spoof a fixed source address. """ ) self.add_option( - "upstream_auth", None, Optional[str], + "upstream_auth", Optional[str], None, """ Add HTTP Basic authentcation to upstream proxy and reverse proxy requests. Format: username:password. """ ) self.add_option( - "ssl_version_client", "secure", str, + "ssl_version_client", str, "secure", """ Set supported SSL/TLS versions for client connections. SSLv2, SSLv3 and 'all' are INSECURE. Defaults to secure, which is TLS1.0+. @@ -338,7 +339,7 @@ class Options(optmanager.OptManager): choices=tcp.sslversion_choices.keys(), ) self.add_option( - "ssl_version_server", "secure", str, + "ssl_version_server", str, "secure", """ Set supported SSL/TLS versions for server connections. SSLv2, SSLv3 and 'all' are INSECURE. Defaults to secure, which is TLS1.0+. @@ -346,22 +347,22 @@ class Options(optmanager.OptManager): choices=tcp.sslversion_choices.keys(), ) self.add_option( - "ssl_insecure", False, bool, + "ssl_insecure", bool, False, "Do not verify upstream server SSL/TLS certificates." ) self.add_option( - "ssl_verify_upstream_trusted_cadir", None, Optional[str], + "ssl_verify_upstream_trusted_cadir", Optional[str], None, """ Path to a directory of trusted CA certificates for upstream server verification prepared using the c_rehash tool. """ ) self.add_option( - "ssl_verify_upstream_trusted_ca", None, Optional[str], + "ssl_verify_upstream_trusted_ca", Optional[str], None, "Path to a PEM formatted trusted CA certificate." ) self.add_option( - "tcp_hosts", [], Sequence[str], + "tcp_hosts", Sequence[str], [], """ Generic TCP SSL proxy mode for all hosts that match the pattern. Similar to --ignore, but SSL connections are intercepted. The @@ -370,72 +371,72 @@ class Options(optmanager.OptManager): ) self.add_option( - "intercept", None, Optional[str], + "intercept", Optional[str], None, "Intercept filter expression." ) # Console options self.add_option( - "console_eventlog", False, bool, + "console_eventlog", bool, False, "Show event log." ) self.add_option( - "console_focus_follow", False, bool, + "console_focus_follow", bool, False, "Focus follows new flows." ) self.add_option( - "console_palette", "dark", str, + "console_palette", str, "dark", "Color palette.", choices=sorted(console_palettes), ) self.add_option( - "console_palette_transparent", False, bool, + "console_palette_transparent", bool, False, "Set transparent background for palette." ) self.add_option( - "console_mouse", True, bool, + "console_mouse", bool, True, "Console mouse interaction." ) self.add_option( - "console_order", None, Optional[str], + "console_order", Optional[str], None, "Flow sort order.", choices=view_orders, ) self.add_option( - "console_order_reversed", False, bool, + "console_order_reversed", bool, False, "Reverse the sorting order." ) self.add_option( - "filter", None, Optional[str], + "filter", Optional[str], None, "Filter view expression." ) # Web options self.add_option( - "web_open_browser", True, bool, + "web_open_browser", bool, True, "Start a browser." ) self.add_option( - "web_debug", False, bool, + "web_debug", bool, False, "Mitmweb debugging." ) self.add_option( - "web_port", 8081, int, + "web_port", int, 8081, "Mitmweb port." ) self.add_option( - "web_iface", "127.0.0.1", str, + "web_iface", str, "127.0.0.1", "Mitmweb interface." ) # Dump options self.add_option( - "filtstr", None, Optional[str], + "filtstr", Optional[str], None, "The filter string for mitmdump." ) self.add_option( - "flow_detail", 1, int, + "flow_detail", int, 1, "Flow detail display level." ) diff --git a/mitmproxy/optmanager.py b/mitmproxy/optmanager.py index b05e78eb..a928b953 100644 --- a/mitmproxy/optmanager.py +++ b/mitmproxy/optmanager.py @@ -26,15 +26,15 @@ class _Option: def __init__( self, name: str, - default: typing.Any, typespec: typing.Type, + default: typing.Any, help: str, choices: typing.Optional[typing.Sequence[str]] ) -> None: typecheck.check_type(name, default, typespec) self.name = name - self._default = default self.typespec = typespec + self._default = default self.value = unset self.help = help self.choices = choices @@ -71,7 +71,7 @@ class _Option: def __deepcopy__(self, _): o = _Option( - self.name, self.default, self.typespec, self.help, self.choices + self.name, self.typespec, self.default, self.help, self.choices ) if self.has_changed(): o.value = self.current() @@ -101,14 +101,14 @@ class OptManager: def add_option( self, name: str, - default: typing.Any, typespec: typing.Type, + default: typing.Any, help: str, choices: typing.Optional[typing.Sequence[str]] = None ) -> None: if name in self._options: raise ValueError("Option %s already exists" % name) - self._options[name] = _Option(name, default, typespec, help, choices) + self._options[name] = _Option(name, typespec, default, help, choices) @contextlib.contextmanager def rollback(self, updated, reraise=False): diff --git a/test/mitmproxy/addons/test_core.py b/test/mitmproxy/addons/test_core.py index 7b9e9614..db739b5d 100644 --- a/test/mitmproxy/addons/test_core.py +++ b/test/mitmproxy/addons/test_core.py @@ -39,5 +39,5 @@ def test_modes(m): sa = core.Core() with taddons.context() as tctx: tctx.configure(sa, mode = "reverse:http://localhost") - with pytest.raises(Exception, match="Invalid mode"): + with pytest.raises(Exception, match="Invalid server specification"): tctx.configure(sa, mode = "reverse:") diff --git a/test/mitmproxy/test_optmanager.py b/test/mitmproxy/test_optmanager.py index ba31c750..db33cddd 100644 --- a/test/mitmproxy/test_optmanager.py +++ b/test/mitmproxy/test_optmanager.py @@ -13,36 +13,36 @@ from mitmproxy.test import tutils class TO(optmanager.OptManager): def __init__(self): super().__init__() - self.add_option("one", None, typing.Optional[int], "help") - self.add_option("two", 2, typing.Optional[int], "help") - self.add_option("bool", False, bool, "help") + self.add_option("one", typing.Optional[int], None, "help") + self.add_option("two", typing.Optional[int], 2, "help") + self.add_option("bool", bool, False, "help") class TD(optmanager.OptManager): def __init__(self): super().__init__() - self.add_option("one", "done", str, "help") - self.add_option("two", "dtwo", str, "help") + self.add_option("one", str, "done", "help") + self.add_option("two", str, "dtwo", "help") class TD2(TD): def __init__(self): super().__init__() - self.add_option("three", "dthree", str, "help") - self.add_option("four", "dfour", str, "help") + self.add_option("three", str, "dthree", "help") + self.add_option("four", str, "dfour", "help") class TM(optmanager.OptManager): def __init__(self): super().__init__() - self.add_option("two", ["foo"], typing.Sequence[str], "help") - self.add_option("one", None, typing.Optional[str], "help") + self.add_option("two", typing.Sequence[str], ["foo"], "help") + self.add_option("one", typing.Optional[str], None, "help") def test_add_option(): o = TO() with pytest.raises(ValueError, match="already exists"): - o.add_option("one", None, typing.Optional[int], "help") + o.add_option("one", typing.Optional[int], None, "help") def test_defaults(): @@ -76,7 +76,7 @@ def test_defaults(): def test_options(): o = TO() - assert o.keys() == set(["bool", "one", "two"]) + assert o.keys() == {"bool", "one", "two"} assert o.one is None assert o.two == 2 @@ -189,7 +189,7 @@ def test_rollback(): assert rec[3].bool is False with pytest.raises(exceptions.OptionsError): - with o.rollback(set(["one"]), reraise=True): + with o.rollback({"one"}, reraise=True): raise exceptions.OptionsError() @@ -270,14 +270,14 @@ def test_merge(): def test_option(): - o = optmanager._Option("test", 1, int, None, None) + o = optmanager._Option("test", int, 1, None, None) assert o.current() == 1 with pytest.raises(TypeError): o.set("foo") with pytest.raises(TypeError): - optmanager._Option("test", 1, str, None, None) + optmanager._Option("test", str, 1, None, None) - o2 = optmanager._Option("test", 1, int, None, None) + o2 = optmanager._Option("test", int, 1, None, None) assert o2 == o o2.set(5) assert o2 != o @@ -291,14 +291,14 @@ def test_dump(): class TTypes(optmanager.OptManager): def __init__(self): super().__init__() - self.add_option("str", "str", str, "help") - self.add_option("optstr", "optstr", typing.Optional[str], "help", "help") - self.add_option("bool", False, bool, "help") - self.add_option("bool_on", True, bool, "help") - self.add_option("int", 0, int, "help") - self.add_option("optint", 0, typing.Optional[int], "help") - self.add_option("seqstr", [], typing.Sequence[str], "help") - self.add_option("unknown", 0.0, float, "help") + self.add_option("str", str, "str", "help") + self.add_option("optstr", typing.Optional[str], "optstr", "help", "help") + self.add_option("bool", bool, False, "help") + self.add_option("bool_on", bool, True, "help") + self.add_option("int", int, 0, "help") + self.add_option("optint", typing.Optional[int], 0, "help") + self.add_option("seqstr", typing.Sequence[str], [], "help") + self.add_option("unknown", float, 0.0, "help") def test_make_parser(): -- cgit v1.2.3