aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libpathod/language/base.py53
-rw-r--r--libpathod/language/http.py40
-rw-r--r--libpathod/language/websockets.py10
-rw-r--r--test/test_language_base.py41
4 files changed, 65 insertions, 79 deletions
diff --git a/libpathod/language/base.py b/libpathod/language/base.py
index f6530d75..4e1900a7 100644
--- a/libpathod/language/base.py
+++ b/libpathod/language/base.py
@@ -11,6 +11,9 @@ from . import generators, exceptions
TRUNCATE = 1024
+Sep = pp.Optional(pp.Literal(":")).suppress()
+
+
v_integer = pp.Word(pp.nums)\
.setName("integer")\
.setParseAction(lambda toks: int(toks[0]))
@@ -318,28 +321,6 @@ class ShortcutUserAgent(_Header):
return ShortcutUserAgent(self.value.freeze(settings))
-class Body(_Component):
- def __init__(self, value):
- self.value = value
-
- @classmethod
- def expr(klass):
- e = pp.Literal("b").suppress()
- e = e + Value
- return e.setParseAction(lambda x: klass(*x))
-
- def values(self, settings):
- return [
- self.value.get_generator(settings),
- ]
-
- def spec(self):
- return "b%s"%(self.value.spec())
-
- def freeze(self, settings):
- return Body(self.value.freeze(settings))
-
-
class PathodSpec(_Token):
def __init__(self, value):
self.value = value
@@ -457,9 +438,9 @@ class OptionsOrValue(_Component):
return self.__class__(self.value.freeze(settings))
-class Code(_Component):
- def __init__(self, code):
- self.code = str(code)
+class Integer(_Component):
+ def __init__(self, value):
+ self.value = str(value)
@classmethod
def expr(klass):
@@ -467,22 +448,25 @@ class Code(_Component):
return e.setParseAction(lambda x: klass(*x))
def values(self, settings):
- return [generators.LiteralGenerator(self.code)]
+ return [generators.LiteralGenerator(self.value)]
def spec(self):
- return "%s"%(self.code)
+ return "%s"%(self.value)
def freeze(self, settings):
return self
-class Reason(_Component):
+class PreValue(_Component):
+ """
+ A value lead by self.preamble.
+ """
def __init__(self, value):
self.value = value
@classmethod
def expr(klass):
- e = pp.Literal("m").suppress()
+ e = pp.Literal(klass.preamble).suppress()
e = e + Value
return e.setParseAction(lambda x: klass(*x))
@@ -490,10 +474,10 @@ class Reason(_Component):
return [self.value.get_generator(settings)]
def spec(self):
- return "m%s"%(self.value.spec())
+ return "%s%s"%(self.preamble, self.value.spec())
def freeze(self, settings):
- return Reason(self.value.freeze(settings))
+ return self.__class__(self.value.freeze(settings))
class _Action(_Token):
@@ -634,10 +618,6 @@ class _Message(object):
return self.toks(_Action)
@property
- def body(self):
- return self.tok(Body)
-
- @property
def headers(self):
return self.toks(_Header)
@@ -695,6 +675,3 @@ class _Message(object):
def __repr__(self):
return self.spec()
-
-
-Sep = pp.Optional(pp.Literal(":")).suppress()
diff --git a/libpathod/language/http.py b/libpathod/language/http.py
index 7966b914..30a5fd9f 100644
--- a/libpathod/language/http.py
+++ b/libpathod/language/http.py
@@ -20,6 +20,18 @@ class Path(base.SimpleValue):
pass
+class Code(base.Integer):
+ pass
+
+
+class Reason(base.PreValue):
+ preamble = "m"
+
+
+class Body(base.PreValue):
+ preamble = "b"
+
+
class Method(base.OptionsOrValue):
options = [
"get",
@@ -47,10 +59,14 @@ def get_header(val, headers):
class _HTTPMessage(base._Message):
version = "HTTP/1.1"
+
@property
def raw(self):
return bool(self.tok(Raw))
+ @property
+ def body(self):
+ return self.tok(Body)
@abc.abstractmethod
def preamble(self, settings): # pragma: no cover
@@ -69,7 +85,7 @@ class _HTTPMessage(base._Message):
class Response(_HTTPMessage):
comps = (
- base.Body,
+ Body,
base.Header,
base.PauseAt,
base.DisconnectAt,
@@ -77,7 +93,7 @@ class Response(_HTTPMessage):
base.ShortcutContentType,
base.ShortcutLocation,
Raw,
- base.Reason
+ Reason
)
logattrs = ["code", "reason", "version", "body"]
@@ -87,16 +103,16 @@ class Response(_HTTPMessage):
@property
def code(self):
- return self.tok(base.Code)
+ return self.tok(Code)
@property
def reason(self):
- return self.tok(base.Reason)
+ return self.tok(Reason)
def preamble(self, settings):
l = [self.version, " "]
l.extend(self.code.values(settings))
- code = int(self.code.code)
+ code = int(self.code.value)
l.append(" ")
if self.reason:
l.extend(self.reason.values(settings))
@@ -121,7 +137,7 @@ class Response(_HTTPMessage):
if not self.code:
tokens.insert(
1,
- base.Code(101)
+ Code(101)
)
hdrs = netlib.websockets.server_handshake_headers(
settings.websocket_key
@@ -159,9 +175,9 @@ class Response(_HTTPMessage):
pp.MatchFirst(
[
WS.expr() + pp.Optional(
- base.Sep + base.Code.expr()
+ base.Sep + Code.expr()
),
- base.Code.expr(),
+ Code.expr(),
]
),
pp.ZeroOrMore(base.Sep + atom)
@@ -176,7 +192,7 @@ class Response(_HTTPMessage):
class Request(_HTTPMessage):
comps = (
- base.Body,
+ Body,
base.Header,
base.PauseAt,
base.DisconnectAt,
@@ -285,12 +301,12 @@ class PathodErrorResponse(Response):
def make_error_response(reason, body=None):
tokens = [
- base.Code("800"),
+ Code("800"),
base.Header(
base.ValueLiteral("Content-Type"),
base.ValueLiteral("text/plain")
),
- base.Reason(base.ValueLiteral(reason)),
- base.Body(base.ValueLiteral("pathod error: " + (body or reason))),
+ Reason(base.ValueLiteral(reason)),
+ Body(base.ValueLiteral("pathod error: " + (body or reason))),
]
return PathodErrorResponse(tokens)
diff --git a/libpathod/language/websockets.py b/libpathod/language/websockets.py
index 7ec4a2b1..b666b2fe 100644
--- a/libpathod/language/websockets.py
+++ b/libpathod/language/websockets.py
@@ -17,15 +17,23 @@ class WF(base.CaselessLiteral):
TOK = "wf"
+class Body(base.PreValue):
+ preamble = "b"
+
+
class WebsocketFrame(base._Message):
comps = (
- base.Body,
+ Body,
base.PauseAt,
base.DisconnectAt,
base.InjectAt
)
logattrs = ["body"]
+ @property
+ def body(self):
+ return self.tok(Body)
+
@classmethod
def expr(klass):
parts = [i.expr() for i in klass.comps]
diff --git a/test/test_language_base.py b/test/test_language_base.py
index 10f11d42..e4458021 100644
--- a/test/test_language_base.py
+++ b/test/test_language_base.py
@@ -183,24 +183,6 @@ class TestMisc:
s = v.spec()
assert s == v.expr().parseString(s)[0].spec()
- def test_body(self):
- e = base.Body.expr()
- v = e.parseString("b'foo'")[0]
- assert v.value.val == "foo"
-
- v = e.parseString("b@100")[0]
- assert str(v.value) == "@100"
- v2 = v.freeze({})
- v3 = v2.freeze({})
- assert v2.value.val == v3.value.val
-
- v = e.parseString("b@100g,digits", parseAll=True)[0]
- assert v.value.datatype == "digits"
- assert str(v.value) == "@100g,digits"
-
- s = v.spec()
- assert s == e.parseString(s)[0].spec()
-
def test_pathodspec(self):
e = base.PathodSpec.expr()
v = e.parseString("s'200'")[0]
@@ -227,16 +209,10 @@ class TestMisc:
assert e.freeze({})
assert e.values({})
- def test_code(self):
- e = base.Code.expr()
- v = e.parseString("200")[0]
- assert v.string() == "200"
- assert v.spec() == "200"
-
- assert v.freeze({}).code == v.code
-
- def test_reason(self):
- e = base.Reason.expr()
+ def test_value(self):
+ class TT(base.PreValue):
+ preamble = "m"
+ e = TT.expr()
v = e.parseString("m'msg'")[0]
assert v.value.val == "msg"
@@ -472,3 +448,12 @@ def test_options_or_value():
v2 = v.freeze({})
v3 = v2.freeze({})
assert v2.value.val == v3.value.val
+
+
+def test_integer():
+ e = base.Integer.expr()
+ v = e.parseString("200")[0]
+ assert v.string() == "200"
+ assert v.spec() == "200"
+
+ assert v.freeze({}).value == v.value