aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libpathod/pathod.py31
-rw-r--r--libpathod/test.py8
-rw-r--r--test/test_pathod.py6
-rw-r--r--test/test_test.py12
4 files changed, 45 insertions, 12 deletions
diff --git a/libpathod/pathod.py b/libpathod/pathod.py
index ef37d5ad..1491072c 100644
--- a/libpathod/pathod.py
+++ b/libpathod/pathod.py
@@ -1,4 +1,4 @@
-import urllib, threading
+import urllib, threading, re
from netlib import tcp, http, odict, wsgi
import version, app, rparse
@@ -23,16 +23,23 @@ class PathodHandler(tcp.BaseHandler):
self.rfile, self.wfile, headers, httpversion, None
)
- if path.startswith(self.server.prefix):
+ crafted = None
+ for i in self.server.anchors:
+ if i[0].match(path):
+ crafted = i[1]
+
+ if not crafted and path.startswith(self.server.prefix):
spec = urllib.unquote(path)[len(self.server.prefix):]
try:
- presp = rparse.parse(self.server.request_settings, spec)
+ crafted = rparse.parse(self.server.request_settings, spec)
except rparse.ParseException, v:
- presp = rparse.InternalResponse(
+ crafted = rparse.InternalResponse(
800,
"Error parsing response spec: %s\n"%v.msg + v.marked()
)
- ret = presp.serve(self.wfile)
+
+ if crafted:
+ ret = crafted.serve(self.wfile)
if ret["disconnect"]:
self.finish()
ret["request"] = dict(
@@ -62,6 +69,14 @@ class PathodHandler(tcp.BaseHandler):
class Pathod(tcp.TCPServer):
LOGBUF = 500
def __init__(self, addr, ssloptions=None, prefix="/p/", staticdir=None, anchors=None):
+ """
+ addr: (address, port) tuple. If port is 0, a free port will be
+ automatically chosen.
+ ssloptions: a dictionary containing certfile and keyfile specifications.
+ prefix: string specifying the prefix at which to anchor response generation.
+ staticdir: path to a directory of static resources, or None.
+ anchors: A list of (regex, spec) tuples, or None.
+ """
tcp.TCPServer.__init__(self, addr)
self.ssloptions = ssloptions
self.staticdir = staticdir
@@ -70,6 +85,12 @@ class Pathod(tcp.TCPServer):
self.app.config["pathod"] = self
self.log = []
self.logid = 0
+ self.anchors = []
+ if anchors:
+ for i in anchors:
+ arex = re.compile(i[0])
+ aresp = rparse.parse(self.request_settings, i[1])
+ self.anchors.append((arex, aresp))
@property
def request_settings(self):
diff --git a/libpathod/test.py b/libpathod/test.py
index cb1b9745..00e03823 100644
--- a/libpathod/test.py
+++ b/libpathod/test.py
@@ -8,7 +8,7 @@ IFACE = "127.0.0.1"
class Daemon:
def __init__(self, staticdir=None, anchors=(), ssl=None):
self.q = Queue.Queue()
- self.thread = PaThread(self.q, ssl, staticdir)
+ self.thread = PaThread(self.q, staticdir, anchors, ssl)
self.thread.start()
self.port = self.q.get(True, 5)
self.urlbase = "%s://%s:%s"%("https" if ssl else "http", IFACE, self.port)
@@ -43,10 +43,9 @@ class Daemon:
class PaThread(threading.Thread):
- def __init__(self, q, ssl, staticdir):
+ def __init__(self, q, staticdir, anchors, ssl):
threading.Thread.__init__(self)
- self.q, self.ssl, self.staticdir = q, ssl, staticdir
- self.port = None
+ self.q, self.staticdir, self.anchors, self.ssl = q, staticdir, anchors, ssl
def run(self):
if self.ssl is True:
@@ -59,6 +58,7 @@ class PaThread(threading.Thread):
self.server = pathod.Pathod(
(IFACE, 0),
ssloptions = ssloptions,
+ anchors = self.anchors,
staticdir = self.staticdir
)
self.q.put(self.server.port)
diff --git a/test/test_pathod.py b/test/test_pathod.py
index 966ae12e..e00694cd 100644
--- a/test/test_pathod.py
+++ b/test/test_pathod.py
@@ -15,7 +15,11 @@ class _TestApplication:
class TestPathod:
def test_instantiation(self):
- p = pathod.Pathod(("127.0.0.1", 0))
+ p = pathod.Pathod(
+ ("127.0.0.1", 0),
+ anchors = [(".*", "200")]
+ )
+ assert p.anchors
def test_logging(self):
p = pathod.Pathod(("127.0.0.1", 0))
diff --git a/test/test_test.py b/test/test_test.py
index b9a9cfac..dcf980bc 100644
--- a/test/test_test.py
+++ b/test/test_test.py
@@ -38,7 +38,10 @@ class TestDaemonManual:
class TestDaemon:
@classmethod
def setUpAll(self):
- self.d = test.Daemon(staticdir=tutils.test_data.path("data"))
+ self.d = test.Daemon(
+ staticdir=tutils.test_data.path("data"),
+ anchors=[("/anchor/.*", "202")]
+ )
@classmethod
def tearDownAll(self):
@@ -47,6 +50,9 @@ class TestDaemon:
def setUp(self):
self.d.clear_log()
+ def getpath(self, path):
+ return requests.get("http://localhost:%s/%s"%(self.d.port, path))
+
def get(self, spec):
return requests.get("http://localhost:%s/p/%s"%(self.d.port, spec))
@@ -72,5 +78,7 @@ class TestDaemon:
assert rsp.status_code == 200
assert rsp.content.strip() == "testfile"
-
+ def test_anchor(self):
+ rsp = self.getpath("anchor/foo")
+ assert rsp.status_code == 202