Beispiel #1
0
 def parse_ws_frame(self, buf):
     if not buf:
         self._read_queue_put(buf)
         return
     if self.ws_data:
         ws_data = self.ws_data+buf
         self.ws_data = b""
     else:
         ws_data = buf
     log("parse_ws_frame(%i bytes) total buffer is %i bytes", len(buf), len(ws_data))
     while ws_data and not self._closed:
         parsed = decode_hybi(ws_data)
         if parsed is None:
             log("parse_ws_frame(%i bytes) not enough data", len(ws_data))
             #not enough data to get a full websocket frame,
             #save it for later:
             self.ws_data = ws_data
             return
         opcode, payload, processed, fin = parsed
         ws_data = ws_data[processed:]
         log("parse_ws_frame(%i bytes) payload=%i bytes, processed=%i, remaining=%i, opcode=%s, fin=%s",
             len(buf), len(payload), processed, len(ws_data), OPCODES.get(opcode, opcode), fin)
         if opcode==OPCODE_CONTINUE:
             assert self.ws_payload_opcode and self.ws_payload, "continuation frame does not follow a partial frame"
             self.ws_payload.append(payload)
             if not fin:
                 #wait for more
                 continue
             #join all the frames and process the payload:
             full_payload = b"".join(memoryview_to_bytes(v) for v in self.ws_payload)
             self.ws_payload = []
             opcode = self.ws_payload_opcode
             self.ws_payload_opcode = 0
         else:
             if self.ws_payload and self.ws_payload_opcode:
                 raise Exception("expected a continuation frame not %s" % OPCODES.get(opcode, opcode))
             full_payload = payload
             if not fin:
                 if opcode not in (OPCODE_BINARY, OPCODE_TEXT):
                     raise Exception("cannot handle fragmented '%s' frames" % OPCODES.get(opcode, opcode))
                 #fragmented, keep this payload for later
                 self.ws_payload_opcode = opcode
                 self.ws_payload.append(payload)
                 continue
         if opcode==OPCODE_BINARY:
             self._read_queue_put(full_payload)
         elif opcode==OPCODE_TEXT:
             if first_time("ws-text-frame-from-%s" % self._conn):
                 log.warn("Warning: handling text websocket frame as binary")
             self._read_queue_put(full_payload)
         elif opcode==OPCODE_CLOSE:
             self._process_ws_close(full_payload)
         elif opcode==OPCODE_PING:
             self._process_ws_ping(full_payload)
         elif opcode==OPCODE_PONG:
             self._process_ws_pong(full_payload)
         else:
             log.warn("Warning unhandled websocket opcode '%s'", OPCODES.get(opcode, "%#x" % opcode))
             log("payload=%r", payload)
 def rt(opcode, payload, has_mask=False, fin=True):
     h = encode_hybi_header(opcode, len(payload), has_mask, fin)
     packet = h + payload
     ropcode, rpayload, rlen, rfin = decode_hybi(packet)
     assert opcode == ropcode
     assert rpayload == payload
     assert rlen > len(payload)
     assert fin == rfin
 def test_invalid_decode(self):
     for l in (0, 10, 125, 126, 65535, 65536):
         for has_mask in (True, False):
             payload = b"\0" * l
             h = encode_hybi_header(0, len(payload), has_mask, True)
             if has_mask:
                 packet = h + b"9" * 4 + payload
             else:
                 packet = h + payload
             v = decode_hybi(packet)
             assert v
             v = decode_hybi(packet[:-1])
             assert v is None
             v = decode_hybi(packet[:int(has_mask) * 4])
             assert v is None, "got %s" % (v, )
             if l > 0:
                 for i in range(5):
                     v = decode_hybi(packet[:int(has_mask) * 4 + i])
                     assert v is None, "got %s" % (v, )