aboutsummaryrefslogtreecommitdiffstats
path: root/libpathod/language
diff options
context:
space:
mode:
Diffstat (limited to 'libpathod/language')
-rw-r--r--libpathod/language/__init__.py14
-rw-r--r--libpathod/language/http.py6
-rw-r--r--libpathod/language/http2.py113
3 files changed, 113 insertions, 20 deletions
diff --git a/libpathod/language/__init__.py b/libpathod/language/__init__.py
index ae9a8c76..10050bf8 100644
--- a/libpathod/language/__init__.py
+++ b/libpathod/language/__init__.py
@@ -19,7 +19,7 @@ def expand(msg):
yield msg
-def parse_pathod(s):
+def parse_pathod(s, use_http2=False):
"""
May raise ParseException
"""
@@ -28,12 +28,17 @@ def parse_pathod(s):
except UnicodeError:
raise exceptions.ParseException("Spec must be valid ASCII.", 0, 0)
try:
- reqs = pp.Or(
- [
+ if use_http2:
+ expressions = [
+ # http2.Frame.expr(),
+ http2.Response.expr(),
+ ]
+ else:
+ expressions = [
websockets.WebsocketFrame.expr(),
http.Response.expr(),
]
- ).parseString(s, parseAll=True)
+ reqs = pp.Or(expressions).parseString(s, parseAll=True)
except pp.ParseException as v:
raise exceptions.ParseException(v.msg, v.line, v.col)
return itertools.chain(*[expand(i) for i in reqs])
@@ -55,7 +60,6 @@ def parse_pathoc(s, use_http2=False):
websockets.WebsocketClientFrame.expr(),
http.Request.expr(),
]
-
reqs = pp.OneOrMore(pp.Or(expressions)).parseString(s, parseAll=True)
except pp.ParseException as v:
raise exceptions.ParseException(v.msg, v.line, v.col)
diff --git a/libpathod/language/http.py b/libpathod/language/http.py
index 9a8404f0..115f8069 100644
--- a/libpathod/language/http.py
+++ b/libpathod/language/http.py
@@ -367,10 +367,6 @@ class Request(_HTTPMessage):
return ":".join([i.spec() for i in self.tokens])
-class PathodErrorResponse(Response):
- pass
-
-
def make_error_response(reason, body=None):
tokens = [
Code("800"),
@@ -381,4 +377,4 @@ def make_error_response(reason, body=None):
Reason(base.TokValueLiteral(reason)),
Body(base.TokValueLiteral("pathod error: " + (body or reason))),
]
- return PathodErrorResponse(tokens)
+ return Response(tokens)
diff --git a/libpathod/language/http2.py b/libpathod/language/http2.py
index 4a5b9084..1d2517d3 100644
--- a/libpathod/language/http2.py
+++ b/libpathod/language/http2.py
@@ -45,14 +45,20 @@ class Body(base.Value):
class Times(base.Integer):
preamble = "x"
+class Code(base.Integer):
+ pass
class Request(message.Message):
comps = (
Header,
Body,
-
Times,
)
+ logattrs = ["method", "path"]
+
+ def __init__(self, tokens):
+ super(Response, self).__init__(tokens)
+ self.rendered_values = None
@property
def method(self):
@@ -87,7 +93,6 @@ class Request(message.Message):
Method.expr(),
base.Sep,
Path.expr(),
- base.Sep,
pp.ZeroOrMore(base.Sep + atom)
]
)
@@ -95,21 +100,109 @@ class Request(message.Message):
return resp
def resolve(self, settings, msg=None):
- tokens = self.tokens[:]
- return self.__class__(
- [i.resolve(settings, self) for i in tokens]
+ return self
+
+ def values(self, settings):
+ if self.rendered_values:
+ return self.rendered_values
+ else:
+ headers = self.headers
+ if headers:
+ headers = headers.values(settings)
+
+ body = self.body
+ if body:
+ body = body.string()
+
+ self.rendered_values = settings.protocol.create_request(
+ self.method.string(),
+ self.path.string(),
+ headers, # TODO: parse that into a dict?!
+ body)
+ return self.rendered_values
+
+ def spec(self):
+ return ":".join([i.spec() for i in self.tokens])
+
+
+class Response(message.Message):
+ unique_name = None
+ comps = (
+ Header,
+ Body,
+ )
+
+ def __init__(self, tokens):
+ super(Response, self).__init__(tokens)
+ self.rendered_values = None
+ self.stream_id = 0
+
+ @property
+ def code(self):
+ return self.tok(Code)
+
+ @property
+ def headers(self):
+ return self.toks(Header)
+
+ @property
+ def body(self):
+ return self.tok(Body)
+
+ @property
+ def actions(self):
+ return []
+
+ def resolve(self, settings, msg=None):
+ return self
+
+ @classmethod
+ def expr(klass):
+ parts = [i.expr() for i in klass.comps]
+ atom = pp.MatchFirst(parts)
+ resp = pp.And(
+ [
+ Code.expr(),
+ pp.ZeroOrMore(base.Sep + atom)
+ ]
)
+ resp = resp.setParseAction(klass)
+ return resp
def values(self, settings):
- return settings.protocol.create_request(
- self.method.string(),
- self.path,
- self.headers,
- self.body)
+ if self.rendered_values:
+ return self.rendered_values
+ else:
+ headers = self.headers
+ if headers:
+ headers = headers.values(settings)
+
+ body = self.body
+ if body:
+ body = body.values(settings)
+
+ self.rendered_values = settings.protocol.create_response(
+ self.code.string(),
+ self.stream_id,
+ headers, # TODO: parse that into a dict?!
+ body)
+ return self.rendered_values
def spec(self):
return ":".join([i.spec() for i in self.tokens])
+def make_error_response(reason, body=None):
+ raise NotImplementedError
+ # tokens = [
+ # Code("800"),
+ # Header(
+ # base.TokValueLiteral("Content-Type"),
+ # base.TokValueLiteral("text/plain")
+ # ),
+ # Reason(base.TokValueLiteral(reason)),
+ # Body(base.TokValueLiteral("pathod error: " + (body or reason))),
+ # ]
+ # return Response(tokens)
# class Frame(message.Message):
# pass