Start unifying options and the command-line: booleans

This commit:

- Adds a help field to options
- Adds a function to generate parser definitions from options
- Uses this to migrate all boolean flags over to the new system
- Makes all booleans consistently follow the --foo/--not-foo convention

There are a number of things left to be done here:

- Argparse doesn't give us a nice way to format --foo --not-foo help. Click
does, and moving to click is a goal down the track.
- For now, we remove all short aliases. I want to re-evaluate these
systematically once we have the new structure in place.
This commit is contained in:
Aldo Cortesi 2017-03-05 20:10:06 +13:00
parent 67381ae550
commit f15a628561
16 changed files with 255 additions and 255 deletions

View File

@ -23,20 +23,50 @@ DEFAULT_CLIENT_CIPHERS = "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA
class Options(optmanager.OptManager):
def __init__(self, **kwargs) -> None:
super().__init__()
self.add_option("onboarding", True, bool)
self.add_option(
"onboarding", True, bool,
"Toggle the mitmproxy onboarding app."
)
self.add_option("onboarding_host", APP_HOST, str)
self.add_option("onboarding_port", APP_PORT, int)
self.add_option("anticache", False, bool)
self.add_option("anticomp", False, bool)
self.add_option(
"anticache", False, bool,
"""
Strip out request headers that might cause the server to return
304-not-modified.
"""
)
self.add_option(
"anticomp", False, bool,
"Try to convince servers to send us un-compressed data."
)
self.add_option("client_replay", [], Sequence[str])
self.add_option("replay_kill_extra", False, bool)
self.add_option("keepserving", True, bool)
self.add_option("no_server", False, bool)
self.add_option("server_replay_nopop", False, bool)
self.add_option("refresh_server_playback", True, bool)
self.add_option(
"replay_kill_extra", False, bool,
"Kill extra requests during replay."
)
self.add_option(
"keepserving", True, bool,
"Continue serving after client playback or file read."
)
self.add_option(
"no_server", False, bool,
"Don't start a proxy server."
)
self.add_option(
"server_replay_nopop", False, bool,
"Disable response pop from response flow. "
"This makes it possible to replay same response multiple times."
)
self.add_option(
"refresh_server_playback", True, bool,
)
self.add_option("rfile", None, Optional[str])
self.add_option("scripts", [], Sequence[str])
self.add_option("showhost", False, bool)
self.add_option(
"showhost", False, bool,
"Use the Host header to construct URLs for display."
)
self.add_option("replacements", [], Sequence[Union[Tuple[str, str, str], str]])
self.add_option("replacement_files", [], Sequence[Union[Tuple[str, str, str], str]])
self.add_option("server_replay_use_headers", [], Sequence[str])
@ -49,16 +79,30 @@ class Options(optmanager.OptManager):
self.add_option("default_contentview", "auto", str)
self.add_option("streamfile", None, Optional[str])
self.add_option("streamfile_append", False, bool)
self.add_option("server_replay_ignore_content", False, bool)
self.add_option(
"server_replay_ignore_content", False, bool,
"Ignore request's content while searching for a saved flow to replay."
)
self.add_option("server_replay_ignore_params", [], Sequence[str])
self.add_option("server_replay_ignore_payload_params", [], Sequence[str])
self.add_option("server_replay_ignore_host", False, bool)
self.add_option(
"server_replay_ignore_host", False, bool,
"Ignore request's destination host while searching for a saved"
" flow to replay"
)
# Proxy options
self.add_option("auth_nonanonymous", False, bool)
self.add_option(
"auth_nonanonymous", False, bool,
"Allow access to any user long as a credentials are specified."
)
self.add_option("auth_singleuser", None, Optional[str])
self.add_option("auth_htpasswd", None, Optional[str])
self.add_option("add_upstream_certs_to_client_chain", False, bool)
self.add_option(
"add_upstream_certs_to_client_chain", False, bool,
"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[int])
self.add_option("cadir", CA_DIR, str)
self.add_option("certs", [], Sequence[Tuple[str, str]])
@ -70,20 +114,51 @@ class Options(optmanager.OptManager):
self.add_option("listen_port", LISTEN_PORT, int)
self.add_option("upstream_bind_address", "", str)
self.add_option("mode", "regular", str)
self.add_option("no_upstream_cert", False, bool)
self.add_option("keep_host_header", False, bool)
self.add_option(
"upstream_cert", True, bool,
"Connect to upstream server to look up certificate details."
)
self.add_option(
"keep_host_header", False, bool,
"Reverse Proxy: Keep the original host header instead of rewriting it"
" to the reverse proxy target."
)
self.add_option("http2", True, bool)
self.add_option("http2_priority", False, bool)
self.add_option("websocket", True, bool)
self.add_option("rawtcp", False, bool)
self.add_option(
"http2", True, bool,
"Enable/disable HTTP/2 support. "
"HTTP/2 support is enabled by default.",
)
self.add_option(
"http2_priority", False, bool,
"Enable/disable PRIORITY forwarding for HTTP/2 connections. "
"PRIORITY forwarding is disabled by default, "
"because some webservers fail to implement the RFC properly.",
)
self.add_option(
"websocket", True, bool,
"Enable/disable WebSocket support. "
"WebSocket support is enabled by default.",
)
self.add_option(
"rawtcp", False, bool,
"Enable/disable experimental raw TCP support. "
"Disabled by default. "
)
self.add_option("spoof_source_address", False, bool)
self.add_option(
"spoof_source_address", False, bool,
"Use the client's IP for server-side connections. "
"Combine with --upstream-bind-address to spoof a fixed source address."
)
self.add_option("upstream_server", None, Optional[str])
self.add_option("upstream_auth", None, Optional[str])
self.add_option("ssl_version_client", "secure", str)
self.add_option("ssl_version_server", "secure", str)
self.add_option("ssl_insecure", False, bool)
self.add_option(
"ssl_insecure", False, bool,
"Do not verify upstream server SSL/TLS certificates."
)
self.add_option("ssl_verify_upstream_trusted_cadir", None, Optional[str])
self.add_option("ssl_verify_upstream_trusted_ca", None, Optional[str])
self.add_option("tcp_hosts", [], Sequence[str])
@ -91,19 +166,39 @@ class Options(optmanager.OptManager):
self.add_option("intercept", None, Optional[str])
# Console options
self.add_option("console_eventlog", False, bool)
self.add_option("console_focus_follow", False, bool)
self.add_option(
"console_eventlog", False, bool,
help="Show event log."
)
self.add_option(
"console_focus_follow", False, bool,
"Focus follows new flows."
)
self.add_option("console_palette", "dark", Optional[str])
self.add_option("console_palette_transparent", False, bool)
self.add_option("console_no_mouse", False, bool)
self.add_option(
"console_palette_transparent", False, bool,
"Set transparent background for palette."
)
self.add_option(
"console_mouse", True, bool,
"Console mouse interaction."
)
self.add_option("console_order", None, Optional[str])
self.add_option("console_order_reversed", False, bool)
self.add_option(
"console_order_reversed", False, bool,
)
self.add_option("filter", None, Optional[str])
# Web options
self.add_option("web_open_browser", True, bool)
self.add_option("web_debug", False, bool)
self.add_option(
"web_open_browser", True, bool,
"Start a browser"
)
self.add_option(
"web_debug", False, bool,
"Mitmweb debugging"
)
self.add_option("web_port", 8081, int)
self.add_option("web_iface", "127.0.0.1", str)

View File

@ -21,19 +21,21 @@ unset = object()
class _Option:
__slots__ = ("name", "typespec", "value", "_default")
__slots__ = ("name", "typespec", "value", "_default", "help")
def __init__(
self,
name: str,
default: typing.Any,
typespec: typing.Type
typespec: typing.Type,
help: typing.Optional[str]
) -> None:
typecheck.check_type(name, default, typespec)
self.name = name
self._default = default
self.typespec = typespec
self.value = unset
self.help = help
def __repr__(self):
return "{value} [{type}]".format(value=self.current(), type=self.typespec)
@ -66,7 +68,7 @@ class _Option:
return True
def __deepcopy__(self, _):
o = _Option(self.name, self.default, self.typespec)
o = _Option(self.name, self.default, self.typespec, self.help)
if self.has_changed():
o.value = self.current()
return o
@ -91,10 +93,16 @@ class OptManager:
self.__dict__["changed"] = blinker.Signal()
self.__dict__["errored"] = blinker.Signal()
def add_option(self, name: str, default: typing.Any, typespec: typing.Type) -> None:
def add_option(
self,
name: str,
default: typing.Any,
typespec: typing.Type,
help: str = None
) -> None:
if name in self._options:
raise ValueError("Option %s already exists" % name)
self._options[name] = _Option(name, default, typespec)
self._options[name] = _Option(name, default, typespec, help)
@contextlib.contextmanager
def rollback(self, updated):
@ -303,3 +311,24 @@ class OptManager:
cls=type(self).__name__,
options=options
)
def make_parser(self, parser, option):
o = self._options[option]
f = option.replace("_", "-")
if o.typespec == bool:
g = parser.add_mutually_exclusive_group(required=False)
g.add_argument(
"--%s" % f,
action="store_true",
dest=option,
help=o.help
)
g.add_argument(
"--no-%s" % f,
action="store_false",
dest=option,
help=o.help
)
parser.set_defaults(**{option: o.default})
else:
raise ValueError("Unsupported option type: %s", o.typespec)

