diff options
-rw-r--r-- | libpathod/app.py | 27 | ||||
-rw-r--r-- | libpathod/rparse.py | 29 | ||||
-rw-r--r-- | test/test_app.py | 12 | ||||
-rw-r--r-- | test/test_rparse.py | 6 | ||||
-rw-r--r-- | todo | 2 |
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'")) @@ -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 |