aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAldo Cortesi <aldo@nullcube.com>2012-10-28 12:56:08 +1300
committerAldo Cortesi <aldo@nullcube.com>2012-10-28 12:56:08 +1300
commit9d42a06c92f0fdc7ca986b738086d361d9b0599b (patch)
tree03604d6f93c3358d8cf70bf0e94f601e8ce5754b
parentf54ed69a358d2dd059bd844c752f96e29e90e269 (diff)
downloadmitmproxy-9d42a06c92f0fdc7ca986b738086d361d9b0599b.tar.gz
mitmproxy-9d42a06c92f0fdc7ca986b738086d361d9b0599b.tar.bz2
mitmproxy-9d42a06c92f0fdc7ca986b738086d361d9b0599b.zip
Move message body to new lazy-generator scheme.
-rw-r--r--.gitignore2
-rw-r--r--libpathod/app.py6
-rw-r--r--libpathod/language.py21
-rw-r--r--libpathod/pathod.py13
-rw-r--r--test/test_app.py8
-rw-r--r--test/test_language.py2
-rw-r--r--test/test_pathod.py2
7 files changed, 33 insertions, 21 deletions
diff --git a/.gitignore b/.gitignore
index 674722aa..2c7c0b9a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,5 +7,7 @@ MANIFEST
*.swp
/doc
.coverage
+.noseids
netlib
venv
+
diff --git a/libpathod/app.py b/libpathod/app.py
index 6f12c0a2..38d0be33 100644
--- a/libpathod/app.py
+++ b/libpathod/app.py
@@ -123,18 +123,14 @@ def _preview(is_request):
args["syntaxerror"] = str(v)
args["marked"] = v.marked()
return render(template, False, **args)
- except language.FileAccessDenied:
- args["error"] = "File access is disabled."
- return render(template, False, **args)
s = cStringIO.StringIO()
args["pauses"] = r.preview_safe()
- c = app.config["pathod"].check_policy(r)
+ c = app.config["pathod"].check_policy(r, app.config["pathod"].request_settings)
if c:
args["error"] = c
return render(template, False, **args)
-
if is_request:
r.serve(s, app.config["pathod"].request_settings, host="example.com")
else:
diff --git a/libpathod/language.py b/libpathod/language.py
index 31239b74..5d6471e6 100644
--- a/libpathod/language.py
+++ b/libpathod/language.py
@@ -345,7 +345,7 @@ class Body:
self.value = value
def accept(self, settings, r):
- r.body = self.value.get_generator(settings)
+ r.body = self
@classmethod
def expr(klass):
@@ -353,6 +353,11 @@ class Body:
e = e + Value
return e.setParseAction(lambda x: klass(*x))
+ def values(self, settings):
+ return [
+ self.value.get_generator(settings),
+ ]
+
class Raw:
def accept(self, settings, r):
@@ -532,7 +537,7 @@ class Code:
class Message:
version = "HTTP/1.1"
def __init__(self):
- self.body = LiteralGenerator("")
+ self.body = None
self.headers = []
self.actions = []
self.raw = False
@@ -546,7 +551,8 @@ class Message:
for h in self.headervals(settings, request_host):
l += len(h)
l += 2
- l += len(self.body)
+ if self.body:
+ l += len(self.body.value.get_generator(settings))
return l
def preview_safe(self):
@@ -574,7 +580,7 @@ class Message:
hdrs.append(
Header(
ValueLiteral("Content-Length"),
- ValueLiteral(str(len(self.body))),
+ ValueLiteral(str(len(self.body.value.get_generator(settings)))),
)
)
if request_host:
@@ -624,7 +630,7 @@ class Message:
vals.extend(hdrs)
vals.append("\r\n")
if self.body:
- vals.append(self.body)
+ vals.append(self.body.value.get_generator(settings))
vals.reverse()
actions = self.ready_actions(settings, request_host)
@@ -638,6 +644,9 @@ class Message:
for i in self.logattrs:
v = getattr(self, i)
# Careful not to log any VALUE specs without sanitizing them first. We truncate at 1k.
+ if hasattr(v, "values"):
+ v = [x[:TRUNCATE] for x in v.values(settings)]
+ v = "".join(v)
if hasattr(v, "__len__"):
v = v[:TRUNCATE]
v = v.encode("string_escape")
@@ -757,7 +766,7 @@ class PathodErrorResponse(Response):
Response.__init__(self)
self.code = 800
self.msg = LiteralGenerator(msg)
- self.body = LiteralGenerator("pathod error: " + (body or msg))
+ self.body = Body(ValueLiteral("pathod error: " + (body or msg)))
self.headers = [
Header(ValueLiteral("Content-Type"), ValueLiteral("text/plain")),
]
diff --git a/libpathod/pathod.py b/libpathod/pathod.py
index d80a9018..131dbc3c 100644
--- a/libpathod/pathod.py
+++ b/libpathod/pathod.py
@@ -18,7 +18,7 @@ class PathodHandler(tcp.BaseHandler):
self.sni = connection.get_servername()
def serve_crafted(self, crafted, request_log):
- c = self.server.check_policy(crafted)
+ c = self.server.check_policy(crafted, self.server.request_settings)
if c:
err = language.PathodErrorResponse(c)
err.serve(self.wfile, self.server.request_settings)
@@ -100,9 +100,6 @@ class PathodHandler(tcp.BaseHandler):
"Parse Error",
"Error parsing response spec: %s\n"%v.msg + v.marked()
)
- except language.FileAccessDenied:
- self.info("File access denied")
- crafted = language.PathodErrorResponse("Access Denied")
return self.serve_crafted(crafted, request_log)
elif self.server.noweb:
crafted = language.PathodErrorResponse("Access Denied")
@@ -215,11 +212,15 @@ class Pathod(tcp.TCPServer):
raise PathodError("Invalid page spec in anchor: '%s', %s"%(i[1], str(v)))
self.anchors.append((arex, i[1]))
- def check_policy(self, req):
+ def check_policy(self, req, settings):
"""
A policy check that verifies the request size is withing limits.
"""
- if self.sizelimit and req.maximum_length({}, None) > self.sizelimit:
+ try:
+ l = req.maximum_length(settings, None)
+ except language.FileAccessDenied, v:
+ return "File access denied."
+ if self.sizelimit and l > self.sizelimit:
return "Response too large."
if self.nohang and any([isinstance(i, language.PauseAt) for i in req.actions]):
return "Pauses have been disabled."
diff --git a/test/test_app.py b/test/test_app.py
index 7b2451d6..b3194052 100644
--- a/test/test_app.py
+++ b/test/test_app.py
@@ -47,9 +47,13 @@ class TestApp(tutils.DaemonTests):
assert r.status_code == 200
assert 'Response' in r.content
- r = self.getpath("/response_preview", params=dict(spec="200:b<foo"))
+ r = self.getpath("/response_preview", params=dict(spec="200:b<nonexistent"))
assert r.status_code == 200
- assert 'File access is disabled' in r.content
+ assert 'File access denied' in r.content
+
+ r = self.getpath("/response_preview", params=dict(spec="200:b<file"))
+ assert r.status_code == 200
+ assert 'testfile' in r.content
def test_request_preview(self):
r = self.getpath("/request_preview", params=dict(spec="get:/"))
diff --git a/test/test_language.py b/test/test_language.py
index e5ec51d2..54f96d51 100644
--- a/test/test_language.py
+++ b/test/test_language.py
@@ -508,7 +508,7 @@ class TestResponse:
r = language.parse_response({}, "400'msg':b@100b")
assert r.msg == "msg"
- assert r.body[:]
+ assert r.body.values({})
assert str(r)
def test_render(self):
diff --git a/test/test_pathod.py b/test/test_pathod.py
index 195c7333..83f57727 100644
--- a/test/test_pathod.py
+++ b/test/test_pathod.py
@@ -141,7 +141,7 @@ class CommonTests(tutils.DaemonTests):
def test_source_access_denied(self):
rsp = self.get("200:b</foo")
assert rsp.status_code == 800
- assert "Access Denied" in rsp.content
+ assert "File access denied" in rsp.content
class TestDaemon(CommonTests):