aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libpathod/language.py48
-rw-r--r--test/test_language.py25
-rw-r--r--test/test_pathoc.py5
3 files changed, 73 insertions, 5 deletions
diff --git a/libpathod/language.py b/libpathod/language.py
index 56cbc18b..d8e87145 100644
--- a/libpathod/language.py
+++ b/libpathod/language.py
@@ -1,3 +1,4 @@
+from __future__ import print_function
import operator
import string
import random
@@ -6,7 +7,6 @@ import os
import time
import copy
import abc
-from email.utils import formatdate
import contrib.pyparsing as pp
from netlib import http_status, tcp, http_uastrings
@@ -527,6 +527,43 @@ class Body(_Component):
return Body(self.value.freeze(settings))
+class PathodSpec(_Token):
+ def __init__(self, value):
+ self.value = value
+ try:
+ self.parsed = Response(
+ Response.expr().parseString(
+ value.val,
+ parseAll=True
+ )
+ )
+ except pp.ParseException, v:
+ raise ParseException(v.msg, v.line, v.col)
+
+ @classmethod
+ def expr(klass):
+ e = pp.Literal("s").suppress()
+ e = e + ValueLiteral.expr()
+ return e.setParseAction(lambda x: klass(*x))
+
+ def values(self, settings):
+ return [
+ self.value.get_generator(settings),
+ ]
+
+ def quote(self, s):
+ quotechar = s[0]
+ s = s[1:-1]
+ s = s.replace(quotechar, "\\" + quotechar)
+ return quotechar + s + quotechar
+
+ def spec(self):
+ return "s%s"%(self.quote(self.value.spec()))
+
+ def freeze(self, settings):
+ return PathodSpec(ValueLiteral(self.parsed.freeze(settings).spec()))
+
+
class Path(_Component):
def __init__(self, value):
if isinstance(value, basestring):
@@ -934,7 +971,8 @@ class Request(_Message):
InjectAt,
ShortcutContentType,
ShortcutUserAgent,
- Raw
+ Raw,
+ PathodSpec,
)
logattrs = ["method", "path", "body"]
@@ -946,10 +984,16 @@ class Request(_Message):
def path(self):
return self._get_token(Path)
+ @property
+ def pathodspec(self):
+ return self._get_token(PathodSpec)
+
def preamble(self, settings):
v = self.method.values(settings)
v.append(" ")
v.extend(self.path.values(settings))
+ if self.pathodspec:
+ v.append(self.pathodspec.parsed.spec())
v.append(" ")
v.append(self.version)
return v
diff --git a/test/test_language.py b/test/test_language.py
index 0818c587..f3cfa5a9 100644
--- a/test/test_language.py
+++ b/test/test_language.py
@@ -223,6 +223,29 @@ class TestMisc:
s = v.spec()
assert s == e.parseString(s)[0].spec()
+ def test_pathodspec(self):
+ e = language.PathodSpec.expr()
+ v = e.parseString("s'200'")[0]
+ assert v.value.val == "200"
+ tutils.raises(
+ language.ParseException,
+ e.parseString,
+ "s'foo'"
+ )
+
+ v = e.parseString('s"200:b@1"')[0]
+ assert "@1" in v.spec()
+ f = v.freeze({})
+ assert "@1" not in f.spec()
+
+ r = parse_request('GET:"/foo":s"200"')
+ assert "200" in r.preamble({})
+
+ f = r.freeze({})
+ assert parse_request(f.spec())
+
+
+
def test_code(self):
e = language.Code.expr()
v = e.parseString("200")[0]
@@ -661,14 +684,12 @@ class TestResponse:
language.serve(r, s, {})
v = s.getvalue()
assert "Content-Length" in v
- assert "Date" in v
s = cStringIO.StringIO()
r = language.parse_response("400:b'foo':r")
language.serve(r, s, {})
v = s.getvalue()
assert not "Content-Length" in v
- assert not "Date" in v
def test_length(self):
def testlen(x):
diff --git a/test/test_pathoc.py b/test/test_pathoc.py
index 2542b622..23b42994 100644
--- a/test/test_pathoc.py
+++ b/test/test_pathoc.py
@@ -59,8 +59,11 @@ class _TestDaemon:
c.settimeout(timeout)
s = cStringIO.StringIO()
for i in requests:
+ r = language.parse_requests(i)[0]
+ if explain:
+ r = r.freeze({})
c.print_request(
- language.parse_requests(i)[0],
+ r,
showreq = showreq,
showresp = showresp,
explain = explain,