aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAldo Cortesi <aldo@corte.si>2017-03-17 11:16:34 +1300
committerAldo Cortesi <aldo@corte.si>2017-03-19 10:32:22 +1300
commitd759150734e19c1b253ca112b723440c4e773074 (patch)
tree75d61215ebaeaec52fecafe541f4da9eb6291a5f
parent8130b9880a1f22c477adf5f7bcfd5e1936ae550e (diff)
downloadmitmproxy-d759150734e19c1b253ca112b723440c4e773074.tar.gz
mitmproxy-d759150734e19c1b253ca112b723440c4e773074.tar.bz2
mitmproxy-d759150734e19c1b253ca112b723440c4e773074.zip
console: options/help pane switching, toggle bools with enter
-rw-r--r--mitmproxy/options.py36
-rw-r--r--mitmproxy/tools/console/options.py72
2 files changed, 77 insertions, 31 deletions
diff --git a/mitmproxy/options.py b/mitmproxy/options.py
index 1b66790f..9232378f 100644
--- a/mitmproxy/options.py
+++ b/mitmproxy/options.py
@@ -43,8 +43,9 @@ class Options(optmanager.OptManager):
self.add_option(
"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. """
+ Onboarding app domain. For transparent mode, use an IP when a DNS
+ entry for the app domain is not present.
+ """
)
self.add_option(
"onboarding_port", int, APP_PORT,
@@ -72,9 +73,9 @@ class Options(optmanager.OptManager):
self.add_option(
"keepserving", bool, False,
"""
- Instructs mitmdump to continue serving after client playback, server
- playback or file read. This option is ignored by interactive tools,
- which always keep serving.
+ Continue serving after client playback, server playback or file
+ read. This option is ignored by interactive tools, which always keep
+ serving.
"""
)
self.add_option(
@@ -84,8 +85,8 @@ class Options(optmanager.OptManager):
self.add_option(
"server_replay_nopop", bool, False,
"""
- Disable response pop from response flow. This makes it possible to
- replay same response multiple times.
+ Don't remove flows from server replay state after use. This makes it
+ possible to replay same response multiple times.
"""
)
self.add_option(
@@ -190,11 +191,10 @@ class Options(optmanager.OptManager):
self.add_option(
"proxyauth", Optional[str], None,
"""
- Require authentication before proxying requests. If the value is
- "any", we prompt for authentication, but permit any values. If it
- starts with an "@", it is treated as a path to an Apache htpasswd
- file. If its is of the form "username:password", it is treated as a
- single-user credential.
+ Require proxy authentication. Value may be "any" to require
+ authenticaiton but accept any credentials, start with "@" to specify
+ a path to an Apache htpasswd file, or be of the form
+ "username:password".
"""
)
self.add_option(
@@ -218,12 +218,12 @@ class Options(optmanager.OptManager):
self.add_option(
"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.
- The file at path is a certificate in PEM format. If a private key is
- included in the PEM, it is used, else the default key in the conf
- dir is used. The PEM file should contain the full certificate chain,
- with the leaf certificate as the first entry.
+ SSL certificates of the form "[domain=]path". The domain may include
+ a wildcard, and is equal to "*" if not specified. The file at path
+ is a certificate in PEM format. If a private key is included in the
+ PEM, it is used, else the default key in the conf dir is used. The
+ PEM file should contain the full certificate chain, with the leaf
+ certificate as the first entry.
"""
)
self.add_option(
diff --git a/mitmproxy/tools/console/options.py b/mitmproxy/tools/console/options.py
index 903bde5b..94b80f83 100644
--- a/mitmproxy/tools/console/options.py
+++ b/mitmproxy/tools/console/options.py
@@ -55,15 +55,22 @@ class OptionItem(urwid.WidgetWrap):
displayval = str(val)
changed = self.master.options.has_changed(self.opt.name)
- namestyle = "option_selected" if self.focused else "title"
- valstyle = "option_active" if changed else "text"
+ if self.focused:
+ valstyle = "option_active_selected" if changed else "option_selected"
+ else:
+ valstyle = "option_active" if changed else "text"
return urwid.Columns(
[
(
self.namewidth,
- urwid.Text([(namestyle, self.opt.name.ljust(self.namewidth))])
+ urwid.Text([("title", self.opt.name.ljust(self.namewidth))])
),
- urwid.Text([(valstyle, displayval)])
+ urwid.AttrMap(
+ urwid.Padding(
+ urwid.Text([(valstyle, displayval)])
+ ),
+ valstyle
+ )
],
dividechars=2
)
@@ -72,8 +79,15 @@ class OptionItem(urwid.WidgetWrap):
return True
def keypress(self, xxx_todo_changeme, key):
- key = common.shortcuts(key)
- return key
+ if key == "enter":
+ if self.opt.typespec == bool:
+ setattr(
+ self.master.options,
+ self.opt.name,
+ not self.opt.current()
+ )
+ else:
+ return key
class OptionListWalker(urwid.ListWalker):
@@ -86,6 +100,10 @@ class OptionListWalker(urwid.ListWalker):
# Trigger a help text update for the first selected item
first = self.master.options._options[self.opts[0]]
option_focus_change.send(first.help)
+ self.master.options.changed.connect(self.sig_mod)
+
+ def sig_mod(self, *args, **kwargs):
+ self._modified()
def _get(self, pos):
name = self.opts[pos]
@@ -121,19 +139,28 @@ class OptionsList(urwid.ListBox):
class OptionHelp(urwid.Frame):
- def __init__(self):
+ def __init__(self, master):
+ self.master = master
+
h = urwid.Text("Option Help")
h = urwid.Padding(h, align="left", width=("relative", 100))
- h = urwid.AttrWrap(h, "heading")
- super().__init__(self.widget(""), header=h)
+
+ self.inactive_header = urwid.AttrWrap(h, "heading_inactive")
+ self.active_header = urwid.AttrWrap(h, "heading")
+
+ super().__init__(self.widget(""), header=self.inactive_header)
option_focus_change.connect(self.sig_mod)
- def selectable(self):
- return False
+ def active(self, val):
+ if val:
+ self.header = self.active_header
+ else:
+ self.header = self.inactive_header
def widget(self, txt):
+ cols, _ = self.master.ui.get_cols_rows()
return urwid.ListBox(
- [urwid.Text(i) for i in textwrap.wrap(txt)]
+ [urwid.Text(i) for i in textwrap.wrap(txt, cols)]
)
def sig_mod(self, txt):
@@ -142,7 +169,7 @@ class OptionHelp(urwid.Frame):
class Options(urwid.Pile):
def __init__(self, master):
- oh = OptionHelp()
+ oh = OptionHelp(master)
super().__init__(
[
OptionsList(master),
@@ -150,3 +177,22 @@ class Options(urwid.Pile):
]
)
self.master = master
+
+ def keypress(self, size, key):
+ key = common.shortcuts(key)
+ if key == "tab":
+ self.focus_position = (
+ self.focus_position + 1
+ ) % len(self.widget_list)
+ self.widget_list[1].active(self.focus_position == 1)
+ key = None
+
+ # This is essentially a copypasta from urwid.Pile's keypress handler.
+ # So much for "closed for modification, but open for extension".
+ item_rows = None
+ if len(size) == 2:
+ item_rows = self.get_item_rows(size, focus = True)
+ i = self.widget_list.index(self.focus_item)
+ tsize = self.get_item_size(size, i, True, item_rows)
+ return self.focus_item.keypress(tsize, key)
+