aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAldo Cortesi <aldo@nullcube.com>2017-03-07 14:27:50 +1300
committerAldo Cortesi <aldo@nullcube.com>2017-03-07 14:27:50 +1300
commitac3b0d69cc29b5469f6b4cc55af528f6266d42cf (patch)
tree780efa34b2ec94bea4814febca7a4a8578d9a2ac
parent79f5883c2fbe475269a02920aaaad053e797abec (diff)
downloadmitmproxy-ac3b0d69cc29b5469f6b4cc55af528f6266d42cf.tar.gz
mitmproxy-ac3b0d69cc29b5469f6b4cc55af528f6266d42cf.tar.bz2
mitmproxy-ac3b0d69cc29b5469f6b4cc55af528f6266d42cf.zip
Add the --set option to set options directly
The --set option is a universal flag for setting options. Some examples: Turn on a boolean: mitmdump --set onboarding=false Add a value to a sequence: mitumdupm --set setheaders=/foo/bar/voing Zero a sequence: mitumdupm --set setheaders
-rw-r--r--mitmproxy/optmanager.py39
-rw-r--r--mitmproxy/tools/cmdline.py24
-rw-r--r--mitmproxy/tools/main.py3
-rw-r--r--test/mitmproxy/test_optmanager.py40
4 files changed, 100 insertions, 6 deletions
diff --git a/mitmproxy/optmanager.py b/mitmproxy/optmanager.py
index beb9084c..eb56ef2d 100644
--- a/mitmproxy/optmanager.py
+++ b/mitmproxy/optmanager.py
@@ -323,6 +323,45 @@ class OptManager:
options=options
)
+ def set(self, spec):
+ parts = spec.split("=", maxsplit=1)
+ if len(parts) == 1:
+ optname, optval = parts[0], None
+ else:
+ optname, optval = parts[0], parts[1]
+ o = self._options[optname]
+
+ if o.typespec in (str, typing.Optional[str]):
+ setattr(self, optname, optval)
+ elif o.typespec in (int, typing.Optional[int]):
+ if optval:
+ try:
+ optval = int(optval)
+ except ValueError:
+ raise exceptions.OptionsError("Not an integer: %s" % optval)
+ setattr(self, optname, optval)
+ elif o.typespec == bool:
+ if not optval or optval == "true":
+ v = True
+ elif optval == "false":
+ v = False
+ else:
+ raise exceptions.OptionsError(
+ "Boolean must be \"true\", \"false\", or have the value " "omitted (a synonym for \"true\")."
+ )
+ setattr(self, optname, v)
+ elif o.typespec == typing.Sequence[str]:
+ if not optval:
+ setattr(self, optname, [])
+ else:
+ setattr(
+ self,
+ optname,
+ getattr(self, optname) + [optval]
+ )
+ else:
+ raise ValueError("Unsupported option type: %s", o.typespec)
+
def make_parser(self, parser, optname, metavar=None):
o = self._options[optname]
f = optname.replace("_", "-")
diff --git a/mitmproxy/tools/cmdline.py b/mitmproxy/tools/cmdline.py
index 7b0da34f..ea77acfd 100644
--- a/mitmproxy/tools/cmdline.py
+++ b/mitmproxy/tools/cmdline.py
@@ -26,6 +26,24 @@ def common_options(parser, opts):
help="Dump all options",
)
parser.add_argument(
+ "--conf",
+ type=str, dest="conf", default=CONFIG_PATH,
+ metavar="PATH",
+ help="Read options from a configuration file"
+ )
+ parser.add_argument(
+ "--set",
+ type=str, dest="setoptions", default=[],
+ action="append",
+ metavar="option[=value]",
+ help="""
+ Set an option. When the value is omitted, booleans are set to true,
+ strings and integers are set to None (if permitted), and sequences
+ are emptied.
+ """
+ )
+
+ parser.add_argument(
"-q", "--quiet",
action="store_true", dest="quiet",
help="Quiet."
@@ -35,12 +53,6 @@ def common_options(parser, opts):
action="store_const", dest="verbose", const=3,
help="Increase log verbosity."
)
- parser.add_argument(
- "--conf",
- type=str, dest="conf", default=CONFIG_PATH,
- metavar="PATH",
- help="Configuration file"
- )
# Basic options
opts.make_parser(parser, "mode")
diff --git a/mitmproxy/tools/main.py b/mitmproxy/tools/main.py
index 5c58d995..7c1e7b32 100644
--- a/mitmproxy/tools/main.py
+++ b/mitmproxy/tools/main.py
@@ -45,6 +45,9 @@ def process_options(parser, opts, args):
if args.quiet:
args.flow_detail = 0
+ for i in args.setoptions:
+ opts.set(i)
+
adict = {}
for n in dir(args):
if n in opts:
diff --git a/test/mitmproxy/test_optmanager.py b/test/mitmproxy/test_optmanager.py
index 010fc339..9311e82d 100644
--- a/test/mitmproxy/test_optmanager.py
+++ b/test/mitmproxy/test_optmanager.py
@@ -292,8 +292,10 @@ class TTypes(optmanager.OptManager):
def __init__(self):
super().__init__()
self.add_option("str", "str", str)
+ self.add_option("optstr", "optstr", typing.Optional[str])
self.add_option("bool", False, bool)
self.add_option("int", 0, int)
+ self.add_option("optint", 0, typing.Optional[int])
self.add_option("seqstr", [], typing.Sequence[str])
self.add_option("unknown", 0.0, float)
@@ -307,3 +309,41 @@ def test_make_parser():
opts.make_parser(parser, "seqstr")
with pytest.raises(ValueError):
opts.make_parser(parser, "unknown")
+
+
+def test_set():
+ opts = TTypes()
+
+ opts.set("str=foo")
+ assert opts.str == "foo"
+ with pytest.raises(TypeError):
+ opts.set("str")
+
+ opts.set("optstr=foo")
+ assert opts.optstr == "foo"
+ opts.set("optstr")
+ assert opts.optstr is None
+
+ opts.set("bool=false")
+ assert opts.bool is False
+ opts.set("bool")
+ assert opts.bool is True
+ opts.set("bool=true")
+ assert opts.bool is True
+ with pytest.raises(exceptions.OptionsError):
+ opts.set("bool=wobble")
+
+ opts.set("int=1")
+ assert opts.int == 1
+ with pytest.raises(exceptions.OptionsError):
+ opts.set("int=wobble")
+ opts.set("optint")
+ assert opts.optint is None
+
+ assert opts.seqstr == []
+ opts.set("seqstr=foo")
+ assert opts.seqstr == ["foo"]
+ opts.set("seqstr=bar")
+ assert opts.seqstr == ["foo", "bar"]
+ opts.set("seqstr")
+ assert opts.seqstr == []