aboutsummaryrefslogtreecommitdiffstats
path: root/libmproxy
diff options
context:
space:
mode:
Diffstat (limited to 'libmproxy')
-rw-r--r--libmproxy/cmdline.py36
-rw-r--r--libmproxy/console.py1
-rw-r--r--libmproxy/flow.py13
-rw-r--r--libmproxy/plugins.py46
-rw-r--r--libmproxy/script.py75
5 files changed, 73 insertions, 98 deletions
diff --git a/libmproxy/cmdline.py b/libmproxy/cmdline.py
index 5f51b854..8be419a6 100644
--- a/libmproxy/cmdline.py
+++ b/libmproxy/cmdline.py
@@ -25,9 +25,8 @@ def get_common_options(options):
refresh_server_playback = not options.norefresh,
rheaders = options.rheaders,
rfile = options.rfile,
- request_script = options.request_script,
- response_script = options.response_script,
server_replay = options.server_replay,
+ script = options.script,
stickycookie = stickycookie,
stickyauth = stickyauth,
wfile = options.wfile,
@@ -42,6 +41,16 @@ def common_options(parser):
help = "Address to bind proxy to (defaults to all interfaces)"
)
parser.add_option(
+ "--anticache",
+ action="store_true", dest="anticache", default=False,
+ help="Strip out request headers that might cause the server to return 304-not-modified."
+ )
+ parser.add_option(
+ "--confdir",
+ action="store", type = "str", dest="confdir", default='~/.mitmproxy',
+ help = "Configuration directory. (~/.mitmproxy)"
+ )
+ parser.add_option(
"-d",
action="store_true", dest="autodecode",
help="Automatically decode compressed server responses."
@@ -52,11 +61,6 @@ def common_options(parser):
help="Show event log."
)
parser.add_option(
- "--confdir",
- action="store", type = "str", dest="confdir", default='~/.mitmproxy',
- help = "Configuration directory. (~/.mitmproxy)"
- )
- parser.add_option(
"-n",
action="store_true", dest="no_server",
help="Don't start a proxy server."
@@ -77,19 +81,9 @@ def common_options(parser):
help="Read flows from file."
)
parser.add_option(
- "--anticache",
- action="store_true", dest="anticache", default=False,
- help="Strip out request headers that might cause the server to return 304-not-modified."
- )
- parser.add_option(
- "--reqscript",
- action="store", dest="request_script", default=None,
- help="Script to run when a request is recieved."
- )
- parser.add_option(
- "--respscript",
- action="store", dest="response_script", default=None,
- help="Script to run when a response is recieved."
+ "-s",
+ action="store", dest="script", default=None,
+ help="Run a script."
)
parser.add_option(
"-t",
@@ -143,7 +137,7 @@ def common_options(parser):
group = optparse.OptionGroup(parser, "Server Replay")
group.add_option(
- "-s",
+ "-S",
action="store", dest="server_replay", default=None, metavar="PATH",
help="Replay server responses from a saved file."
)
diff --git a/libmproxy/console.py b/libmproxy/console.py
index 39fb871f..ae3210e7 100644
--- a/libmproxy/console.py
+++ b/libmproxy/console.py
@@ -852,6 +852,7 @@ class Options(object):
"request_script",
"response_script",
"rfile",
+ "script",
"rheaders",
"server_replay",
"stickycookie",
diff --git a/libmproxy/flow.py b/libmproxy/flow.py
index 57bcc878..92a4e812 100644
--- a/libmproxy/flow.py
+++ b/libmproxy/flow.py
@@ -462,8 +462,8 @@ class FlowMaster(controller.Master):
self.state = state
self.server_playback = None
self.client_playback = None
- self.scripts = {}
self.kill_nonreplay = False
+ self.plugin = None
self.stickycookie_state = False
self.stickycookie_txt = None
@@ -481,11 +481,8 @@ class FlowMaster(controller.Master):
raise NotImplementedError
#end nocover
- def set_response_script(self, s):
- self.scripts["response"] = s
-
- def set_request_script(self, s):
- self.scripts["request"] = s
+ def set_plugin(self, p):
+ self.plugin = p
def set_stickycookie(self, txt):
if txt:
@@ -582,8 +579,6 @@ class FlowMaster(controller.Master):
if self.stickyauth_state:
self.stickyauth_state.handle_request(f)
- if "request" in self.scripts:
- self._runscript(f, self.scripts["request"])
if self.anticache:
f.request.anticache()
if self.anticomp:
@@ -600,8 +595,6 @@ class FlowMaster(controller.Master):
def process_new_response(self, f):
if self.stickycookie_state:
self.stickycookie_state.handle_response(f)
- if "response" in self.scripts:
- self._runscript(f, self.scripts["response"])
def replay_request(self, f):
"""
diff --git a/libmproxy/plugins.py b/libmproxy/plugins.py
deleted file mode 100644
index 09c2edf8..00000000
--- a/libmproxy/plugins.py
+++ /dev/null
@@ -1,46 +0,0 @@
-import imp, os, traceback
-
-
-class Context:
- def __init__(self, master, state):
- self.master, self.state = master, state
-
- def log(self, *args, **kwargs):
- self.master.log(*args, **kwargs)
-
-
-class Plugin:
- def __init__(self, path, master):
- self.path = path
- self.ctx = Context(master, master.state)
- self.mod = None
- self.ns = None
- self.load()
-
- def load(self):
- """
- Loads a module and runs the start method.
- """
- ns = {}
- self.mod = execfile(os.path.expanduser(self.path), {}, ns)
- self.ns = ns
- self.run("start")
-
- 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)
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)