def SendChunked(self, data, compress=True, zhistory=None, just_buffer=False): if self.use_websocket: with self.lock: return self.Send([ ABNF.create_frame(''.join(data), ABNF.OPCODE_BINARY, 1, self.ws_zero_mask).format() ], activity=False, try_flush=(not just_buffer), just_buffer=just_buffer) rst = '' if self.zreset: self.zreset = False rst = 'R' # Stop compressing streams that just get bigger. if zhistory and (zhistory[0] < zhistory[1]): compress = False with self.lock: try: sdata = ''.join(data) if self.zw and compress and len(sdata) > 64: try: zdata = s( self.zw.compress(b(sdata)) + self.zw.flush(zlib.Z_SYNC_FLUSH)) if zhistory: zhistory[0] = len(sdata) zhistory[1] = len(zdata) return self.Send([ '%xZ%x%s\r\n' % (len(sdata), len(zdata), rst), zdata ], activity=False, try_flush=(not just_buffer), just_buffer=just_buffer) except zlib.error: logging.LogError( 'Error compressing, resetting ZChunks.') self.ResetZChunks() return self.Send(['%x%s\r\n' % (len(sdata), rst), sdata], activity=False, try_flush=(not just_buffer), just_buffer=just_buffer) except UnicodeDecodeError: logging.LogError('UnicodeDecodeError in SendChunked, wtf?') return False
def ProcessWebsocketData(self, data): loops = 150 happy = more = True while happy and more and (loops > 0): loops -= 1 if self.peeking: self.header = '' self.chunk = '' self.header += (data or '') try: ws_frame, data = ABNF.parse(self.header) more = data and (len(data) > 0) except ValueError as err: self.LogError('ChunkParser::ProcessData: %s' % err) self.Log([('bad_data', data)]) return False if ws_frame and ws_frame.length == len(ws_frame.data): # We have a complete frame, process it! self.header = '' happy = self.ProcessChunk( ws_frame.data) if ws_frame.data else True else: if self.read_eof: return self.ProcessEofRead() # Frame is incomplete, but there were no errors: we're done for now. return True if happy and more: self.LogError('Unprocessed data: %s' % data) raise BugFoundError('Too much data') elif self.read_eof: return self.ProcessEofRead() and happy else: return happy return False # Not reached