View File

@ -358,7 +358,7 @@ class TlsLayer(base.Layer):
# 2.5 The client did not sent a SNI value, we don't know the certificate subject.
client_tls_requires_server_connection = (
self._server_tls and
not self.config.options.no_upstream_cert and
self.config.options.upstream_cert and
(
self.config.options.add_upstream_certs_to_client_chain or
self._client_tls and (
@ -574,7 +574,7 @@ class TlsLayer(base.Layer):
use_upstream_cert = (
self.server_conn and
self.server_conn.tls_established and
(not self.config.options.no_upstream_cert)
self.config.options.upstream_cert
)
if use_upstream_cert:
upstream_cert = self.server_conn.cert

View File

@ -85,7 +85,7 @@ def get_common_options(args):
"are mutually exclusive. Read the docs on proxy modes "
"to understand why."
)
if args.add_upstream_certs_to_client_chain and args.no_upstream_cert:
if args.add_upstream_certs_to_client_chain and not args.upstream_cert:
raise exceptions.OptionsError(
"The no-upstream-cert and add-upstream-certs-to-client-chain "
"options are mutually exclusive. If no-upstream-cert is enabled "
@ -106,7 +106,7 @@ def get_common_options(args):
client_replay=args.client_replay,
replay_kill_extra=args.replay_kill_extra,
no_server=args.no_server,
refresh_server_playback=not args.norefresh,
refresh_server_playback=args.refresh_server_playback,
server_replay_use_headers=args.server_replay_use_headers,
rfile=args.rfile,
replacements=args.replacements,
@ -143,7 +143,7 @@ def get_common_options(args):
listen_port = args.port,
upstream_bind_address = args.upstream_bind_address,
mode = mode,
no_upstream_cert = args.no_upstream_cert,
upstream_cert = args.upstream_cert,
spoof_source_address = args.spoof_source_address,
http2 = args.http2,
@ -162,7 +162,7 @@ def get_common_options(args):
)
def basic_options(parser):
def basic_options(parser, opts):
parser.add_argument(
'--version',
action='store_true',
@ -174,24 +174,13 @@ def basic_options(parser):
help="show program's short version number and exit",
version=version.VERSION
)
parser.add_argument(
"--anticache",
action="store_true", dest="anticache",
help="""
Strip out request headers that might cause the server to return
304-not-modified.
"""
)
opts.make_parser(parser, "anticache")
parser.add_argument(
"--cadir",
action="store", type=str, dest="cadir",
help="Location of the default mitmproxy CA files. (%s)" % options.CA_DIR
)
parser.add_argument(
"--host",
action="store_true", dest="showhost",
help="Use the Host header to construct URLs for display."
)
opts.make_parser(parser, "showhost")
parser.add_argument(
"-q", "--quiet",
action="store_true", dest="quiet",
@ -239,11 +228,7 @@ def basic_options(parser):
action="store", dest="streamfile", type=lambda f: (f, "a"),
help="Append flows to file."
)
parser.add_argument(
"-z", "--anticomp",
action="store_true", dest="anticomp",
help="Try to convince servers to send us un-compressed data."
)
opts.make_parser(parser, "anticomp")
parser.add_argument(
"-Z", "--body-size-limit",
action="store", dest="body_size_limit",
@ -263,7 +248,7 @@ def basic_options(parser):
)
def proxy_modes(parser):
def proxy_modes(parser, opts):
group = parser.add_argument_group("Proxy Modes")
group.add_argument(
"-R", "--reverse",
@ -296,7 +281,7 @@ def proxy_modes(parser):
)
def proxy_options(parser):
def proxy_options(parser, opts):
group = parser.add_argument_group("Proxy Options")
group.add_argument(
"-b", "--bind-address",
@ -326,11 +311,7 @@ def proxy_options(parser):
communication contents are printed to the log in verbose mode.
"""
)
group.add_argument(
"-n", "--no-server",
action="store_true", dest="no_server",
help="Don't start a proxy server."
)
opts.make_parser(group, "no_server")
group.add_argument(
"-p", "--port",
action="store", type=int, dest="port",
@ -338,26 +319,11 @@ def proxy_options(parser):
)
http2 = group.add_mutually_exclusive_group()
http2.add_argument("--no-http2", action="store_false", dest="http2")
http2.add_argument("--http2", action="store_true", dest="http2",
help="Explicitly enable/disable HTTP/2 support. "
"HTTP/2 support is enabled by default.",
)
http2_priority = group.add_mutually_exclusive_group()
http2_priority.add_argument("--http2-priority", action="store_true", dest="http2_priority")
http2_priority.add_argument("--no-http2-priority", action="store_false", dest="http2_priority",
help="Explicitly enable/disable PRIORITY forwarding for HTTP/2 connections. "
"PRIORITY forwarding is disabled by default, "
"because some webservers fail at implementing the RFC properly.",
)
opts.make_parser(http2, "http2")
opts.make_parser(http2, "http2_priority")
websocket = group.add_mutually_exclusive_group()
websocket.add_argument("--no-websocket", action="store_false", dest="websocket")
websocket.add_argument("--websocket", action="store_true", dest="websocket",
help="Explicitly enable/disable WebSocket support. "
"WebSocket support is enabled by default.",
)
opts.make_parser(websocket, "websocket")
parser.add_argument(
"--upstream-auth",
@ -369,33 +335,18 @@ def proxy_options(parser):
"""
)
rawtcp = group.add_mutually_exclusive_group()
rawtcp.add_argument("--raw-tcp", action="store_true", dest="rawtcp")
rawtcp.add_argument("--no-raw-tcp", action="store_false", dest="rawtcp",
help="Explicitly enable/disable experimental raw tcp support. "
"Disabled by default. "
"Default value will change in a future version."
)
opts.make_parser(group, "rawtcp")
group.add_argument(
"--spoof-source-address",
action="store_true", dest="spoof_source_address",
help="Use the client's IP for server-side connections. "
"Combine with --upstream-bind-address to spoof a fixed source address."
)
opts.make_parser(group, "spoof_source_address")
group.add_argument(
"--upstream-bind-address",
action="store", type=str, dest="upstream_bind_address",
help="Address to bind upstream requests to (defaults to none)"
)
group.add_argument(
"--keep-host-header",
action="store_true", dest="keep_host_header",
help="Reverse Proxy: Keep the original host header instead of rewriting it to the reverse proxy target."
)
opts.make_parser(group, "keep_host_header")
def proxy_ssl_options(parser):
def proxy_ssl_options(parser, opts):
# TODO: Agree to consistently either use "upstream" or "server".
group = parser.add_argument_group("SSL")
group.add_argument(
@ -425,22 +376,9 @@ def proxy_ssl_options(parser):
type=str, dest="clientcerts",
help="Client certificate file or directory."
)
group.add_argument(
"--no-upstream-cert",
action="store_true", dest="no_upstream_cert",
help="Don't connect to upstream server to look up certificate details."
)
group.add_argument(
"--add-upstream-certs-to-client-chain",
action="store_true", dest="add_upstream_certs_to_client_chain",
help="Add all certificates of the upstream server to the certificate chain "
"that will be served to the proxy client, as extras."
)
group.add_argument(
"--insecure",
action="store_true", dest="ssl_insecure",
help="Do not verify upstream server SSL/TLS certificates."
)
opts.make_parser(group, "upstream_cert")
opts.make_parser(group, "add_upstream_certs_to_client_chain")
opts.make_parser(group, "ssl_insecure")
group.add_argument(
"--upstream-trusted-cadir", action="store",
dest="ssl_verify_upstream_trusted_cadir",
@ -468,13 +406,9 @@ def proxy_ssl_options(parser):
)
def onboarding_app(parser):
def onboarding_app(parser, opts):
group = parser.add_argument_group("Onboarding App")
group.add_argument(
"--no-onboarding",
action="store_false", dest="onboarding",
help="Disable the mitmproxy onboarding app."
)
opts.make_parser(parser, "onboarding")
group.add_argument(
"--onboarding-host",
action="store", dest="onboarding_host",
@ -494,7 +428,7 @@ def onboarding_app(parser):
)
def client_replay(parser):
def client_replay(parser, opts):
group = parser.add_argument_group("Client Replay")
group.add_argument(
"-c", "--client-replay",
@ -503,46 +437,24 @@ def client_replay(parser):
)
def server_replay(parser):
def server_replay(parser, opts):
group = parser.add_argument_group("Server Replay")
group.add_argument(
"-S", "--server-replay",
action="append", dest="server_replay", metavar="PATH",
help="Replay server responses from a saved file."
)
group.add_argument(
"-k", "--replay-kill-extra",
action="store_true", dest="replay_kill_extra",
help="Kill extra requests during replay."
)
opts.make_parser(parser, "replay_kill_extra")
group.add_argument(
"--server-replay-use-header",
action="append", dest="server_replay_use_headers", type=str,
help="Request headers to be considered during replay. "
"Can be passed multiple times."
)
group.add_argument(
"--norefresh",
action="store_true", dest="norefresh",
help="""
Disable response refresh, which updates times in cookies and headers
for replayed responses.
"""
)
group.add_argument(
"--no-pop",
action="store_true", dest="server_replay_nopop",
help="Disable response pop from response flow. "
"This makes it possible to replay same response multiple times."
)
opts.make_parser(group, "refresh_server_playback")
opts.make_parser(group, "server_replay_nopop")
payload = group.add_mutually_exclusive_group()
payload.add_argument(
"--replay-ignore-content",
action="store_true", dest="server_replay_ignore_content",
help="""
Ignore request's content while searching for a saved flow to replay
"""
)
opts.make_parser(payload, "server_replay_ignore_content")
payload.add_argument(
"--replay-ignore-payload-param",
action="append", dest="server_replay_ignore_payload_params", type=str,
@ -561,14 +473,10 @@ def server_replay(parser):
to replay. Can be passed multiple times.
"""
)
group.add_argument(
"--replay-ignore-host",
action="store_true",
dest="server_replay_ignore_host",
help="Ignore request's destination host while searching for a saved flow to replay")
opts.make_parser(parser, "server_replay_ignore_host")
def replacements(parser):
def replacements(parser, opts):
group = parser.add_argument_group(
"Replacements",
"""
@ -594,7 +502,7 @@ def replacements(parser):
)
def set_headers(parser):
def set_headers(parser, opts):
group = parser.add_argument_group(
"Set Headers",
"""
@ -611,7 +519,7 @@ def set_headers(parser):
)
def proxy_authentication(parser):
def proxy_authentication(parser, opts):
group = parser.add_argument_group(
"Proxy Authentication",
"""
@ -619,12 +527,7 @@ def proxy_authentication(parser):
used for authenticating them.
"""
).add_mutually_exclusive_group()
group.add_argument(
"--nonanonymous",
action="store_true", dest="auth_nonanonymous",
help="Allow access to any user long as a credentials are specified."
)
opts.make_parser(group, "auth_nonanonymous")
group.add_argument(
"--singleuser",
action="store", dest="auth_singleuser", type=str,
@ -642,7 +545,7 @@ def proxy_authentication(parser):
)
def common_options(parser):
def common_options(parser, opts):
parser.add_argument(
"--conf",
type=str, dest="conf", default=CONFIG_PATH,
@ -651,58 +554,41 @@ def common_options(parser):
Configuration file
"""
)
basic_options(parser)
proxy_modes(parser)
proxy_options(parser)
proxy_ssl_options(parser)
onboarding_app(parser)
client_replay(parser)
server_replay(parser)
replacements(parser)
set_headers(parser)
proxy_authentication(parser)
basic_options(parser, opts)
proxy_modes(parser, opts)
proxy_options(parser, opts)
proxy_ssl_options(parser, opts)
onboarding_app(parser, opts)
client_replay(parser, opts)
server_replay(parser, opts)
replacements(parser, opts)
set_headers(parser, opts)
proxy_authentication(parser, opts)
def mitmproxy():
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)
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())
)
parser.add_argument(
"--palette-transparent",
action="store_true", dest="console_palette_transparent",
help="Set transparent background for palette."
)
parser.add_argument(
"-e", "--eventlog",
action="store_true", dest="console_eventlog",
help="Show event log."
)
parser.add_argument(
"--follow",
action="store_true", dest="console_focus_follow",
help="Focus follows new flows."
)
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."
)
parser.add_argument(
"--no-mouse",
action="store_true", dest="console_no_mouse",
help="Disable mouse interaction."
)
opts.make_parser(parser, "console_mouse")
group = parser.add_argument_group(
"Filters",
"See help in mitmproxy for filter expression syntax."
@ -720,18 +606,11 @@ def mitmproxy():
return parser
def mitmdump():
def mitmdump(opts):
parser = argparse.ArgumentParser(usage="%(prog)s [options] [filter]")
common_options(parser)
parser.add_argument(
"--keepserving",
action="store_true", dest="keepserving",
help="""
Continue serving after client playback or file read. We exit by
default.
"""
)
common_options(parser, opts)
opts.make_parser(parser, "keepserving")
parser.add_argument(
"-d", "--detail",
action="count", dest="flow_detail",
@ -748,15 +627,11 @@ def mitmdump():
return parser
def mitmweb():
def mitmweb(opts):
parser = argparse.ArgumentParser(usage="%(prog)s [options]")
group = parser.add_argument_group("Mitmweb")
group.add_argument(
"--no-browser",
action="store_false", dest="web_open_browser",
help="Don't start a browser"
)
opts.make_parser(group, "web_open_browser")
group.add_argument(
"--web-port",
action="store", type=int, dest="web_port",
@ -769,13 +644,9 @@ def mitmweb():
metavar="IFACE",
help="Mitmweb interface."
)
group.add_argument(
"--web-debug",
action="store_true", dest="web_debug",
help="Turn on mitmweb debugging"
)
opts.make_parser(group, "web_debug")
common_options(parser)
common_options(parser, opts)
group = parser.add_argument_group(
"Filters",
"See help in mitmproxy for filter expression syntax."

View File

@ -252,7 +252,7 @@ class ConsoleMaster(master.Master):
self.loop = urwid.MainLoop(
urwid.SolidFill("x"),
screen = self.ui,
handle_mouse = not self.options.console_no_mouse,
handle_mouse = self.options.console_mouse,
)
self.ab = statusbar.ActionBar()

View File

@ -90,10 +90,10 @@ class Options(urwid.WidgetWrap):
select.Heading("Network"),
select.Option(
"No Upstream Certs",
"Upstream Certs",
"U",
checker("no_upstream_cert", master.options),
master.options.toggler("no_upstream_cert")
checker("upstream_cert", master.options),
master.options.toggler("upstream_cert")
),
select.Option(
"TCP Proxying",

View File

@ -220,7 +220,7 @@ class StatusBar(urwid.WidgetWrap):
opts.append("norefresh")
if self.master.options.replay_kill_extra:
opts.append("killextra")
if self.master.options.no_upstream_cert:
if not self.master.options.upstream_cert:
opts.append("no-upstream-cert")
if self.master.options.console_focus_follow:
opts.append("following")

View File

@ -61,11 +61,11 @@ def mitmproxy(args=None): # pragma: no cover
version_check.check_pyopenssl_version()
assert_utf8_env()
parser = cmdline.mitmproxy()
console_options = options.Options()
parser = cmdline.mitmproxy(console_options)
args = parser.parse_args(args)
try:
console_options = options.Options()
console_options.load_paths(args.conf)
console_options.merge(cmdline.get_common_options(args))
console_options.merge(
@ -74,7 +74,7 @@ def mitmproxy(args=None): # pragma: no cover
console_palette_transparent = args.console_palette_transparent,
console_eventlog = args.console_eventlog,
console_focus_follow = args.console_focus_follow,
console_no_mouse = args.console_no_mouse,
console_mouse = args.console_mouse,
console_order = args.console_order,
filter = args.filter,
@ -98,14 +98,14 @@ def mitmdump(args=None): # pragma: no cover
version_check.check_pyopenssl_version()
parser = cmdline.mitmdump()
dump_options = options.Options()
parser = cmdline.mitmdump(dump_options)
args = parser.parse_args(args)
if args.quiet:
args.flow_detail = 0
master = None
try:
dump_options = options.Options()
dump_options.load_paths(args.conf)
dump_options.merge(cmdline.get_common_options(args))
dump_options.merge(
@ -139,12 +139,11 @@ def mitmweb(args=None): # pragma: no cover
version_check.check_pyopenssl_version()
parser = cmdline.mitmweb()
web_options = options.Options()
parser = cmdline.mitmweb(web_options)
args = parser.parse_args(args)
try:
web_options = options.Options()
web_options.load_paths(args.conf)
web_options.merge(cmdline.get_common_options(args))
web_options.merge(

View File

@ -408,7 +408,7 @@ class Settings(RequestHandler):
mode=str(self.master.options.mode),
intercept=self.master.options.intercept,
showhost=self.master.options.showhost,
no_upstream_cert=self.master.options.no_upstream_cert,
upstream_cert=self.master.options.upstream_cert,
rawtcp=self.master.options.rawtcp,
http2=self.master.options.http2,
websocket=self.master.options.websocket,
@ -425,7 +425,7 @@ class Settings(RequestHandler):
def put(self):
update = self.json
option_whitelist = {
"intercept", "showhost", "no_upstream_cert",
"intercept", "showhost", "upstream_cert",
"rawtcp", "http2", "websocket", "anticache", "anticomp",
"stickycookie", "stickyauth", "stream_large_bodies"
}

View File

@ -100,7 +100,7 @@ class _Http2TestBase:
def get_options(cls):
opts = options.Options(
listen_port=0,
no_upstream_cert=False,
upstream_cert=True,
ssl_insecure=True
)
opts.cadir = os.path.join(tempfile.gettempdir(), "mitmproxy")

View File

@ -64,7 +64,7 @@ class _WebSocketTestBase:
def get_options(cls):
opts = options.Options(
listen_port=0,
no_upstream_cert=False,
upstream_cert=True,
ssl_insecure=True,
websocket=True,
)

View File

@ -870,11 +870,11 @@ class TestServerConnect(tservers.HTTPProxyTest):
@classmethod
def get_options(cls):
opts = tservers.HTTPProxyTest.get_options()
opts.no_upstream_cert = True
opts.upstream_cert = False
return opts
def test_unnecessary_serverconnect(self):
"""A replayed/fake response with no_upstream_cert should not connect to an upstream server"""
"""A replayed/fake response with no upstream_cert should not connect to an upstream server"""
assert self.pathod("200").status_code == 200
for msg in self.proxy.tmaster.tlog:
assert "serverconnect" not in msg

View File

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

View File

@ -30,9 +30,9 @@ class TestProcessProxyOptions:
def p(self, *args):
parser = MockParser()
cmdline.common_options(parser)
args = parser.parse_args(args=args)
opts = options.Options()
cmdline.common_options(parser, opts)
args = parser.parse_args(args=args)
opts.merge(cmdline.get_common_options(args))
pconf = config.ProxyConfig(opts)
return parser, pconf
@ -91,7 +91,7 @@ class TestProcessProxyOptions:
self.p("--cert", "nonexistent")
def test_insecure(self):
p = self.assert_noerr("--insecure")
p = self.assert_noerr("--ssl-insecure")
assert p.openssl_verification_mode_server == SSL.VERIFY_NONE
def test_upstream_trusted_cadir(self):

View File

@ -1,31 +1,36 @@
import argparse
from mitmproxy.tools import cmdline
from mitmproxy import options
def test_common():
parser = argparse.ArgumentParser()
cmdline.common_options(parser)
opts = parser.parse_args(args=[])
opts = options.Options()
cmdline.common_options(parser, opts)
args = parser.parse_args(args=[])
assert cmdline.get_common_options(opts)
assert cmdline.get_common_options(args)
opts.stickycookie_filt = "foo"
opts.stickyauth_filt = "foo"
v = cmdline.get_common_options(opts)
args.stickycookie_filt = "foo"
args.stickyauth_filt = "foo"
v = cmdline.get_common_options(args)
assert v["stickycookie"] == "foo"
assert v["stickyauth"] == "foo"
def test_mitmproxy():
ap = cmdline.mitmproxy()
opts = options.Options()
ap = cmdline.mitmproxy(opts)
assert ap
def test_mitmdump():
ap = cmdline.mitmdump()
opts = options.Options()
ap = cmdline.mitmdump(opts)
assert ap
def test_mitmweb():
ap = cmdline.mitmweb()
opts = options.Options()
ap = cmdline.mitmweb(opts)
assert ap

View File

@ -30,6 +30,7 @@ commands =
mypy --ignore-missing-imports --follow-imports=skip \
mitmproxy/addons/ \
mitmproxy/addonmanager.py \
mitmproxy/optmanager.py \
mitmproxy/proxy/protocol/ \
mitmproxy/log.py \
mitmproxy/tools/dump.py \