@@ -247,6 +247,46 @@ def _process_CLOSE_payload(self, data):
247
247
CloseReason .INVALID_FRAME_PAYLOAD_DATA )
248
248
return (code , reason )
249
249
250
+ def _parse_frame_payload (self ,
251
+ opcode ,
252
+ remaining ,
253
+ message_decoder ,
254
+ masker ,
255
+ fin_flag ):
256
+ frame_finished = False
257
+ message_finished = False
258
+ while not frame_finished :
259
+ # For control frames, we collect all the data and return it as
260
+ # a single lump. For message frames, we stream out chunks as
261
+ # they arrive, to minimize buffering.
262
+ if opcode .iscontrol ():
263
+ data = yield from self ._consume_exactly (remaining )
264
+ else :
265
+ data = yield from self ._consume_at_most (remaining )
266
+ remaining -= len (data )
267
+ frame_finished = (remaining == 0 )
268
+ message_finished = (frame_finished and fin_flag )
269
+
270
+ data = self ._process_payload_chunk (masker , data )
271
+ if frame_finished :
272
+ data += self ._process_payload_complete (fin_flag )
273
+
274
+ if opcode is Opcode .CLOSE :
275
+ data = self ._process_CLOSE_payload (data )
276
+
277
+ if not opcode .iscontrol ():
278
+ if message_decoder is not None :
279
+ try :
280
+ data = message_decoder .decode (data , message_finished )
281
+ except UnicodeDecodeError as exc :
282
+ raise ParseFailed (
283
+ str (exc ),
284
+ CloseReason .INVALID_FRAME_PAYLOAD_DATA )
285
+
286
+ yield Frame (opcode , data , frame_finished , message_finished )
287
+
288
+ return message_finished
289
+
250
290
def parse_more_gen (self ):
251
291
# Consume as much as we can from self._buffer, yielding events, and
252
292
# then yield None when we need more data. Or raise ParseFailed.
@@ -257,7 +297,8 @@ def parse_more_gen(self):
257
297
258
298
unfinished_message_opcode = None
259
299
unfinished_message_decoder = None
260
- while True :
300
+ effective_opcode = None
301
+ while effective_opcode is not Opcode .CLOSE :
261
302
header = yield from self ._parse_header ()
262
303
263
304
if unfinished_message_opcode is None :
@@ -286,47 +327,19 @@ def parse_more_gen(self):
286
327
unfinished_message_decoder is None :
287
328
unfinished_message_decoder = getincrementaldecoder ("utf-8" )()
288
329
289
- remaining = header .payload_len
290
- frame_finished = False
291
- while not frame_finished :
292
- # For control frames, we collect all the data and return it as
293
- # a single lump. For message frames, we stream out chunks as
294
- # they arrive, to minimize buffering.
295
- if effective_opcode .iscontrol ():
296
- data = yield from self ._consume_exactly (remaining )
297
- else :
298
- data = yield from self ._consume_at_most (remaining )
299
- remaining -= len (data )
300
- frame_finished = (remaining == 0 )
301
- message_finished = (frame_finished and header .fin )
302
-
303
- data = self ._process_payload_chunk (masker , data )
304
- if frame_finished :
305
- data += self ._process_payload_complete (header .fin )
306
-
307
- if effective_opcode is Opcode .CLOSE :
308
- data = self ._process_CLOSE_payload (data )
309
-
310
- if not effective_opcode .iscontrol ():
311
- if unfinished_message_decoder is not None :
312
- try :
313
- data = unfinished_message_decoder .decode (
314
- data , message_finished )
315
- except UnicodeDecodeError as exc :
316
- raise ParseFailed (
317
- str (exc ),
318
- CloseReason .INVALID_FRAME_PAYLOAD_DATA )
319
- # This isn't a control, so if this message is finished
320
- # then the unfinished message is also finished.
321
- if message_finished :
322
- unfinished_message_opcode = None
323
- unfinished_message_decoder = None
324
-
325
- yield Frame (
326
- effective_opcode , data , frame_finished , message_finished )
327
-
328
- if effective_opcode is Opcode .CLOSE :
329
- break
330
+ message_finished = yield from self ._parse_frame_payload (
331
+ opcode = effective_opcode ,
332
+ remaining = header .payload_len ,
333
+ message_decoder = unfinished_message_decoder ,
334
+ masker = masker ,
335
+ fin_flag = header .fin
336
+ )
337
+
338
+ if message_finished and not effective_opcode .iscontrol ():
339
+ # This isn't a control, so if this message is finished
340
+ # then the unfinished message is also finished.
341
+ unfinished_message_opcode = None
342
+ unfinished_message_decoder = None
330
343
331
344
def receive_bytes (self , data ):
332
345
self ._buffer += data
0 commit comments