From 12c140b951705c08131cc4b86a247bccc9c493c0 Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Thu, 21 Jun 2012 14:29:49 +1200 Subject: Restore client argument parsing. Add thread-safe logging subsystem. --- libpathod/pathod.py | 32 +++++++++++++++++++++++++++-- opathod | 56 --------------------------------------------------- pathod | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++--- test/test_pathod.py | 16 +++++++++++++-- 4 files changed, 99 insertions(+), 63 deletions(-) delete mode 100755 opathod diff --git a/libpathod/pathod.py b/libpathod/pathod.py index e0a0764f..edf6e03a 100644 --- a/libpathod/pathod.py +++ b/libpathod/pathod.py @@ -1,4 +1,4 @@ -import urllib +import urllib, threading from netlib import tcp, protocol, odict, wsgi import version, app, rparse @@ -22,6 +22,7 @@ class PathodHandler(tcp.BaseHandler): content = protocol.read_http_body_request( self.rfile, self.wfile, headers, httpversion, None ) + if path.startswith(self.server.prefix): spec = urllib.unquote(path)[len(self.server.prefix):] try: @@ -34,6 +35,7 @@ class PathodHandler(tcp.BaseHandler): ret = presp.serve(self.wfile) if ret["disconnect"]: self.close() + self.server.add_log(ret) else: cc = wsgi.ClientConn(self.client_address) req = wsgi.Request(cc, "http", method, path, headers, content) @@ -48,12 +50,38 @@ class PathodHandler(tcp.BaseHandler): class Pathod(tcp.TCPServer): - def __init__(self, addr, ssloptions=None, prefix="/p/"): + LOGBUF = 500 + def __init__(self, addr, ssloptions=None, prefix="/p/", staticdir=None, anchors=None): tcp.TCPServer.__init__(self, addr) self.ssloptions = ssloptions self.prefix = prefix self.app = app.app self.app.config["pathod"] = self + self.log = [] + self.logid = 0 def handle_connection(self, request, client_address): PathodHandler(request, client_address, self) + + def add_log(self, d): + lock = threading.Lock() + with lock: + d["id"] = self.logid + self.log.insert(0, d) + if len(self.log) > self.LOGBUF: + self.log.pop() + self.logid += 1 + return d["id"] + + def clear_log(self): + lock = threading.Lock() + with lock: + self.log = [] + + def log_by_id(self, id): + for i in self.log: + if i["id"] == id: + return i + + def get_log(self): + return self.log diff --git a/opathod b/opathod deleted file mode 100755 index f49baa34..00000000 --- a/opathod +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env python -import argparse, sys -from libpathod import pathod, utils, version -import tornado.ioloop - -if __name__ == "__main__": - parser = argparse.ArgumentParser(description='Process some integers.') - parser.add_argument("-p", dest='port', default=9999, type=int, help='Port. Specify 0 to pick an arbitrary empty port.') - parser.add_argument("-l", dest='address', default="0.0.0.0", type=str, help='Listening address.') - parser.add_argument( - "-a", dest='anchors', default=[], type=str, action="append", - help='Add an anchor. Specified as a string with the form pattern=pagespec' - ) - parser.add_argument( - "-d", dest='staticdir', default=None, type=str, - help='Directory for static files.' - ) - parser.add_argument( - "-s", dest='ssl', default=False, - action="store_true", - help='Serve with SSL.' - ) - parser.add_argument( - "--keyfile", dest='ssl_keyfile', default=None, - type=str, - help='SSL key file. If not specified, a default key is used.' - ) - parser.add_argument( - "--certfile", dest='ssl_certfile', default=None, - type=str, - help='SSL cert file. If not specified, a default cert is used.' - ) - args = parser.parse_args() - - try: - app = pathod.make_app(staticdir=args.staticdir, anchors=args.anchors) - except utils.AnchorError, v: - parser.error(str(v)) - - sl = [args.ssl_keyfile, args.ssl_certfile] - if any(sl) and not all(sl): - parser.error("Both --certfile and --keyfile must be specified.") - - if args.ssl: - ssl = dict( - keyfile = args.ssl_keyfile or utils.data.path("resources/server.key"), - certfile = args.ssl_certfile or utils.data.path("resources/server.crt"), - ) - else: - ssl = None - try: - server, port = pathod.make_server(app, args.port, args.address, ssl) - print "%s listening on port %s"%(version.NAMEVERSION, port) - pathod.run(server) - except KeyboardInterrupt: - pass diff --git a/pathod b/pathod index f1cdc96c..d8565144 100755 --- a/pathod +++ b/pathod @@ -1,5 +1,57 @@ #!/usr/bin/env python -from libpathod import pathod +import argparse, sys +from libpathod import pathod, utils, version +import tornado.ioloop -s = pathod.Pathod(("127.0.0.1", 8888)) -s.serve_forever() +if __name__ == "__main__": + parser = argparse.ArgumentParser(description='Process some integers.') + parser.add_argument("-p", dest='port', default=9999, type=int, help='Port. Specify 0 to pick an arbitrary empty port.') + parser.add_argument("-l", dest='address', default="0.0.0.0", type=str, help='Listening address.') + parser.add_argument( + "-a", dest='anchors', default=[], type=str, action="append", + help='Add an anchor. Specified as a string with the form pattern=pagespec' + ) + parser.add_argument( + "-d", dest='staticdir', default=None, type=str, + help='Directory for static files.' + ) + parser.add_argument( + "-s", dest='ssl', default=False, + action="store_true", + help='Serve with SSL.' + ) + parser.add_argument( + "--keyfile", dest='ssl_keyfile', default=None, + type=str, + help='SSL key file. If not specified, a default key is used.' + ) + parser.add_argument( + "--certfile", dest='ssl_certfile', default=None, + type=str, + help='SSL cert file. If not specified, a default cert is used.' + ) + args = parser.parse_args() + + sl = [args.ssl_keyfile, args.ssl_certfile] + if any(sl) and not all(sl): + parser.error("Both --certfile and --keyfile must be specified.") + + if args.ssl: + ssl = dict( + keyfile = args.ssl_keyfile or utils.data.path("resources/server.key"), + certfile = args.ssl_certfile or utils.data.path("resources/server.crt"), + ) + else: + ssl = None + + pd = pathod.Pathod( + (args.address, args.port), + ssloptions = ssl, + staticdir = args.staticdir, + anchors = args.anchors + ) + try: + print "%s listening on port %s"%(version.NAMEVERSION, pd.port) + pd.serve_forever() + except KeyboardInterrupt: + pass diff --git a/test/test_pathod.py b/test/test_pathod.py index 36a2d090..9c16748d 100644 --- a/test/test_pathod.py +++ b/test/test_pathod.py @@ -31,5 +31,17 @@ class _TestApplication: class TestPathod: def test_instantiation(self): - pathod.Pathod(("127.0.0.1", 0)) - + p = pathod.Pathod(("127.0.0.1", 0)) + + def test_logging(self): + p = pathod.Pathod(("127.0.0.1", 0)) + assert len(p.get_log()) == 0 + id = p.add_log(dict(s="foo")) + assert p.log_by_id(id) + assert len(p.get_log()) == 1 + p.clear_log() + assert len(p.get_log()) == 0 + + for i in range(p.LOGBUF + 1): + p.add_log(dict(s="foo")) + assert len(p.get_log()) <= p.LOGBUF -- cgit v1.2.3