aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAldo Cortesi <aldo@nullcube.com>2017-03-05 20:10:06 +1300
committerAldo Cortesi <aldo@nullcube.com>2017-03-05 20:16:33 +1300
commitf15a6285613540e031b004b726799dd6edee5a27 (patch)
tree810ab7ac3c450415bdd83e864ba4704ce2e66fe5
parent67381ae550a5d57c1f2841cd7118550afdfaa736 (diff)
downloadmitmproxy-f15a6285613540e031b004b726799dd6edee5a27.tar.gz
mitmproxy-f15a6285613540e031b004b726799dd6edee5a27.tar.bz2
mitmproxy-f15a6285613540e031b004b726799dd6edee5a27.zip
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.
-rw-r--r--mitmproxy/options.py151
-rw-r--r--mitmproxy/optmanager.py39
-rw-r--r--mitmproxy/proxy/protocol/tls.py4
-rw-r--r--mitmproxy/tools/cmdline.py243
-rw-r--r--mitmproxy/tools/console/master.py2
-rw-r--r--mitmproxy/tools/console/options.py6
-rw-r--r--mitmproxy/tools/console/statusbar.py2
-rw-r--r--mitmproxy/tools/main.py15
-rw-r--r--mitmproxy/tools/web/app.py4
-rw-r--r--test/mitmproxy/proxy/protocol/test_http2.py2
-rw-r--r--test/mitmproxy/proxy/protocol/test_websocket.py2
-rw-r--r--test/mitmproxy/proxy/test_server.py4
-rw-r--r--test/mitmproxy/test_optmanager.py6
-rw-r--r--test/mitmproxy/test_proxy.py6
-rw-r--r--test/mitmproxy/tools/test_cmdline.py23
-rw-r--r--tox.ini1
16 files changed, 255 insertions, 255 deletions
diff --git a/mitmproxy/options.py b/mitmproxy/options.py
index 16009316..1d879ac8 100644
--- a/mitmproxy/options.py
+++ b/mitmproxy/options.py
@@ -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)
diff --git a/mitmproxy/optmanager.py b/mitmproxy/optmanager.py
index 4b5a710e..240e3642 100644
--- a/mitmproxy/optmanager.py
+++ b/mitmproxy/optmanager.py
@@ -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)
diff --git a/mitmproxy/proxy/protocol/tls.py b/mitmproxy/proxy/protocol/tls.py
index 7d15130f..103d96cc 100644
--- a/mitmproxy/proxy/protocol/tls.py
+++ b/mitmproxy/proxy/protocol/tls.py
@@ -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
diff --git a/mitmproxy/tools/cmdline.py b/mitmproxy/tools/cmdline.py
index 11558cc3..41f4cedb 100644
--- a/mitmproxy/tools/cmdline.py
+++ b/mitmproxy/tools/cmdline.py
@@ -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."
diff --git a/mitmproxy/tools/console/master.py b/mitmproxy/tools/console/master.py
index d68dc93c..e75105cf 100644
--- a/mitmproxy/tools/console/master.py
+++ b/mitmproxy/tools/console/master.py
@@ -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()
diff --git a/mitmproxy/tools/console/options.py b/mitmproxy/tools/console/options.py
index 4115bd18..33e3ec38 100644
--- a/mitmproxy/tools/console/options.py
+++ b/mitmproxy/tools/console/options.py
@@ -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",
diff --git a/mitmproxy/tools/console/statusbar.py b/mitmproxy/tools/console/statusbar.py
index d90d932b..a5611b28 100644
--- a/mitmproxy/tools/console/statusbar.py
+++ b/mitmproxy/tools/console/statusbar.py
@@ -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")
diff --git a/mitmproxy/tools/main.py b/mitmproxy/tools/main.py
index ce78cd13..c0293f28 100644
--- a/mitmproxy/tools/main.py
+++ b/mitmproxy/tools/main.py
@@ -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(
diff --git a/mitmproxy/tools/web/app.py b/mitmproxy/tools/web/app.py
index 35b549ee..eddaa3e1 100644
--- a/mitmproxy/tools/web/app.py
+++ b/mitmproxy/tools/web/app.py
@@ -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"
}
diff --git a/test/mitmproxy/proxy/protocol/test_http2.py b/test/mitmproxy/proxy/protocol/test_http2.py
index 871d02fe..770c6550 100644
--- a/test/mitmproxy/proxy/protocol/test_http2.py
+++ b/test/mitmproxy/proxy/protocol/test_http2.py
@@ -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")
diff --git a/test/mitmproxy/proxy/protocol/test_websocket.py b/test/mitmproxy/proxy/protocol/test_websocket.py
index bac0e527..486e9d64 100644
--- a/test/mitmproxy/proxy/protocol/test_websocket.py
+++ b/test/mitmproxy/proxy/protocol/test_websocket.py
@@ -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,
)
diff --git a/test/mitmproxy/proxy/test_server.py b/test/mitmproxy/proxy/test_server.py
index 56b09b9a..eb40dd14 100644
--- a/test/mitmproxy/proxy/test_server.py
+++ b/test/mitmproxy/proxy/test_server.py
@@ -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
diff --git a/test/mitmproxy/test_optmanager.py b/test/mitmproxy/test_optmanager.py
index 3fba304a..44c757af 100644
--- a/test/mitmproxy/test_optmanager.py
+++ b/test/mitmproxy/test_optmanager.py
@@ -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
diff --git a/test/mitmproxy/test_proxy.py b/test/mitmproxy/test_proxy.py
index 37cec57a..6e360875 100644
--- a/test/mitmproxy/test_proxy.py
+++ b/test/mitmproxy/test_proxy.py
@@ -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):
diff --git a/test/mitmproxy/tools/test_cmdline.py b/test/mitmproxy/tools/test_cmdline.py
index 96d5ae31..b9f9d00d 100644
--- a/test/mitmproxy/tools/test_cmdline.py
+++ b/test/mitmproxy/tools/test_cmdline.py
@@ -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
diff --git a/tox.ini b/tox.ini
index 4994b119..a9904e87 100644
--- a/tox.ini
+++ b/tox.ini
@@ -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 \