Options unification: string choices

This commit is contained in:
Aldo Cortesi 2017-03-06 13:17:53 +13:00
parent e70b46672c
commit 71a830c836
4 changed files with 66 additions and 46 deletions

View File

@ -1,7 +1,27 @@
from typing import Tuple, Optional, Sequence, Union
from mitmproxy.net import tcp
from mitmproxy import optmanager
# 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
# a lazy checker down the track.
console_palettes = [
"lowlight",
"lowdark",
"light",
"dark",
"solarized_light",
"solarized_dark"
]
view_orders = [
"time",
"method",
"url",
"size",
]
APP_HOST = "mitm.it"
APP_PORT = 80
CA_DIR = "~/.mitmproxy"
@ -260,8 +280,20 @@ class Options(optmanager.OptManager):
requests. Format: username:password
"""
)
self.add_option("ssl_version_client", "secure", str)
self.add_option("ssl_version_server", "secure", str)
self.add_option(
"ssl_version_client", "secure", str,
"Set supported SSL/TLS versions for client connections. "
"SSLv2, SSLv3 and 'all' are INSECURE. Defaults to secure, which "
"is TLS1.0+.",
choices=tcp.sslversion_choices.keys(),
)
self.add_option(
"ssl_version_server", "secure", str,
"Set supported SSL/TLS versions for server connections. "
"SSLv2, SSLv3 and 'all' are INSECURE. Defaults to secure, "
"which is TLS1.0+.",
choices=tcp.sslversion_choices.keys(),
)
self.add_option(
"ssl_insecure", False, bool,
"Do not verify upstream server SSL/TLS certificates."
@ -298,7 +330,11 @@ class Options(optmanager.OptManager):
"console_focus_follow", False, bool,
"Focus follows new flows."
)
self.add_option("console_palette", "dark", Optional[str])
self.add_option(
"console_palette", "dark", Optional[str],
help="Select color palette: " + ", ".join(console_palettes),
choices=sorted(console_palettes),
)
self.add_option(
"console_palette_transparent", False, bool,
"Set transparent background for palette."
@ -307,10 +343,12 @@ class Options(optmanager.OptManager):
"console_mouse", True, bool,
"Console mouse interaction."
)
self.add_option("console_order", None, Optional[str])
self.add_option(
"console_order_reversed", False, bool,
"console_order", None, Optional[str],
"Flow sort order.",
choices=view_orders,
)
self.add_option("console_order_reversed", False, bool)
self.add_option(
"filter", None, Optional[str],

View File

@ -20,14 +20,15 @@ unset = object()
class _Option:
__slots__ = ("name", "typespec", "value", "_default", "help")
__slots__ = ("name", "typespec", "value", "_default", "choices", "help")
def __init__(
self,
name: str,
default: typing.Any,
typespec: typing.Type,
help: typing.Optional[str]
help: typing.Optional[str],
choices: typing.Optional[typing.Sequence[str]]
) -> None:
typecheck.check_type(name, default, typespec)
self.name = name
@ -35,6 +36,7 @@ class _Option:
self.typespec = typespec
self.value = unset
self.help = help
self.choices = choices
def __repr__(self):
return "{value} [{type}]".format(value=self.current(), type=self.typespec)
@ -67,7 +69,9 @@ class _Option:
return True
def __deepcopy__(self, _):
o = _Option(self.name, self.default, self.typespec, self.help)
o = _Option(
self.name, self.default, self.typespec, self.help, self.choices
)
if self.has_changed():
o.value = self.current()
return o
@ -98,11 +102,12 @@ class OptManager:
name: str,
default: typing.Any,
typespec: typing.Type,
help: str = None
help: typing.Optional[str] = None,
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)
self._options[name] = _Option(name, default, typespec, help, choices)
@contextlib.contextmanager
def rollback(self, updated):
@ -337,7 +342,7 @@ class OptManager:
type=int,
dest=option,
help=o.help,
metavar=metavar
metavar=metavar,
)
elif o.typespec in (str, typing.Optional[str]):
parser.add_argument(
@ -346,7 +351,8 @@ class OptManager:
type=str,
dest=option,
help=o.help,
metavar=metavar
metavar=metavar,
choices=o.choices
)
elif o.typespec == typing.Sequence[str]:
parser.add_argument(
@ -355,7 +361,8 @@ class OptManager:
type=str,
dest=option,
help=o.help,
metavar=metavar
metavar=metavar,
choices=o.choices,
)
else:
raise ValueError("Unsupported option type: %s", o.typespec)

View File

@ -4,9 +4,7 @@ import os
from mitmproxy import exceptions
from mitmproxy import options
from mitmproxy import platform
from mitmproxy.net import tcp
from mitmproxy import version
from mitmproxy.addons import view
CONFIG_PATH = os.path.join(options.CA_DIR, "config.yaml")
@ -264,20 +262,8 @@ def proxy_ssl_options(parser, opts):
opts.make_parser(group, "ssl_insecure")
opts.make_parser(group, "ssl_verify_upstream_trusted_cadir", metavar="PATH")
opts.make_parser(group, "ssl_verify_upstream_trusted_ca", metavar="PATH")
group.add_argument(
"--ssl-version-client", dest="ssl_version_client",
action="store",
choices=tcp.sslversion_choices.keys(),
help="Set supported SSL/TLS versions for client connections. "
"SSLv2, SSLv3 and 'all' are INSECURE. Defaults to secure, which is TLS1.0+."
)
group.add_argument(
"--ssl-version-server", dest="ssl_version_server",
action="store",
choices=tcp.sslversion_choices.keys(),
help="Set supported SSL/TLS versions for server connections. "
"SSLv2, SSLv3 and 'all' are INSECURE. Defaults to secure, which is TLS1.0+."
)
opts.make_parser(group, "ssl_version_client", metavar="VERSION")
opts.make_parser(group, "ssl_version_server", metavar="VERSION")
def onboarding_app(parser, opts):
@ -387,25 +373,14 @@ def common_options(parser, opts):
def mitmproxy(opts):
# Don't import mitmproxy.tools.console for mitmdump, urwid is not available
# on all platforms.
from .console import palettes
parser = argparse.ArgumentParser(usage="%(prog)s [options]")
common_options(parser, opts)
parser.add_argument(
"--palette", type=str,
action="store", dest="console_palette",
choices=sorted(palettes.palettes.keys()),
help="Select color palette: " + ", ".join(palettes.palettes.keys())
)
opts.make_parser(parser, "console_palette")
opts.make_parser(parser, "console_palette_transparent")
opts.make_parser(parser, "console_eventlog")
opts.make_parser(parser, "console_focus_follow")
parser.add_argument(
"--order",
type=str, dest="console_order",
choices=[o[1] for o in view.orders],
help="Flow sort order."
)
opts.make_parser(parser, "console_order")
opts.make_parser(parser, "console_mouse")
group = parser.add_argument_group(
"Filters",

View File

@ -252,14 +252,14 @@ def test_merge():
def test_option():
o = optmanager._Option("test", 1, int, None)
o = optmanager._Option("test", 1, int, None, None)
assert o.current() == 1
with pytest.raises(TypeError):
o.set("foo")
with pytest.raises(TypeError):
optmanager._Option("test", 1, str, None)
optmanager._Option("test", 1, str, None, None)
o2 = optmanager._Option("test", 1, int, None)
o2 = optmanager._Option("test", 1, int, None, None)
assert o2 == o
o2.set(5)
assert o2 != o