mirror of
https://github.com/Grasscutters/mitmproxy.git
synced 2024-11-26 18:18:25 +00:00
Rip out old script interface, start replacing with new stubs.
Scripts are broken for now.
This commit is contained in:
parent
62088a6661
commit
12d2b1f926
@ -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,
|
||||
@ -41,6 +40,16 @@ def common_options(parser):
|
||||
action="store", type = "str", dest="addr", default='',
|
||||
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",
|
||||
@ -51,11 +60,6 @@ def common_options(parser):
|
||||
action="store_true", dest="eventlog",
|
||||
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",
|
||||
@ -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."
|
||||
)
|
||||
|
@ -852,6 +852,7 @@ class Options(object):
|
||||
"request_script",
|
||||
"response_script",
|
||||
"rfile",
|
||||
"script",
|
||||
"rheaders",
|
||||
"server_replay",
|
||||
"stickycookie",
|
||||
|
@ -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):
|
||||
"""
|
||||
|
@ -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)
|
@ -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
|
||||
import imp, os, traceback
|
||||
|
||||
#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)
|
||||
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)
|
||||
|
@ -1,9 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
import sys
|
||||
sys.path.insert(0, "..")
|
||||
from libmproxy import script
|
||||
|
||||
f = script.load_flow()
|
||||
f.request.host = "TESTOK"
|
||||
print >> sys.stderr, "DEBUG"
|
||||
script.return_flow(f)
|
@ -1,2 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
print "NONSENSE"
|
@ -1,6 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
import sys
|
||||
sys.path.insert(0, "..")
|
||||
print >> sys.stderr, "output"
|
||||
sys.exit(1)
|
||||
|
3
test/scripts/loaderr.py
Normal file
3
test/scripts/loaderr.py
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
|
||||
a = x
|
@ -1,35 +0,0 @@
|
||||
import os
|
||||
from libmproxy import plugins, flow
|
||||
import libpry
|
||||
|
||||
class uPlugin(libpry.AutoTree):
|
||||
def test_simple(self):
|
||||
s = flow.State()
|
||||
fm = flow.FlowMaster(None, s)
|
||||
|
||||
p = plugins.Plugin(os.path.join("plugins", "a.py"), fm)
|
||||
assert "here" in p.ns
|
||||
assert p.run("here") == (True, 1)
|
||||
assert p.run("here") == (True, 2)
|
||||
|
||||
ret = p.run("errargs")
|
||||
assert not ret[0]
|
||||
assert len(ret[1]) == 2
|
||||
|
||||
# Check reload
|
||||
p.load()
|
||||
assert p.run("here") == (True, 1)
|
||||
|
||||
def test_err(self):
|
||||
s = flow.State()
|
||||
fm = flow.FlowMaster(None, s)
|
||||
|
||||
libpry.raises(IOError, plugins.Plugin, "nonexistent", fm)
|
||||
libpry.raises(SyntaxError, plugins.Plugin, os.path.join("plugins", "syntaxerr.py"), fm)
|
||||
|
||||
|
||||
|
||||
tests = [
|
||||
uPlugin(),
|
||||
]
|
||||
|
@ -1,6 +1,6 @@
|
||||
import cStringIO, time, re
|
||||
import libpry
|
||||
from libmproxy import proxy, controller, utils, dump, script
|
||||
from libmproxy import proxy, controller, utils, dump
|
||||
import email.utils
|
||||
import tutils
|
||||
|
||||
|
51
test/test_script.py
Normal file
51
test/test_script.py
Normal file
@ -0,0 +1,51 @@
|
||||
import os
|
||||
from libmproxy import script, flow
|
||||
import libpry
|
||||
|
||||
class uScript(libpry.AutoTree):
|
||||
def test_simple(self):
|
||||
s = flow.State()
|
||||
fm = flow.FlowMaster(None, s)
|
||||
|
||||
p = script.Script(os.path.join("scripts", "a.py"), fm)
|
||||
p.load()
|
||||
assert "here" in p.ns
|
||||
assert p.run("here") == (True, 1)
|
||||
assert p.run("here") == (True, 2)
|
||||
|
||||
ret = p.run("errargs")
|
||||
assert not ret[0]
|
||||
assert len(ret[1]) == 2
|
||||
|
||||
# Check reload
|
||||
p.load()
|
||||
assert p.run("here") == (True, 1)
|
||||
|
||||
def test_err(self):
|
||||
s = flow.State()
|
||||
fm = flow.FlowMaster(None, s)
|
||||
|
||||
s = script.Script("nonexistent", fm)
|
||||
libpry.raises(
|
||||
script.ScriptError,
|
||||
s.load
|
||||
)
|
||||
|
||||
s = script.Script(os.path.join("scripts", "syntaxerr.py"), fm)
|
||||
libpry.raises(
|
||||
script.ScriptError,
|
||||
s.load
|
||||
)
|
||||
|
||||
s = script.Script(os.path.join("scripts", "loaderr.py"), fm)
|
||||
libpry.raises(
|
||||
script.ScriptError,
|
||||
s.load
|
||||
)
|
||||
|
||||
|
||||
|
||||
tests = [
|
||||
uScript(),
|
||||
]
|
||||
|
Loading…
Reference in New Issue
Block a user