aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAldo Cortesi <aldo@nullcube.com>2012-04-29 14:59:54 +1200
committerAldo Cortesi <aldo@nullcube.com>2012-04-29 14:59:54 +1200
commitfd946f0c04c2471ab9e579087af3f4cb645be41a (patch)
tree65c9b2f20d0d5a4ba9569435d6b5f0cad053f10e
parent6d4500c67943d03cf0910256ef9dab46789f366f (diff)
downloadmitmproxy-fd946f0c04c2471ab9e579087af3f4cb645be41a.tar.gz
mitmproxy-fd946f0c04c2471ab9e579087af3f4cb645be41a.tar.bz2
mitmproxy-fd946f0c04c2471ab9e579087af3f4cb645be41a.zip
Basic logging.
-rw-r--r--libpathod/app.py27
-rw-r--r--libpathod/rparse.py29
-rw-r--r--test/test_app.py12
-rw-r--r--test/test_rparse.py6
-rw-r--r--todo2
5 files changed, 64 insertions, 12 deletions
diff --git a/libpathod/app.py b/libpathod/app.py
index ac118602..ef549334 100644
--- a/libpathod/app.py
+++ b/libpathod/app.py
@@ -1,4 +1,4 @@
-import urllib
+import urllib, pprint
import tornado.web, tornado.template, tornado.ioloop, tornado.httpserver
import rparse, utils
@@ -48,7 +48,20 @@ class Pathod(object):
)
def _execute(self, transforms, *args, **kwargs):
- self.response.render(self.request)
+ d = self.response.serve(self.request)
+ d["request"] = dict(
+ path = self.request.path,
+ method = self.request.method,
+ headers = self.request.headers,
+ host = self.request.host,
+ protocol = self.request.protocol,
+ remote_address = self.request.connection.address,
+ full_url = self.request.full_url(),
+ query = self.request.query,
+ version = self.request.version,
+ uri = self.request.uri,
+ )
+ self.application.add_log(d)
class RequestPathod(Pathod):
@@ -59,6 +72,7 @@ class RequestPathod(Pathod):
class PathodApp(tornado.web.Application):
+ LOGBUF = 500
def __init__(self, **settings):
self.templates = tornado.template.Loader(utils.data.path("templates"))
self.appsettings = settings
@@ -75,6 +89,8 @@ class PathodApp(tornado.web.Application):
template_path = utils.data.path("templates"),
debug=True
)
+ self.log = []
+ self.logid = 0
def add_anchor(self, pattern, spec):
"""
@@ -116,6 +132,13 @@ class PathodApp(tornado.web.Application):
del l[i]
return
+ def add_log(self, d):
+ d["id"] = self.logid
+ self.log.insert(0, d)
+ if len(self.log) > self.LOGBUF:
+ self.log.pop()
+ self.logid += 1
+
# begin nocover
def run(application, port, ssl_options):
diff --git a/libpathod/rparse.py b/libpathod/rparse.py
index de69e9b9..1a6a5e4c 100644
--- a/libpathod/rparse.py
+++ b/libpathod/rparse.py
@@ -1,4 +1,4 @@
-import operator, string, random, sys, time, mmap, os
+import operator, string, random, sys, time, mmap, os, time
import contrib.pyparsing as pp
import http, utils
import tornado.ioloop
@@ -430,7 +430,8 @@ class Response:
skip = 0
fp.finish()
- def render(self, fp):
+ def serve(self, fp):
+ started = time.time()
if self.body and not self.get_header("Content-Length"):
self.headers.append(
(
@@ -460,7 +461,13 @@ class Response:
vals.reverse()
actions = self.ready_actions(self.length(), self.actions)
actions.reverse()
- return self.write_values(fp, vals, actions)
+ self.write_values(fp, vals, actions[:])
+ duration = time.time() - started
+ return dict(
+ started = started,
+ duration = duration,
+ actions = actions,
+ )
def __str__(self):
parts = [
@@ -470,12 +477,17 @@ class Response:
class CraftedResponse(Response):
- def __init__(self, settings, tokens):
+ def __init__(self, settings, spec, tokens):
Response.__init__(self)
- self.tokens = tokens
+ self.spec, self.tokens = spec, tokens
for i in tokens:
i.mod_response(settings, self)
+ def serve(self, fp):
+ d = Response.serve(self, fp)
+ d["spec"] = self.spec
+ return d
+
class InternalResponse(Response):
def __init__(self, code, body):
@@ -494,9 +506,14 @@ class InternalResponse(Response):
)
]
+ def serve(self, fp):
+ d = Response.serve(self, fp)
+ d["internal"] = True
+ return d
+
def parse(settings, s):
try:
- return CraftedResponse(settings, Response.expr().parseString(s, parseAll=True))
+ return CraftedResponse(settings, s, Response.expr().parseString(s, parseAll=True))
except pp.ParseException, v:
raise ParseException(v.msg, v.line, v.col)
diff --git a/test/test_app.py b/test/test_app.py
index e0060e82..721b36d7 100644
--- a/test/test_app.py
+++ b/test/test_app.py
@@ -14,6 +14,18 @@ class uApplication(libpry.AutoTree):
a.remove_anchor("/oink", "400")
assert a.get_anchors() == [("/foo", "200")]
+ def test_logs(self):
+ a = app.PathodApp(staticdir=None)
+ a.LOGBUF = 3
+ a.add_log({})
+ assert a.log[0]["id"] == 0
+ a.add_log({})
+ a.add_log({})
+ assert a.log[0]["id"] == 2
+ a.add_log({})
+ assert len(a.log) == 3
+ assert a.log[0]["id"] == 3
+ assert a.log[-1]["id"] == 1
class uPages(libpry.AutoTree):
def dummy_page(self, path):
diff --git a/test/test_rparse.py b/test/test_rparse.py
index 67fac11e..f9c07eec 100644
--- a/test/test_rparse.py
+++ b/test/test_rparse.py
@@ -152,7 +152,7 @@ class uMisc(libpry.AutoTree):
def test_internal_response(self):
d = DummyRequest()
s = rparse.InternalResponse(400, "foo")
- s.render(d)
+ s.serve(d)
class uDisconnects(libpry.AutoTree):
@@ -296,12 +296,12 @@ class uResponse(libpry.AutoTree):
def test_render(self):
s = DummyRequest()
r = rparse.parse({}, "400'msg'")
- r.render(s)
+ assert r.serve(s)
def test_length(self):
def testlen(x):
s = DummyRequest()
- x.render(s)
+ x.serve(s)
assert x.length() == len(s.getvalue())
testlen(rparse.parse({}, "400'msg'"))
testlen(rparse.parse({}, "400'msg':h'foo'='bar'"))
diff --git a/todo b/todo
index 112aed22..f38847da 100644
--- a/todo
+++ b/todo
@@ -1,12 +1,12 @@
0.1:
- - Disconnect or pause at specified byte offset
- Logs
- API
- Logs, log reset, log retrieval
- Anchor management
0.2:
+ - Specify if server should add Server and Date headers
- Shortcuts for cookies, auth
- Various SSL errors (expired certs, etc.)
- Caching