aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/custom_contentviews.py2
-rw-r--r--examples/filt.py2
-rw-r--r--examples/flowwriter.py2
-rw-r--r--examples/har_extractor.py2
-rw-r--r--examples/iframe_injector.py2
-rw-r--r--examples/modify_response_body.py2
-rw-r--r--examples/proxapp.py2
-rw-r--r--examples/stub.py9
-rw-r--r--examples/tls_passthrough.py2
-rw-r--r--mitmproxy/addons.py1
-rw-r--r--mitmproxy/builtins/script.py29
-rw-r--r--mitmproxy/controller.py3
-rw-r--r--mitmproxy/script/concurrent.py2
-rw-r--r--test/mitmproxy/builtins/test_script.py7
14 files changed, 46 insertions, 21 deletions
diff --git a/examples/custom_contentviews.py b/examples/custom_contentviews.py
index b10d936f..5a63e2a0 100644
--- a/examples/custom_contentviews.py
+++ b/examples/custom_contentviews.py
@@ -62,7 +62,7 @@ class ViewPigLatin(contentviews.View):
pig_view = ViewPigLatin()
-def configure(options):
+def start():
contentviews.add(pig_view)
diff --git a/examples/filt.py b/examples/filt.py
index 102d1274..21744edd 100644
--- a/examples/filt.py
+++ b/examples/filt.py
@@ -6,7 +6,7 @@ from mitmproxy import filt
state = {}
-def configure(options):
+def start():
if len(sys.argv) != 2:
raise ValueError("Usage: -s 'filt.py FILTER'")
state["filter"] = filt.parse(sys.argv[1])
diff --git a/examples/flowwriter.py b/examples/flowwriter.py
index d8fbc1f4..07c7ca20 100644
--- a/examples/flowwriter.py
+++ b/examples/flowwriter.py
@@ -6,7 +6,7 @@ from mitmproxy.flow import FlowWriter
state = {}
-def configure(options):
+def start():
if len(sys.argv) != 2:
raise ValueError('Usage: -s "flowriter.py filename"')
diff --git a/examples/har_extractor.py b/examples/har_extractor.py
index 23deb43a..2a69b9af 100644
--- a/examples/har_extractor.py
+++ b/examples/har_extractor.py
@@ -61,7 +61,7 @@ class Context(object):
context = Context()
-def configure(options):
+def start():
"""
On start we create a HARLog instance. You will have to adapt this to
suit your actual needs of HAR generation. As it will probably be
diff --git a/examples/iframe_injector.py b/examples/iframe_injector.py
index 40934dd3..70247d31 100644
--- a/examples/iframe_injector.py
+++ b/examples/iframe_injector.py
@@ -7,7 +7,7 @@ from mitmproxy.models import decoded
iframe_url = None
-def configure(options):
+def start():
if len(sys.argv) != 2:
raise ValueError('Usage: -s "iframe_injector.py url"')
global iframe_url
diff --git a/examples/modify_response_body.py b/examples/modify_response_body.py
index 8b6908a4..23ad0151 100644
--- a/examples/modify_response_body.py
+++ b/examples/modify_response_body.py
@@ -8,7 +8,7 @@ from mitmproxy.models import decoded
state = {}
-def configure(options):
+def start():
if len(sys.argv) != 3:
raise ValueError('Usage: -s "modify_response_body.py old new"')
# You may want to use Python's argparse for more sophisticated argument
diff --git a/examples/proxapp.py b/examples/proxapp.py
index 095f412a..2935b587 100644
--- a/examples/proxapp.py
+++ b/examples/proxapp.py
@@ -16,7 +16,7 @@ def hello_world():
# Register the app using the magic domain "proxapp" on port 80. Requests to
# this domain and port combination will now be routed to the WSGI app instance.
-def configure(options):
+def start():
mitmproxy.ctx.master.apps.add(app, "proxapp", 80)
# SSL works too, but the magic domain needs to be resolvable from the mitmproxy machine due to mitmproxy's design.
diff --git a/examples/stub.py b/examples/stub.py
index 614acee2..7de4012a 100644
--- a/examples/stub.py
+++ b/examples/stub.py
@@ -4,6 +4,15 @@ import mitmproxy
"""
+
+def start():
+ """
+ Called once on script startup before any other events
+ """
+ mitmproxy.ctx.log("start")
+
+
+
def configure(options):
"""
Called once on script startup before any other events, and whenever options changes.
diff --git a/examples/tls_passthrough.py b/examples/tls_passthrough.py
index 306f55f6..20e8f9be 100644
--- a/examples/tls_passthrough.py
+++ b/examples/tls_passthrough.py
@@ -113,7 +113,7 @@ class TlsFeedback(TlsLayer):
tls_strategy = None
-def configure(options):
+def start():
global tls_strategy
if len(sys.argv) == 2:
tls_strategy = ProbabilisticStrategy(float(sys.argv[1]))
diff --git a/mitmproxy/addons.py b/mitmproxy/addons.py
index 7ac65a09..c779aaf8 100644
--- a/mitmproxy/addons.py
+++ b/mitmproxy/addons.py
@@ -21,6 +21,7 @@ class Addons(object):
def add(self, *addons):
self.chain.extend(addons)
for i in addons:
+ self.invoke_with_context(i, "start")
self.invoke_with_context(i, "configure", self.master.options)
def remove(self, addon):
diff --git a/mitmproxy/builtins/script.py b/mitmproxy/builtins/script.py
index f6cf093f..bcb756f6 100644
--- a/mitmproxy/builtins/script.py
+++ b/mitmproxy/builtins/script.py
@@ -51,22 +51,29 @@ def scriptenv(path, args):
_, _, tb = sys.exc_info()
scriptdir = os.path.dirname(os.path.abspath(path))
for i, s in enumerate(reversed(traceback.extract_tb(tb))):
+ tb = tb.tb_next
if not os.path.abspath(s[0]).startswith(scriptdir):
break
- else:
- tb = tb.tb_next
- ctx.log.warn("".join(traceback.format_tb(tb)))
+ ctx.log.error("Script error: %s" % "".join(traceback.format_tb(tb)))
finally:
sys.argv = oldargs
sys.path.pop()
def load_script(path, args):
+ with open(path, "rb") as f:
+ try:
+ code = compile(f.read(), path, 'exec')
+ except SyntaxError as e:
+ ctx.log.error(
+ "Script error: %s line %s: %s" % (
+ e.filename, e.lineno, e.msg
+ )
+ )
+ return
ns = {'__file__': os.path.abspath(path)}
with scriptenv(path, args):
- with open(path, "rb") as f:
- code = compile(f.read(), path, 'exec')
- exec(code, ns, ns)
+ exec(code, ns, ns)
return ns
@@ -96,7 +103,7 @@ class Script:
self.last_options = None
self.should_reload = threading.Event()
- for i in controller.Events - set(["tick"]):
+ for i in controller.Events - set(["start", "configure", "tick"]):
def mkprox():
evt = i
@@ -120,12 +127,16 @@ class Script:
def tick(self):
if self.should_reload.is_set():
self.should_reload.clear()
- self.ns = None
ctx.log.info("Reloading script: %s" % self.name)
+ self.ns = load_script(self.path, self.args)
self.configure(self.last_options)
else:
self.run("tick")
+ def start(self):
+ self.ns = load_script(self.path, self.args)
+ self.run("start")
+
def configure(self, options):
self.last_options = options
if not self.observer:
@@ -136,8 +147,6 @@ class Script:
os.path.dirname(self.path) or "."
)
self.observer.start()
- if not self.ns:
- self.ns = load_script(self.path, self.args)
self.run("configure", options)
diff --git a/mitmproxy/controller.py b/mitmproxy/controller.py
index d3ae1baa..503cdcd3 100644
--- a/mitmproxy/controller.py
+++ b/mitmproxy/controller.py
@@ -32,6 +32,9 @@ Events = frozenset([
"error",
"log",
+
+ "start",
+ "configure",
"done",
"tick",
diff --git a/mitmproxy/script/concurrent.py b/mitmproxy/script/concurrent.py
index 010a5fa0..0cc0514e 100644
--- a/mitmproxy/script/concurrent.py
+++ b/mitmproxy/script/concurrent.py
@@ -13,7 +13,7 @@ class ScriptThread(basethread.BaseThread):
def concurrent(fn):
- if fn.__name__ not in controller.Events:
+ if fn.__name__ not in controller.Events - set(["start", "configure", "tick"]):
raise NotImplementedError(
"Concurrent decorator not supported for '%s' method." % fn.__name__
)
diff --git a/test/mitmproxy/builtins/test_script.py b/test/mitmproxy/builtins/test_script.py
index 5747912d..2c2568ed 100644
--- a/test/mitmproxy/builtins/test_script.py
+++ b/test/mitmproxy/builtins/test_script.py
@@ -57,7 +57,10 @@ class TestScript(mastertest.MasterTest):
)
)
m.addons.add(sc)
- assert sc.ns["call_log"] == [("configure", (options.Options(),), {})]
+ assert sc.ns["call_log"] == [
+ ("start", (), {}),
+ ("configure", (options.Options(),), {})
+ ]
sc.ns["call_log"] = []
f = tutils.tflow(resp=True)
@@ -93,7 +96,7 @@ class TestScript(mastertest.MasterTest):
m.addons.add(sc)
f = tutils.tflow(resp=True)
self.invoke(m, "request", f)
- assert m.event_log[0][0] == "warn"
+ assert m.event_log[0][0] == "error"
def test_duplicate_flow(self):
s = state.State()