aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/__init__.py0
-rw-r--r--examples/custom_contentviews.py2
-rw-r--r--examples/iframe_injector.py2
-rw-r--r--examples/modify_form.py6
-rw-r--r--examples/modify_querystring.py5
-rw-r--r--mitmproxy/console/__init__.py7
-rw-r--r--mitmproxy/console/grideditor.py4
-rwxr-xr-xrelease/rtool.py31
-rw-r--r--release/specs/mitmdump.spec3
-rw-r--r--release/specs/mitmproxy.spec3
-rw-r--r--release/specs/mitmweb.spec3
-rw-r--r--release/specs/pathoc.spec3
-rw-r--r--release/specs/pathod.spec3
-rw-r--r--test/mitmproxy/test_examples.py119
-rw-r--r--test/mitmproxy/test_flow_export.py1
-rw-r--r--test/mitmproxy/test_har_extractor.py37
16 files changed, 159 insertions, 70 deletions
diff --git a/examples/__init__.py b/examples/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/examples/__init__.py
+++ /dev/null
diff --git a/examples/custom_contentviews.py b/examples/custom_contentviews.py
index 776ba99d..f3b7317f 100644
--- a/examples/custom_contentviews.py
+++ b/examples/custom_contentviews.py
@@ -64,5 +64,5 @@ def start(context, argv):
context.add_contentview(pig_view)
-def stop(context):
+def done(context):
context.remove_contentview(pig_view)
diff --git a/examples/iframe_injector.py b/examples/iframe_injector.py
index fc38b136..ad844f19 100644
--- a/examples/iframe_injector.py
+++ b/examples/iframe_injector.py
@@ -14,7 +14,7 @@ def response(context, flow):
if flow.request.host in context.iframe_url:
return
with decoded(flow.response): # Remove content encoding (gzip, ...)
- html = BeautifulSoup(flow.response.content)
+ html = BeautifulSoup(flow.response.content, "lxml")
if html.body:
iframe = html.new_tag(
"iframe",
diff --git a/examples/modify_form.py b/examples/modify_form.py
index 3e9d15c0..86188781 100644
--- a/examples/modify_form.py
+++ b/examples/modify_form.py
@@ -1,5 +1,5 @@
def request(context, flow):
- if "application/x-www-form-urlencoded" in flow.request.headers.get("content-type", ""):
- form = flow.request.get_form_urlencoded()
+ form = flow.request.urlencoded_form
+ if form is not None:
form["mitmproxy"] = ["rocks"]
- flow.request.set_form_urlencoded(form)
+ flow.request.urlencoded_form = form
diff --git a/examples/modify_querystring.py b/examples/modify_querystring.py
index 7f31a48f..d682df69 100644
--- a/examples/modify_querystring.py
+++ b/examples/modify_querystring.py
@@ -1,6 +1,5 @@
-
def request(context, flow):
- q = flow.request.get_query()
+ q = flow.request.query
if q:
q["mitmproxy"] = ["rocks"]
- flow.request.set_query(q)
+ flow.request.query = q
diff --git a/mitmproxy/console/__init__.py b/mitmproxy/console/__init__.py
index f7e7b0d5..16615cbc 100644
--- a/mitmproxy/console/__init__.py
+++ b/mitmproxy/console/__init__.py
@@ -50,7 +50,7 @@ class ConsoleState(flow.State):
if self.focus is None:
self.set_focus(0)
elif self.follow_focus:
- self.set_focus(len(self.view) - 1)
+ self.update_focus()
self.set_flow_marked(f, False)
return f
@@ -58,6 +58,8 @@ class ConsoleState(flow.State):
super(ConsoleState, self).update_flow(f)
if self.focus is None:
self.set_focus(0)
+ elif self.follow_focus:
+ self.update_focus()
return f
def set_limit(self, limit):
@@ -80,6 +82,9 @@ class ConsoleState(flow.State):
else:
self.focus = None
+ def update_focus(self):
+ self.set_focus(len(self.view) - 1)
+
def set_focus_flow(self, f):
self.set_focus(self.view.index(f))
diff --git a/mitmproxy/console/grideditor.py b/mitmproxy/console/grideditor.py
index a11c962c..597a7e7a 100644
--- a/mitmproxy/console/grideditor.py
+++ b/mitmproxy/console/grideditor.py
@@ -6,7 +6,7 @@ import os
import urwid
from netlib import odict
-from netlib.http import user_agents
+from netlib.http import user_agents, cookies
from . import common, signals
from .. import utils, filt, script
@@ -69,7 +69,7 @@ class SubgridColumn:
self.subeditor = subeditor
def text(self, obj):
- p = http_cookies._format_pairs(obj, sep="\n")
+ p = cookies._format_pairs(obj, sep="\n")
return urwid.Text(p)
def blank(self):
diff --git a/release/rtool.py b/release/rtool.py
index 5929452a..221ace0a 100755
--- a/release/rtool.py
+++ b/release/rtool.py
@@ -34,6 +34,7 @@ else:
RELEASE_DIR = join(os.path.dirname(os.path.realpath(__file__)))
DIST_DIR = join(RELEASE_DIR, "dist")
ROOT_DIR = os.path.normpath(join(RELEASE_DIR, ".."))
+RELEASE_SPEC_DIR = join(RELEASE_DIR, "specs")
VERSION_FILE = join(ROOT_DIR, "netlib/version.py")
BUILD_DIR = join(RELEASE_DIR, "build")
@@ -226,20 +227,22 @@ def bdist(ctx, use_existing_wheels, pyinstaller_version):
for bdist_project, tools in project["bdists"].items():
with Archive(join(DIST_DIR, archive_name(bdist_project))) as archive:
for tool in tools:
- spec = join(RELEASE_DIR, "specs/%s.spec" % tool)
- print("Building %s binary..." % tool)
- subprocess.check_call(
- [
- VENV_PYINSTALLER,
- "--clean",
- "--workpath", PYINSTALLER_TEMP,
- "--distpath", PYINSTALLER_DIST,
- # This is PyInstaller, so setting a
- # different log level obviously breaks it :-)
- # "--log-level", "WARN",
- spec
- ]
- )
+ # This is PyInstaller, so it messes up paths.
+ # We need to make sure that we are in the spec folder.
+ with chdir(RELEASE_SPEC_DIR):
+ print("Building %s binary..." % tool)
+ subprocess.check_call(
+ [
+ VENV_PYINSTALLER,
+ "--clean",
+ "--workpath", PYINSTALLER_TEMP,
+ "--distpath", PYINSTALLER_DIST,
+ # This is PyInstaller, so setting a
+ # different log level obviously breaks it :-)
+ # "--log-level", "WARN",
+ "%s.spec" % tool
+ ]
+ )
# Test if it works at all O:-)
executable = join(PYINSTALLER_DIST, tool)
diff --git a/release/specs/mitmdump.spec b/release/specs/mitmdump.spec
index 149678df..fc145185 100644
--- a/release/specs/mitmdump.spec
+++ b/release/specs/mitmdump.spec
@@ -19,4 +19,5 @@ exe = EXE(pyz,
debug=False,
strip=None,
upx=True,
- console=True )
+ console=True,
+ icon='icon.ico' )
diff --git a/release/specs/mitmproxy.spec b/release/specs/mitmproxy.spec
index 1c481446..f7ea99f9 100644
--- a/release/specs/mitmproxy.spec
+++ b/release/specs/mitmproxy.spec
@@ -19,4 +19,5 @@ exe = EXE(pyz,
debug=False,
strip=None,
upx=True,
- console=True )
+ console=True,
+ icon='icon.ico' )
diff --git a/release/specs/mitmweb.spec b/release/specs/mitmweb.spec
index 79ccf71d..ea6192a4 100644
--- a/release/specs/mitmweb.spec
+++ b/release/specs/mitmweb.spec
@@ -19,4 +19,5 @@ exe = EXE(pyz,
debug=False,
strip=None,
upx=True,
- console=True )
+ console=True,
+ icon='icon.ico' )
diff --git a/release/specs/pathoc.spec b/release/specs/pathoc.spec
index 4f1f44be..d4f4d0d9 100644
--- a/release/specs/pathoc.spec
+++ b/release/specs/pathoc.spec
@@ -19,4 +19,5 @@ exe = EXE(pyz,
debug=False,
strip=None,
upx=True,
- console=True )
+ console=True,
+ icon='icon.ico' )
diff --git a/release/specs/pathod.spec b/release/specs/pathod.spec
index 3d2a8be2..f3a977f2 100644
--- a/release/specs/pathod.spec
+++ b/release/specs/pathod.spec
@@ -19,4 +19,5 @@ exe = EXE(pyz,
debug=False,
strip=None,
upx=True,
- console=True )
+ console=True,
+ icon='icon.ico' )
diff --git a/test/mitmproxy/test_examples.py b/test/mitmproxy/test_examples.py
index 163ace17..803776ac 100644
--- a/test/mitmproxy/test_examples.py
+++ b/test/mitmproxy/test_examples.py
@@ -1,11 +1,42 @@
import glob
+import json
+import os
+from contextlib import contextmanager
+
from mitmproxy import utils, script
from mitmproxy.proxy import config
-from . import tservers
+from netlib import tutils as netutils
+from netlib.http import Headers
+from . import tservers, tutils
+
+example_dir = utils.Data(__name__).path("../../examples")
+
+
+class DummyContext(object):
+ """Emulate script.ScriptContext() functionality."""
+
+ contentview = None
+
+ def log(self, *args, **kwargs):
+ pass
+
+ def add_contentview(self, view_obj):
+ self.contentview = view_obj
+
+ def remove_contentview(self, view_obj):
+ self.contentview = None
+
+
+@contextmanager
+def example(command):
+ command = os.path.join(example_dir, command)
+ ctx = DummyContext()
+ s = script.Script(command, ctx)
+ yield s
+ s.unload()
def test_load_scripts():
- example_dir = utils.Data(__name__).path("../../examples")
scripts = glob.glob("%s/*.py" % example_dir)
tmaster = tservers.TestMaster(config.ProxyConfig())
@@ -28,3 +59,87 @@ def test_load_scripts():
raise
else:
s.unload()
+
+
+def test_add_header():
+ flow = tutils.tflow(resp=netutils.tresp())
+ with example("add_header.py") as ex:
+ ex.run("response", flow)
+ assert flow.response.headers["newheader"] == "foo"
+
+
+def test_custom_contentviews():
+ with example("custom_contentviews.py") as ex:
+ pig = ex.ctx.contentview
+ _, fmt = pig("<html>test!</html>")
+ assert any('esttay!' in val[0][1] for val in fmt)
+ assert not pig("gobbledygook")
+
+
+def test_iframe_injector():
+ with tutils.raises(script.ScriptException):
+ with example("iframe_injector.py") as ex:
+ pass
+
+ flow = tutils.tflow(resp=netutils.tresp(content="<html>mitmproxy</html>"))
+ with example("iframe_injector.py http://example.org/evil_iframe") as ex:
+ ex.run("response", flow)
+ content = flow.response.content
+ assert 'iframe' in content and 'evil_iframe' in content
+
+
+def test_modify_form():
+ form_header = Headers(content_type="application/x-www-form-urlencoded")
+ flow = tutils.tflow(req=netutils.treq(headers=form_header))
+ with example("modify_form.py") as ex:
+ ex.run("request", flow)
+ assert flow.request.urlencoded_form["mitmproxy"] == ["rocks"]
+
+
+def test_modify_querystring():
+ flow = tutils.tflow(req=netutils.treq(path="/search?q=term"))
+ with example("modify_querystring.py") as ex:
+ ex.run("request", flow)
+ assert flow.request.query["mitmproxy"] == ["rocks"]
+
+
+def test_modify_response_body():
+ with tutils.raises(script.ScriptException):
+ with example("modify_response_body.py") as ex:
+ pass
+
+ flow = tutils.tflow(resp=netutils.tresp(content="I <3 mitmproxy"))
+ with example("modify_response_body.py mitmproxy rocks") as ex:
+ assert ex.ctx.old == "mitmproxy" and ex.ctx.new == "rocks"
+ ex.run("response", flow)
+ assert flow.response.content == "I <3 rocks"
+
+
+def test_redirect_requests():
+ flow = tutils.tflow(req=netutils.treq(host="example.org"))
+ with example("redirect_requests.py") as ex:
+ ex.run("request", flow)
+ assert flow.request.host == "mitmproxy.org"
+
+
+def test_har_extractor():
+ with tutils.raises(script.ScriptException):
+ with example("har_extractor.py") as ex:
+ pass
+
+ times = dict(
+ timestamp_start=746203272,
+ timestamp_end=746203272,
+ )
+
+ flow = tutils.tflow(
+ req=netutils.treq(**times),
+ resp=netutils.tresp(**times)
+ )
+
+ with example("har_extractor.py -") as ex:
+ ex.run("response", flow)
+
+ with open(tutils.test_data.path("data/har_extractor.har")) as fp:
+ test_data = json.load(fp)
+ assert json.loads(ex.ctx.HARLog.json()) == test_data["test_response"]
diff --git a/test/mitmproxy/test_flow_export.py b/test/mitmproxy/test_flow_export.py
index 3dc07427..62161d5d 100644
--- a/test/mitmproxy/test_flow_export.py
+++ b/test/mitmproxy/test_flow_export.py
@@ -1,4 +1,3 @@
-import json
from textwrap import dedent
import netlib.tutils
diff --git a/test/mitmproxy/test_har_extractor.py b/test/mitmproxy/test_har_extractor.py
deleted file mode 100644
index 7838f713..00000000
--- a/test/mitmproxy/test_har_extractor.py
+++ /dev/null
@@ -1,37 +0,0 @@
-import json
-import netlib.tutils
-from . import tutils
-
-from examples import har_extractor
-
-
-class Context(object):
- pass
-
-
-trequest = netlib.tutils.treq(
- timestamp_start=746203272,
- timestamp_end=746203272,
-)
-
-tresponse = netlib.tutils.tresp(
- timestamp_start=746203272,
- timestamp_end=746203272,
-)
-
-
-def test_start():
- tutils.raises(ValueError, har_extractor.start, Context(), [])
-
-
-def test_response():
- ctx = Context()
- ctx.HARLog = har_extractor._HARLog([])
- ctx.seen_server = set()
-
- fl = tutils.tflow(req=trequest, resp=tresponse)
- har_extractor.response(ctx, fl)
-
- with open(tutils.test_data.path("data/har_extractor.har")) as fp:
- test_data = json.load(fp)
- assert json.loads(ctx.HARLog.json()) == test_data["test_response"]