diff options
-rw-r--r-- | libpathod/language/__init__.py | 7 | ||||
-rw-r--r-- | libpathod/language/websockets.py | 1 | ||||
-rw-r--r-- | libpathod/pathod.py | 35 | ||||
-rw-r--r-- | test/test_language_websocket.py | 10 |
4 files changed, 34 insertions, 19 deletions
diff --git a/libpathod/language/__init__.py b/libpathod/language/__init__.py index 38395b86..c41e8602 100644 --- a/libpathod/language/__init__.py +++ b/libpathod/language/__init__.py @@ -63,12 +63,15 @@ def parse_websocket_frame(s): May raise ParseException """ try: - return websockets.WebsocketFrame.expr().parseString( + reqs = pp.OneOrMore( + websockets.WebsocketFrame.expr() + ).parseString( s, parseAll = True - )[0] + ) except pp.ParseException as v: raise exceptions.ParseException(v.msg, v.line, v.col) + return itertools.chain(*[expand(i) for i in reqs]) def serve(msg, fp, settings): diff --git a/libpathod/language/websockets.py b/libpathod/language/websockets.py index a42dfc2f..51c1b3ee 100644 --- a/libpathod/language/websockets.py +++ b/libpathod/language/websockets.py @@ -69,6 +69,7 @@ class Length(base.Integer): class Times(base.Integer): preamble = "x" + COMPONENTS = ( OpCode, Length, diff --git a/libpathod/pathod.py b/libpathod/pathod.py index a5e6b8fa..991d3ae8 100644 --- a/libpathod/pathod.py +++ b/libpathod/pathod.py @@ -131,21 +131,22 @@ class PathodHandler(tcp.BaseHandler): if frm.payload.startswith(ld): nest = frm.payload[len(ld):] try: - wf = language.parse_websocket_frame(nest) + wf_gen = language.parse_websocket_frame(nest) except language.exceptions.ParseException, v: lg( "Parse error in reflected frame specifcation:" " %s" % v.msg ) break - with log.Log(self.logfp, self.server.hexdump, lr, lw) as lg: - frame_log = language.serve( - wf, - self.wfile, - self.settings - ) - lg("crafting websocket spec: %s" % frame_log["spec"]) - self.addlog(frame_log) + for frm in wf_gen: + with log.Log(self.logfp, self.server.hexdump, lr, lw) as lg: + frame_log = language.serve( + frm, + self.wfile, + self.settings + ) + lg("crafting websocket spec: %s" % frame_log["spec"]) + self.addlog(frame_log) return self.handle_websocket, None def handle_http_connect(self, connect, lg): @@ -280,32 +281,32 @@ class PathodHandler(tcp.BaseHandler): # If this is a websocket initiation, we respond with a proper # server response, unless over-ridden. if websocket_key: - anchor_spec = language.parse_pathod("ws") + anchor_gen = language.parse_pathod("ws") else: - anchor_spec = None + anchor_gen = None for i in self.server.anchors: if i[0].match(path): - anchor_spec = i[1] + anchor_gen = i[1] break else: if m(self.server.craftanchor.match(path)): spec = urllib.unquote(path)[len(m.v.group()):] if spec: try: - anchor_spec = language.parse_pathod(spec) + anchor_gen = language.parse_pathod(spec) except language.ParseException as v: lg("Parse error: %s" % v.msg) - anchor_spec = iter([language.http.make_error_response( + anchor_gen = iter([language.http.make_error_response( "Parse Error", "Error parsing response spec: %s\n" % ( v.msg + v.marked() ) )]) - if anchor_spec: - lg("crafting spec: %s" % anchor_spec) + if anchor_gen: + lg("crafting spec: %s" % anchor_gen) nexthandler, retlog["response"] = self.http_serve_crafted( - anchor_spec.next() + anchor_gen.next() ) if nexthandler and websocket_key: return self.handle_websocket, retlog diff --git a/test/test_language_websocket.py b/test/test_language_websocket.py index e7f333b4..107f3427 100644 --- a/test/test_language_websocket.py +++ b/test/test_language_websocket.py @@ -36,9 +36,19 @@ class TestWebsocketFrame: "wf:fin:rsv1:rsv2:rsv3:mask", "wf:-fin:-rsv1:-rsv2:-rsv3:-mask", "wf:k@4", + "wf:x10", ] self._test_messages(specs, websockets.WebsocketFrame) + def test_parse_websocket_frames(self): + wf = language.parse_websocket_frame("wf:x10") + assert len(list(wf)) == 10 + tutils.raises( + language.ParseException, + language.parse_websocket_frame, + "wf:x" + ) + def test_client_values(self): specs = [ "wf:f'wf'", |