mirror of
https://github.com/Grasscutters/mitmproxy.git
synced 2024-11-30 03:14:22 +00:00
Add hooks for policy checks of served data.
This commit is contained in:
parent
204a556aa7
commit
c7b5faf7db
@ -86,7 +86,7 @@ class PathodHandler(tcp.BaseHandler):
|
|||||||
httpversion = httpversion,
|
httpversion = httpversion,
|
||||||
)
|
)
|
||||||
if crafted:
|
if crafted:
|
||||||
response_log = crafted.serve(self.wfile)
|
response_log = crafted.serve(self.wfile, self.check_size)
|
||||||
if response_log["disconnect"]:
|
if response_log["disconnect"]:
|
||||||
return
|
return
|
||||||
self.server.add_log(
|
self.server.add_log(
|
||||||
@ -110,6 +110,9 @@ class PathodHandler(tcp.BaseHandler):
|
|||||||
self.debug("%s %s"%(method, path))
|
self.debug("%s %s"%(method, path))
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def check_size(self, req, actions):
|
||||||
|
return False
|
||||||
|
|
||||||
def handle(self):
|
def handle(self):
|
||||||
if self.server.ssloptions:
|
if self.server.ssloptions:
|
||||||
try:
|
try:
|
||||||
@ -145,7 +148,7 @@ class PathodHandler(tcp.BaseHandler):
|
|||||||
|
|
||||||
class Pathod(tcp.TCPServer):
|
class Pathod(tcp.TCPServer):
|
||||||
LOGBUF = 500
|
LOGBUF = 500
|
||||||
def __init__(self, addr, ssloptions=None, prefix="/p/", staticdir=None, anchors=None):
|
def __init__(self, addr, ssloptions=None, prefix="/p/", staticdir=None, anchors=None, sizelimit=None):
|
||||||
"""
|
"""
|
||||||
addr: (address, port) tuple. If port is 0, a free port will be
|
addr: (address, port) tuple. If port is 0, a free port will be
|
||||||
automatically chosen.
|
automatically chosen.
|
||||||
@ -153,11 +156,13 @@ class Pathod(tcp.TCPServer):
|
|||||||
prefix: string specifying the prefix at which to anchor response generation.
|
prefix: string specifying the prefix at which to anchor response generation.
|
||||||
staticdir: path to a directory of static resources, or None.
|
staticdir: path to a directory of static resources, or None.
|
||||||
anchors: A list of (regex, spec) tuples, or None.
|
anchors: A list of (regex, spec) tuples, or None.
|
||||||
|
sizelimit: Limit size of served data.
|
||||||
"""
|
"""
|
||||||
tcp.TCPServer.__init__(self, addr)
|
tcp.TCPServer.__init__(self, addr)
|
||||||
self.ssloptions = ssloptions
|
self.ssloptions = ssloptions
|
||||||
self.staticdir = staticdir
|
self.staticdir = staticdir
|
||||||
self.prefix = prefix
|
self.prefix = prefix
|
||||||
|
self.sizelimit = sizelimit
|
||||||
self.app = app.app
|
self.app = app.app
|
||||||
self.app.config["pathod"] = self
|
self.app.config["pathod"] = self
|
||||||
self.log = []
|
self.log = []
|
||||||
|
@ -25,6 +25,18 @@ class ParseException(Exception):
|
|||||||
class ServerError(Exception): pass
|
class ServerError(Exception): pass
|
||||||
|
|
||||||
|
|
||||||
|
def actions_log(lst):
|
||||||
|
ret = []
|
||||||
|
for i in lst:
|
||||||
|
if i[1] == "inject":
|
||||||
|
ret.append(
|
||||||
|
[i[0], i[1], repr(i[2])]
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
ret.append(i)
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def ready_actions(length, lst):
|
def ready_actions(length, lst):
|
||||||
ret = []
|
ret = []
|
||||||
for i in lst:
|
for i in lst:
|
||||||
@ -527,7 +539,15 @@ class Message:
|
|||||||
l += len(i[2])
|
l += len(i[2])
|
||||||
return l
|
return l
|
||||||
|
|
||||||
def serve(self, fp):
|
def serve(self, fp, check):
|
||||||
|
"""
|
||||||
|
fp: The file pointer to write to.
|
||||||
|
|
||||||
|
check: A function called with the effective actions (after random
|
||||||
|
values have been calculated). If it returns False service
|
||||||
|
proceeds, otherwise the return is treated as an error message to be
|
||||||
|
sent to the client, and service stops.
|
||||||
|
"""
|
||||||
started = time.time()
|
started = time.time()
|
||||||
if self.body and not utils.get_header("Content-Length", self.headers):
|
if self.body and not utils.get_header("Content-Length", self.headers):
|
||||||
self.headers.append(
|
self.headers.append(
|
||||||
@ -554,13 +574,26 @@ class Message:
|
|||||||
vals.reverse()
|
vals.reverse()
|
||||||
actions = ready_actions(self.length(), self.actions)
|
actions = ready_actions(self.length(), self.actions)
|
||||||
actions.reverse()
|
actions.reverse()
|
||||||
|
if check:
|
||||||
|
ret = check(self, actions)
|
||||||
|
if ret:
|
||||||
|
err = InternalResponse(
|
||||||
|
800,
|
||||||
|
ret
|
||||||
|
)
|
||||||
|
err.serve(fp)
|
||||||
|
return dict(
|
||||||
|
disconnect = True,
|
||||||
|
actions = actions_log(actions),
|
||||||
|
error = ret
|
||||||
|
)
|
||||||
disconnect = write_values(fp, vals, actions[:])
|
disconnect = write_values(fp, vals, actions[:])
|
||||||
duration = time.time() - started
|
duration = time.time() - started
|
||||||
ret = dict(
|
ret = dict(
|
||||||
disconnect = disconnect,
|
disconnect = disconnect,
|
||||||
started = started,
|
started = started,
|
||||||
duration = duration,
|
duration = duration,
|
||||||
actions = actions,
|
actions = actions_log(actions),
|
||||||
)
|
)
|
||||||
for i in self.logattrs:
|
for i in self.logattrs:
|
||||||
v = getattr(self, i)
|
v = getattr(self, i)
|
||||||
@ -661,8 +694,8 @@ class CraftedRequest(Request):
|
|||||||
for i in tokens:
|
for i in tokens:
|
||||||
i.accept(settings, self)
|
i.accept(settings, self)
|
||||||
|
|
||||||
def serve(self, fp):
|
def serve(self, fp, check=None):
|
||||||
d = Request.serve(self, fp)
|
d = Request.serve(self, fp, check)
|
||||||
d["spec"] = self.spec
|
d["spec"] = self.spec
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@ -674,8 +707,8 @@ class CraftedResponse(Response):
|
|||||||
for i in tokens:
|
for i in tokens:
|
||||||
i.accept(settings, self)
|
i.accept(settings, self)
|
||||||
|
|
||||||
def serve(self, fp):
|
def serve(self, fp, check=None):
|
||||||
d = Response.serve(self, fp)
|
d = Response.serve(self, fp, check)
|
||||||
d["spec"] = self.spec
|
d["spec"] = self.spec
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@ -697,8 +730,8 @@ class InternalResponse(Response):
|
|||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
def serve(self, fp):
|
def serve(self, fp, check=None):
|
||||||
d = Response.serve(self, fp)
|
d = Response.serve(self, fp, check)
|
||||||
d["internal"] = True
|
d["internal"] = True
|
||||||
return d
|
return d
|
||||||
|
|
||||||
|
@ -419,6 +419,13 @@ class TestResponse:
|
|||||||
assert r.body[:]
|
assert r.body[:]
|
||||||
assert str(r)
|
assert str(r)
|
||||||
|
|
||||||
|
def test_checkfunc(self):
|
||||||
|
s = cStringIO.StringIO()
|
||||||
|
r = rparse.parse_response({}, "400:b@100k")
|
||||||
|
def check(req, acts):
|
||||||
|
return "errmsg"
|
||||||
|
assert r.serve(s, check=check)["error"] == "errmsg"
|
||||||
|
|
||||||
def test_render(self):
|
def test_render(self):
|
||||||
s = cStringIO.StringIO()
|
s = cStringIO.StringIO()
|
||||||
r = rparse.parse_response({}, "400'msg'")
|
r = rparse.parse_response({}, "400'msg'")
|
||||||
|
Loading…
Reference in New Issue
Block a user