aboutsummaryrefslogtreecommitdiffstats
path: root/libmproxy/script.py
diff options
context:
space:
mode:
Diffstat (limited to 'libmproxy/script.py')
-rw-r--r--libmproxy/script.py75
1 files changed, 54 insertions, 21 deletions
diff --git a/libmproxy/script.py b/libmproxy/script.py
index 92563cde..da3131a8 100644
--- a/libmproxy/script.py
+++ b/libmproxy/script.py
@@ -1,26 +1,59 @@
-"""
- The mitmproxy scripting interface is simple - a serialized representation
- of a flow is passed to the script on stdin, and a possibly modified flow is
- then read by mitmproxy from the scripts stdout. This module provides two
- convenience functions to make loading and returning data from scripts
- simple.
-"""
-import sys
-import flow
-
-#begin nocover
-def load_flow():
- """
- Load a flow from the stdin. Returns a Flow object.
- """
- data = sys.stdin.read()
- return flow.Flow.script_deserialize(data)
+import imp, os, traceback
+
+class ScriptError(Exception):
+ pass
+
+class Context:
+ def __init__(self, master, state):
+ self.master, self.state = master, state
+
+ def log(self, *args, **kwargs):
+ self.master.log(*args, **kwargs)
-def return_flow(f):
+class Script:
"""
- Print a flow to stdout.
+ The instantiator should do something along this vein:
+
+ s = Script(path, master)
+ s.load()
+ s.run("start")
"""
- print >> sys.stdout, f.script_serialize()
-
+ def __init__(self, path, master):
+ self.path = path
+ self.ctx = Context(master, master.state)
+ self.mod = None
+ self.ns = None
+
+ def load(self):
+ """
+ Loads a module.
+
+ Raises ScriptError on failure, with argument equal to an error
+ message that may be a formatted traceback.
+ """
+ ns = {}
+ try:
+ self.mod = execfile(os.path.expanduser(self.path), {}, ns)
+ except Exception, v:
+ raise ScriptError(traceback.format_exc(v))
+ self.ns = ns
+
+ def run(self, name, *args, **kwargs):
+ """
+ Runs a plugin method.
+
+ Returns:
+ (True, retval) on success.
+ (False, None) on nonexistent method.
+ (Fals, (exc, traceback string)) if there was an exception.
+ """
+ f = self.ns.get(name)
+ if f:
+ try:
+ return (True, f(self.ctx, *args, **kwargs))
+ except Exception, v:
+ return (False, (v, traceback.format_exc(v)))
+ else:
+ return (False, None)