aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJim Shaver <dcypherd@gmail.com>2015-03-19 15:58:53 -0400
committerJim Shaver <dcypherd@gmail.com>2015-03-19 15:58:53 -0400
commit998c9c49c44969b0e5421c649cfb714e5f578dda (patch)
tree41821482f4bf1db2ebdb1d8aad2be9de40f2ccfd
parent36bec7b77e1a8c02211c706b3e651fee13a3b3e2 (diff)
parent97c6d7ed25e026ae8d5511550df9718f829a7f1e (diff)
downloadmitmproxy-998c9c49c44969b0e5421c649cfb714e5f578dda.tar.gz
mitmproxy-998c9c49c44969b0e5421c649cfb714e5f578dda.tar.bz2
mitmproxy-998c9c49c44969b0e5421c649cfb714e5f578dda.zip
Merge branch 'master' of github.com:mitmproxy/mitmproxy into ssldocs
-rw-r--r--libmproxy/console/__init__.py2
-rw-r--r--libmproxy/console/flowdetailview.py2
-rw-r--r--libmproxy/console/help.py2
-rw-r--r--libmproxy/console/palettes.py447
-rw-r--r--libmproxy/onboarding/app.py36
-rw-r--r--test/test_console_help.py10
-rw-r--r--test/test_console_palettes.py11
-rw-r--r--test/test_dump.py7
-rwxr-xr-xtest/tools/testpatt9
9 files changed, 314 insertions, 212 deletions
diff --git a/libmproxy/console/__init__.py b/libmproxy/console/__init__.py
index 1b65ae68..198b7bbe 100644
--- a/libmproxy/console/__init__.py
+++ b/libmproxy/console/__init__.py
@@ -765,7 +765,7 @@ class ConsoleMaster(flow.FlowMaster):
def run(self):
self.ui = urwid.raw_display.Screen()
self.ui.set_terminal_properties(256)
- self.ui.register_palette(self.palette)
+ self.ui.register_palette(self.palette.palette())
self.flow_list_walker = flowlist.FlowListWalker(self, self.state)
self.view = None
self.statusbar = None
diff --git a/libmproxy/console/flowdetailview.py b/libmproxy/console/flowdetailview.py
index 4164c416..f351bff1 100644
--- a/libmproxy/console/flowdetailview.py
+++ b/libmproxy/console/flowdetailview.py
@@ -21,7 +21,7 @@ class FlowDetailsView(urwid.ListBox):
self.master.statusbar = self.state[0]
self.master.body = self.state[1]
self.master.header = self.state[2]
- self.master.make_view()
+ self.master.loop.widget = self.master.make_view()
return None
elif key == "?":
key = None
diff --git a/libmproxy/console/help.py b/libmproxy/console/help.py
index fddab537..6bb49a92 100644
--- a/libmproxy/console/help.py
+++ b/libmproxy/console/help.py
@@ -183,7 +183,7 @@ class HelpView(urwid.ListBox):
self.master.statusbar = self.state[0]
self.master.body = self.state[1]
self.master.header = self.state[2]
- self.master.make_view()
+ self.master.loop.widget = self.master.make_view()
return None
elif key == "?":
key = None
diff --git a/libmproxy/console/palettes.py b/libmproxy/console/palettes.py
index 650cf261..cfb2702c 100644
--- a/libmproxy/console/palettes.py
+++ b/libmproxy/console/palettes.py
@@ -1,192 +1,261 @@
-palettes = {
-# Default palette for dark background
- 'dark': [
- # name, foreground, background, mono, foreground_high, background_high
- # For details on the meaning of the elements refer to
- # http://excess.org/urwid/reference.html#Screen-register_palette
-
- ('body', 'black', 'dark cyan'),
- ('foot', 'light gray', 'default'),
- ('title', 'white,bold', 'default',),
- ('editline', 'white', 'default',),
-
- # Status bar & heading
- ('heading', 'light gray', 'dark blue', None, 'g85', 'dark blue'),
- ('heading_key', 'light cyan', 'dark blue', None, 'light cyan', 'dark blue'),
- ('heading_inactive', 'white', 'dark gray', None, 'g58', 'g11'),
-
- # Help
- ('key', 'light cyan', 'default'),
- ('head', 'white,bold', 'default'),
- ('text', 'light gray', 'default'),
-
- # List and Connections
- ('method', 'dark cyan', 'default'),
- ('focus', 'yellow', 'default'),
-
- ('code_200', 'light green', 'default'),
- ('code_300', 'light blue', 'default'),
- ('code_400', 'light red', 'default', None, '#f60', 'default'),
- ('code_500', 'light red', 'default'),
- ('code_other', 'dark red', 'default'),
-
- ('error', 'light red', 'default'),
-
- ('header', 'dark cyan', 'default'),
- ('highlight', 'white,bold', 'default'),
- ('intercept', 'brown', 'default', None, '#f60', 'default'),
- ('replay', 'light green', 'default', None, '#0f0', 'default'),
- ('ack', 'light red', 'default'),
-
- # Hex view
- ('offset', 'dark cyan', 'default'),
-
- # Grid Editor
- ('focusfield', 'black', 'light gray'),
- ('focusfield_error', 'dark red', 'light gray'),
- ('field_error', 'dark red', 'black'),
- ('editfield', 'black', 'light cyan'),
- ],
-
-# Palette for light background
- 'light': [
- ('body', 'black', 'dark cyan'),
- ('foot', 'dark gray', 'default'),
- ('title', 'white,bold', 'light blue',),
- ('editline', 'white', 'default',),
-
- # Status bar & heading
- ('heading', 'white', 'light gray', None, 'g85', 'dark blue'),
- ('heading_key', 'dark blue', 'light gray', None, 'light cyan', 'dark blue'),
- ('heading_inactive', 'light gray', 'dark gray', None, 'dark gray', 'dark blue'),
-
- # Help
- ('key', 'dark blue,bold', 'default'),
- ('head', 'black,bold', 'default'),
- ('text', 'dark gray', 'default'),
-
- # List and Connections
- ('method', 'dark cyan', 'default'),
- ('focus', 'black', 'default'),
-
- ('code_200', 'dark green', 'default'),
- ('code_300', 'light blue', 'default'),
- ('code_400', 'dark red', 'default', None, '#f60', 'default'),
- ('code_500', 'dark red', 'default'),
- ('code_other', 'light red', 'default'),
-
- ('error', 'light red', 'default'),
-
- ('header', 'dark blue', 'default'),
- ('highlight', 'black,bold', 'default'),
- ('intercept', 'brown', 'default', None, '#f60', 'default'),
- ('replay', 'dark green', 'default', None, '#0f0', 'default'),
- ('ack', 'dark red', 'default'),
-
- # Hex view
- ('offset', 'dark blue', 'default'),
-
- # Grid Editor
- ('focusfield', 'black', 'light gray'),
- ('focusfield_error', 'dark red', 'light gray'),
- ('field_error', 'dark red', 'black'),
- ('editfield', 'black', 'light cyan'),
- ],
-
-# Palettes for terminals that use the Solarized precision colors
-# (http://ethanschoonover.com/solarized#the-values)
-
-# For dark backgrounds
- 'solarized_dark': [
- ('body', 'dark cyan', 'default'),
- ('foot', 'dark gray', 'default'),
- ('title', 'white,bold', 'default',),
- ('editline', 'white', 'default',),
-
- # Status bar & heading
- ('heading', 'light gray', 'light cyan',),
- ('heading_key', 'dark blue', 'white',),
- ('heading_inactive', 'light cyan', 'light gray',),
-
- # Help
- ('key', 'dark blue', 'default',),
- ('head', 'white,underline', 'default'),
- ('text', 'light cyan', 'default'),
-
- # List and Connections
- ('method', 'dark cyan', 'default'),
- ('focus', 'white', 'default'),
-
- ('code_200', 'dark green', 'default'),
- ('code_300', 'light blue', 'default'),
- ('code_400', 'dark red', 'default',),
- ('code_500', 'dark red', 'default'),
- ('code_other', 'light red', 'default'),
-
- ('error', 'light red', 'default'),
-
- ('header', 'yellow', 'default'),
- ('highlight', 'white', 'default'),
- ('intercept', 'brown', 'default',),
- ('replay', 'dark green', 'default',),
- ('ack', 'dark red', 'default'),
-
- # Hex view
- ('offset', 'yellow', 'default'),
- ('text', 'light cyan', 'default'),
-
- # Grid Editor
- ('focusfield', 'white', 'light cyan'),
- ('focusfield_error', 'dark red', 'light gray'),
- ('field_error', 'dark red', 'black'),
- ('editfield', 'black', 'light gray'),
- ],
-
-# For light backgrounds
- 'solarized_light': [
- ('body', 'dark cyan', 'default'),
- ('foot', 'dark gray', 'default'),
- ('title', 'white,bold', 'light cyan',),
- ('editline', 'white', 'default',),
-
- # Status bar & heading
- ('heading', 'light cyan', 'light gray',),
- ('heading_key', 'dark blue', 'white',),
- ('heading_inactive', 'white', 'light gray',),
-
- # Help
- ('key', 'dark blue', 'default',),
- ('head', 'black,underline', 'default'),
- ('text', 'light cyan', 'default'),
-
- # List and Connections
- ('method', 'dark cyan', 'default'),
- ('focus', 'black', 'default'),
-
- ('code_200', 'dark green', 'default'),
- ('code_300', 'light blue', 'default'),
- ('code_400', 'dark red', 'default',),
- ('code_500', 'dark red', 'default'),
- ('code_other', 'light red', 'default'),
-
- ('error', 'light red', 'default'),
-
- ('header', 'light cyan', 'default'),
- ('highlight', 'black,bold', 'default'),
- ('intercept', 'brown', 'default',),
- ('replay', 'dark green', 'default',),
- ('ack', 'dark red', 'default'),
-
- # Hex view
- ('offset', 'light cyan', 'default'),
- ('text', 'yellow', 'default'),
-
- # Grid Editor
- ('focusfield', 'black', 'light gray'),
- ('focusfield_error', 'dark red', 'light gray'),
- ('field_error', 'dark red', 'black'),
- ('editfield', 'white', 'light cyan'),
- ],
+# Low-color themes should ONLY use the standard foreground and background
+# colours listed here:
+#
+# http://urwid.org/manual/displayattributes.html
+#
+
+
+
+class Palette:
+ _fields = [
+ 'title',
+
+ # Status bar & heading
+ 'heading', 'heading_key', 'heading_inactive',
+
+ # Help
+ 'key', 'head', 'text',
+
+ # List and Connections
+ 'method', 'focus',
+ 'code_200', 'code_300', 'code_400', 'code_500', 'code_other',
+ 'error',
+ 'header', 'highlight', 'intercept', 'replay',
+
+ # Hex view
+ 'offset',
+
+ # Grid Editor
+ 'focusfield', 'focusfield_error', 'field_error', 'editfield',
+ ]
+ high = None
+
+ def palette(self):
+ l = []
+ for i in self._fields:
+ v = [i]
+ v.extend(self.low[i])
+ if self.high and i in self.high:
+ v.append(None)
+ v.extend(self.high[i])
+ l.append(tuple(v))
+ return l
+
+
+class LowDark(Palette):
+ """
+ Low-color dark background
+ """
+ low = dict(
+ title = ('white,bold', 'default'),
+
+ # Status bar & heading
+ heading = ('light gray', 'dark blue'),
+ heading_key = ('light cyan', 'dark blue'),
+ heading_inactive = ('white', 'dark gray'),
+
+ # Help
+ key = ('light cyan', 'default'),
+ head = ('white,bold', 'default'),
+ text = ('light gray', 'default'),
+
+ # List and Connections
+ method = ('dark cyan', 'default'),
+ focus = ('yellow', 'default'),
+
+ code_200 = ('dark green', 'default'),
+ code_300 = ('light blue', 'default'),
+ code_400 = ('light red', 'default'),
+ code_500 = ('light red', 'default'),
+ code_other = ('dark red', 'default'),
+
+ error = ('light red', 'default'),
+
+ header = ('dark cyan', 'default'),
+ highlight = ('white,bold', 'default'),
+ intercept = ('brown', 'default'),
+ replay = ('light green', 'default'),
+
+ # Hex view
+ offset = ('dark cyan', 'default'),
+
+ # Grid Editor
+ focusfield = ('black', 'light gray'),
+ focusfield_error = ('dark red', 'light gray'),
+ field_error = ('dark red', 'default'),
+ editfield = ('white', 'default'),
+ )
+
+
+class Dark(LowDark):
+ high = dict(
+ heading_inactive = ('g58', 'g11'),
+ intercept = ('#f60', 'default'),
+ )
+
+
+class LowLight(Palette):
+ """
+ Low-color light background
+ """
+ low = dict(
+ title = ('dark magenta,bold', 'light blue'),
+
+ # Status bar & heading
+ heading = ('light gray', 'dark blue'),
+ heading_key = ('light cyan', 'dark blue'),
+ heading_inactive = ('black', 'light gray'),
+
+ # Help
+ key = ('dark blue,bold', 'default'),
+ head = ('black,bold', 'default'),
+ text = ('dark gray', 'default'),
+
+ # List and Connections
+ method = ('dark cyan', 'default'),
+ focus = ('black', 'default'),
+
+ code_200 = ('dark green', 'default'),
+ code_300 = ('light blue', 'default'),
+ code_400 = ('dark red', 'default'),
+ code_500 = ('dark red', 'default'),
+ code_other = ('light red', 'default'),
+
+ error = ('light red', 'default'),
+
+ header = ('dark blue', 'default'),
+ highlight = ('black,bold', 'default'),
+ intercept = ('brown', 'default'),
+ replay = ('dark green', 'default'),
+
+ # Hex view
+ offset = ('dark blue', 'default'),
+
+ # Grid Editor
+ focusfield = ('black', 'light gray'),
+ focusfield_error = ('dark red', 'light gray'),
+ field_error = ('dark red', 'black'),
+ editfield = ('black', 'default'),
+ )
+
+
+class Light(LowLight):
+ high = dict(
+ heading = ('g99', '#08f'),
+ heading_key = ('#0ff,bold', '#08f'),
+ heading_inactive = ('g35', 'g85'),
+ replay = ('#0a0,bold', 'default'),
+ )
+
+
+# Solarized palette in Urwid-style terminal high-colour offsets
+# See: http://ethanschoonover.com/solarized
+sol_base03 = "h234"
+sol_base02 = "h235"
+sol_base01 = "h240"
+sol_base00 = "h241"
+sol_base0 = "h244"
+sol_base1 = "h245"
+sol_base2 = "h254"
+sol_base3 = "h230"
+sol_yellow = "h136"
+sol_orange = "h166"
+sol_red = "h160"
+sol_magenta = "h125"
+sol_violet = "h61"
+sol_blue = "h33"
+sol_cyan = "h37"
+sol_green = "h64"
+class SolarizedLight(LowLight):
+ high = dict(
+ title = (sol_blue, 'default'),
+ text = (sol_base00, 'default'),
+
+ # Status bar & heading
+ heading = (sol_base2, sol_base02),
+ heading_key = (sol_blue, sol_base03),
+ heading_inactive = (sol_base03, sol_base1),
+
+ # Help
+ key = (sol_blue, 'default',),
+ head = (sol_base00, 'default'),
+
+ # List and Connections
+ method = (sol_cyan, 'default'),
+ focus = (sol_base01, 'default'),
+
+ code_200 = (sol_green, 'default'),
+ code_300 = (sol_blue, 'default'),
+ code_400 = (sol_orange, 'default',),
+ code_500 = (sol_red, 'default'),
+ code_other = (sol_magenta, 'default'),
+
+ error = (sol_red, 'default'),
+
+ header = (sol_base01, 'default'),
+ highlight = (sol_base01, 'default'),
+ intercept = (sol_red, 'default',),
+ replay = (sol_green, 'default',),
+
+ # Hex view
+ offset = (sol_cyan, 'default'),
+
+ # Grid Editor
+ focusfield = (sol_base00, sol_base2),
+ focusfield_error = (sol_red, sol_base2),
+ field_error = (sol_red, 'default'),
+ editfield = (sol_base01, 'default'),
+ )
+
+
+class SolarizedDark(LowDark):
+ high = dict(
+ title = (sol_blue, 'default'),
+ text = (sol_base0, 'default'),
+
+ # Status bar & heading
+ heading = (sol_base03, sol_base1),
+ heading_key = (sol_blue+",bold", sol_base1),
+ heading_inactive = (sol_base1, sol_base02),
+
+ # Help
+ key = (sol_blue, 'default',),
+ head = (sol_base00, 'default'),
+
+ # List and Connections
+ method = (sol_cyan, 'default'),
+ focus = (sol_base1, 'default'),
+
+ code_200 = (sol_green, 'default'),
+ code_300 = (sol_blue, 'default'),
+ code_400 = (sol_orange, 'default',),
+ code_500 = (sol_red, 'default'),
+ code_other = (sol_magenta, 'default'),
+
+ error = (sol_red, 'default'),
+
+ header = (sol_base01, 'default'),
+ highlight = (sol_base01, 'default'),
+ intercept = (sol_red, 'default',),
+ replay = (sol_green, 'default',),
+
+ # Hex view
+ offset = (sol_cyan, 'default'),
+
+ # Grid Editor
+ focusfield = (sol_base0, sol_base02),
+ focusfield_error = (sol_red, sol_base02),
+ field_error = (sol_red, 'default'),
+ editfield = (sol_base1, 'default'),
+ )
+
+palettes = {
+ "lowlight": LowLight(),
+ "lowdark": LowDark(),
+ "light": Light(),
+ "dark": Dark(),
+ "solarized_light": SolarizedLight(),
+ "solarized_dark": SolarizedDark(),
}
diff --git a/libmproxy/onboarding/app.py b/libmproxy/onboarding/app.py
index f0aecc15..37f05e96 100644
--- a/libmproxy/onboarding/app.py
+++ b/libmproxy/onboarding/app.py
@@ -38,27 +38,31 @@ class Index(tornado.web.RequestHandler):
class PEM(tornado.web.RequestHandler):
+ @property
+ def filename(self):
+ return config.CONF_BASENAME + "-ca-cert.pem"
+
def get(self):
- p = os.path.join(
- self.request.master.server.config.cadir,
- config.CONF_BASENAME + "-ca-cert.pem"
- )
- self.set_header(
- "Content-Type", "application/x-x509-ca-cert"
- )
- self.write(open(p, "rb").read())
+ p = os.path.join(self.request.master.server.config.cadir, self.filename)
+ self.set_header("Content-Type", "application/x-x509-ca-cert")
+ self.set_header("Content-Disposition", "inline; filename={}".format(self.filename))
+
+ with open(p, "rb") as f:
+ self.write(f.read())
class P12(tornado.web.RequestHandler):
+ @property
+ def filename(self):
+ return config.CONF_BASENAME + "-ca-cert.p12"
+
def get(self):
- p = os.path.join(
- self.request.master.server.config.cadir,
- config.CONF_BASENAME + "-ca-cert.p12"
- )
- self.set_header(
- "Content-Type", "application/x-pkcs12"
- )
- self.write(open(p, "rb").read())
+ p = os.path.join(self.request.master.server.config.cadir, self.filename)
+ self.set_header("Content-Type", "application/x-pkcs12")
+ self.set_header("Content-Disposition", "inline; filename={}".format(self.filename))
+
+ with open(p, "rb") as f:
+ self.write(f.read())
application = tornado.web.Application(
diff --git a/test/test_console_help.py b/test/test_console_help.py
index 6e1f9fad..a410bd2e 100644
--- a/test/test_console_help.py
+++ b/test/test_console_help.py
@@ -5,7 +5,14 @@ if os.name == "nt":
import libmproxy.console.help as help
+class DummyLoop:
+ def __init__(self):
+ self.widget = None
+
class DummyMaster:
+ def __init__(self):
+ self.loop = DummyLoop()
+
def make_view(self):
pass
@@ -16,7 +23,8 @@ class TestHelp:
assert h.helptext()
def test_keypress(self):
- h = help.HelpView(DummyMaster(), "foo", [1, 2, 3])
+ master = DummyMaster()
+ h = help.HelpView(master, "foo", [1, 2, 3])
assert not h.keypress((0, 0), "q")
assert not h.keypress((0, 0), "?")
assert h.keypress((0, 0), "o") == "o"
diff --git a/test/test_console_palettes.py b/test/test_console_palettes.py
new file mode 100644
index 00000000..3f8e280a
--- /dev/null
+++ b/test/test_console_palettes.py
@@ -0,0 +1,11 @@
+import os
+from nose.plugins.skip import SkipTest
+if os.name == "nt":
+ raise SkipTest("Skipped on Windows.")
+import libmproxy.console.palettes as palettes
+
+
+class TestPalette:
+ def test_helptext(self):
+ for i in palettes.palettes.values():
+ assert i.palette()
diff --git a/test/test_dump.py b/test/test_dump.py
index 11a024e3..48eeb244 100644
--- a/test/test_dump.py
+++ b/test/test_dump.py
@@ -131,14 +131,16 @@ class TestDumpMaster:
assert len(m.apps.apps) == 1
def test_replacements(self):
+ cs = StringIO()
o = dump.Options(replacements=[(".*", "content", "foo")])
- m = dump.DumpMaster(None, o)
+ m = dump.DumpMaster(None, o, outfile=cs)
f = self._cycle(m, "content")
assert f.request.content == "foo"
def test_setheader(self):
+ cs = StringIO()
o = dump.Options(setheaders=[(".*", "one", "two")])
- m = dump.DumpMaster(None, o)
+ m = dump.DumpMaster(None, o, outfile=cs)
f = self._cycle(m, "content")
assert f.request.headers["one"] == ["two"]
@@ -195,4 +197,3 @@ class TestDumpMaster:
def test_stickyauth(self):
self._dummy_cycle(1, None, "", stickyauth = ".*")
-
diff --git a/test/tools/testpatt b/test/tools/testpatt
new file mode 100755
index 00000000..f6d1169b
--- /dev/null
+++ b/test/tools/testpatt
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+# Generate a test pattern with pathoc
+PATHOD=http://localhost:9999
+pathoc localhost:8080 "get:'$PATHOD/p/200:p0,1:b@200b'"
+pathoc localhost:8080 "get:'$PATHOD/p/300:p0,1:b@200b'"
+pathoc localhost:8080 "get:'$PATHOD/p/400:p0,1:b@200b'"
+pathoc localhost:8080 "get:'$PATHOD/p/500:p0,1:b@200b'"
+pathoc localhost:8080 "get:'$PATHOD/p/600:p0,1:b@200b'"