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
This commit is contained in:
Maximilian Hils 2017-03-08 00:52:37 +01:00
parent 8707928b16
commit f276c7a80d
4 changed files with 111 additions and 110 deletions

View File

@ -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."
)

View File

@ -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):

View File

@ -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:")

View File

@ -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():