diff options
-rw-r--r-- | examples/custom_contentviews.py | 2 | ||||
-rw-r--r-- | examples/filt.py | 2 | ||||
-rw-r--r-- | examples/flowwriter.py | 2 | ||||
-rw-r--r-- | examples/har_extractor.py | 2 | ||||
-rw-r--r-- | examples/iframe_injector.py | 2 | ||||
-rw-r--r-- | examples/modify_response_body.py | 2 | ||||
-rw-r--r-- | examples/proxapp.py | 2 | ||||
-rw-r--r-- | examples/stub.py | 9 | ||||
-rw-r--r-- | examples/tls_passthrough.py | 2 | ||||
-rw-r--r-- | mitmproxy/addons.py | 1 | ||||
-rw-r--r-- | mitmproxy/builtins/script.py | 29 | ||||
-rw-r--r-- | mitmproxy/controller.py | 3 | ||||
-rw-r--r-- | mitmproxy/script/concurrent.py | 2 | ||||
-rw-r--r-- | test/mitmproxy/builtins/test_script.py | 7 |
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() |