Convert parse_websocket_frame to a generator

This commit is contained in:
Aldo Cortesi 2015-06-08 10:58:12 +12:00
parent df962f8e7b
commit 7dff8f0dca
4 changed files with 34 additions and 19 deletions

View File

@ -63,12 +63,15 @@ def parse_websocket_frame(s):
May raise ParseException May raise ParseException
""" """
try: try:
return websockets.WebsocketFrame.expr().parseString( reqs = pp.OneOrMore(
websockets.WebsocketFrame.expr()
).parseString(
s, s,
parseAll = True parseAll = True
)[0] )
except pp.ParseException as v: except pp.ParseException as v:
raise exceptions.ParseException(v.msg, v.line, v.col) raise exceptions.ParseException(v.msg, v.line, v.col)
return itertools.chain(*[expand(i) for i in reqs])
def serve(msg, fp, settings): def serve(msg, fp, settings):

View File

@ -69,6 +69,7 @@ class Length(base.Integer):
class Times(base.Integer): class Times(base.Integer):
preamble = "x" preamble = "x"
COMPONENTS = ( COMPONENTS = (
OpCode, OpCode,
Length, Length,

View File

@ -131,21 +131,22 @@ class PathodHandler(tcp.BaseHandler):
if frm.payload.startswith(ld): if frm.payload.startswith(ld):
nest = frm.payload[len(ld):] nest = frm.payload[len(ld):]
try: try:
wf = language.parse_websocket_frame(nest) wf_gen = language.parse_websocket_frame(nest)
except language.exceptions.ParseException, v: except language.exceptions.ParseException, v:
lg( lg(
"Parse error in reflected frame specifcation:" "Parse error in reflected frame specifcation:"
" %s" % v.msg " %s" % v.msg
) )
break break
with log.Log(self.logfp, self.server.hexdump, lr, lw) as lg: for frm in wf_gen:
frame_log = language.serve( with log.Log(self.logfp, self.server.hexdump, lr, lw) as lg:
wf, frame_log = language.serve(
self.wfile, frm,
self.settings self.wfile,
) self.settings
lg("crafting websocket spec: %s" % frame_log["spec"]) )
self.addlog(frame_log) lg("crafting websocket spec: %s" % frame_log["spec"])
self.addlog(frame_log)
return self.handle_websocket, None return self.handle_websocket, None
def handle_http_connect(self, connect, lg): 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 # If this is a websocket initiation, we respond with a proper
# server response, unless over-ridden. # server response, unless over-ridden.
if websocket_key: if websocket_key:
anchor_spec = language.parse_pathod("ws") anchor_gen = language.parse_pathod("ws")
else: else:
anchor_spec = None anchor_gen = None
for i in self.server.anchors: for i in self.server.anchors:
if i[0].match(path): if i[0].match(path):
anchor_spec = i[1] anchor_gen = i[1]
break break
else: else:
if m(self.server.craftanchor.match(path)): if m(self.server.craftanchor.match(path)):
spec = urllib.unquote(path)[len(m.v.group()):] spec = urllib.unquote(path)[len(m.v.group()):]
if spec: if spec:
try: try:
anchor_spec = language.parse_pathod(spec) anchor_gen = language.parse_pathod(spec)
except language.ParseException as v: except language.ParseException as v:
lg("Parse error: %s" % v.msg) lg("Parse error: %s" % v.msg)
anchor_spec = iter([language.http.make_error_response( anchor_gen = iter([language.http.make_error_response(
"Parse Error", "Parse Error",
"Error parsing response spec: %s\n" % ( "Error parsing response spec: %s\n" % (
v.msg + v.marked() v.msg + v.marked()
) )
)]) )])
if anchor_spec: if anchor_gen:
lg("crafting spec: %s" % anchor_spec) lg("crafting spec: %s" % anchor_gen)
nexthandler, retlog["response"] = self.http_serve_crafted( nexthandler, retlog["response"] = self.http_serve_crafted(
anchor_spec.next() anchor_gen.next()
) )
if nexthandler and websocket_key: if nexthandler and websocket_key:
return self.handle_websocket, retlog return self.handle_websocket, retlog

View File

@ -36,9 +36,19 @@ class TestWebsocketFrame:
"wf:fin:rsv1:rsv2:rsv3:mask", "wf:fin:rsv1:rsv2:rsv3:mask",
"wf:-fin:-rsv1:-rsv2:-rsv3:-mask", "wf:-fin:-rsv1:-rsv2:-rsv3:-mask",
"wf:k@4", "wf:k@4",
"wf:x10",
] ]
self._test_messages(specs, websockets.WebsocketFrame) 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): def test_client_values(self):
specs = [ specs = [
"wf:f'wf'", "wf:f'wf'",