From 7cb7bcaae6a7b34a3806f3865f3178191cea9566 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20H=C3=B6rist?= <forenjunkie@chello.at> Date: Thu, 30 Mar 2017 03:33:51 +0200 Subject: [PATCH] Refactor IBB Handlers - Move handling of Data IQs into IBBIqHandler - Call SendHandler with file_props - Save last sent id in file_props.syn_id - Remove some useless checks, now that we call SendHandler with file_props - Send item-not-found error on invalid session id --- src/common/protocol/bytestream.py | 113 +++++++++++++----------------- 1 file changed, 49 insertions(+), 64 deletions(-) diff --git a/src/common/protocol/bytestream.py b/src/common/protocol/bytestream.py index c18ef7f24d..28528663cd 100644 --- a/src/common/protocol/bytestream.py +++ b/src/common/protocol/bytestream.py @@ -759,7 +759,6 @@ class ConnectionIBBytestream(ConnectionBytestream): def __init__(self): ConnectionBytestream.__init__(self) self._streams = {} - self.last_sent_ibb_id = None def IBBIqHandler(self, conn, stanza): """ @@ -767,12 +766,22 @@ class ConnectionIBBytestream(ConnectionBytestream): """ typ = stanza.getType() log.debug('IBBIqHandler called typ->%s' % typ) - if typ == 'set' and stanza.getTag('open', namespace=nbxmpp.NS_IBB): + if typ == 'set' and stanza.getTag('open'): self.StreamOpenHandler(conn, stanza) - elif typ == 'set' and stanza.getTag('close', namespace=nbxmpp.NS_IBB): + elif typ == 'set' and stanza.getTag('close'): self.StreamCloseHandler(conn, stanza) - elif typ == 'result': - self.SendHandler() + elif typ == 'set' and stanza.getTag('data'): + sid = stanza.getTagAttr('data', 'sid') + file_props = FilesProp.getFilePropByTransportSid(self.name, sid) + if not file_props: + conn.send(nbxmpp.Error(stanza, nbxmpp.ERR_ITEM_NOT_FOUND)) + elif file_props.connected and self.IBBMessageHandler(conn, + stanza): + reply = stanza.buildReply('result') + reply.delChild('data') + conn.send(reply) + elif not file_props.connected: + log.debug('Received IQ for closed filetransfer, IQ dropped') elif typ == 'error': gajim.socks5queue.error_cb() else: @@ -849,7 +858,7 @@ class ConnectionIBBytestream(ConnectionBytestream): base64 encoding that increases size of data by 1/3. """ file_props = FilesProp.getFilePropBySid(sid) - file_props.direction = '|>' + file_props.direction = '>' file_props.block_size = blocksize file_props.fp = fp file_props.seq = 0 @@ -868,50 +877,41 @@ class ConnectionIBBytestream(ConnectionBytestream): file_props.syn_id = syn.getID() return file_props - def SendHandler(self): + def SendHandler(self, file_props): """ Send next portion of data if it is time to do it. Used internally. """ log.debug('SendHandler called') - for file_props in FilesProp.getAllFileProp(): - if not file_props.direction: - # it's socks5 bytestream - continue - if file_props.completed: - self.CloseIBBStream(file_props) - sid = file_props.sid - if file_props.direction[:2] == '|>': - # We waitthat other part accept stream - continue - if file_props.direction[0] == '>': - if file_props.paused: - continue - if not file_props.connected: - #TODO: Reply with out of order error - continue - chunk = file_props.fp.read(file_props.block_size) - if chunk: - datanode = nbxmpp.Node(nbxmpp.NS_IBB + ' data', { - 'sid': file_props.transport_sid, - 'seq': file_props.seq}, base64.b64encode(chunk.encode( - 'utf-8')).decode('utf-8')) - file_props.seq += 1 - file_props.started = True - if file_props.seq == 65536: - file_props.seq = 0 - self.last_sent_ibb_id = self.connection.send( - nbxmpp.Protocol(name='iq', to=file_props.receiver, - typ='set', payload=[datanode])) - current_time = time.time() - file_props.elapsed_time += current_time - file_props.last_time - file_props.last_time = current_time - file_props.received_len += len(chunk) - if file_props.size == file_props.received_len: - file_props.completed = True - gajim.socks5queue.progress_transfer_cb(self.name, - file_props) - else: - log.debug('Nothing to read, but file not completed') + if file_props.completed: + self.CloseIBBStream(file_props) + if file_props.paused: + return + if not file_props.connected: + #TODO: Reply with out of order error + return + chunk = file_props.fp.read(file_props.block_size) + if chunk: + datanode = nbxmpp.Node(nbxmpp.NS_IBB + ' data', { + 'sid': file_props.transport_sid, + 'seq': file_props.seq}, + base64.b64encode(chunk).decode('ascii')) + file_props.seq += 1 + file_props.started = True + if file_props.seq == 65536: + file_props.seq = 0 + file_props.syn_id = self.connection.send( + nbxmpp.Protocol(name='iq', to=file_props.receiver, + typ='set', payload=[datanode])) + current_time = time.time() + file_props.elapsed_time += current_time - file_props.last_time + file_props.last_time = current_time + file_props.received_len += len(chunk) + if file_props.size == file_props.received_len: + file_props.completed = True + gajim.socks5queue.progress_transfer_cb(self.name, + file_props) + else: + log.debug('Nothing to read, but file not completed') def IBBMessageHandler(self, conn, stanza): """ @@ -980,6 +980,7 @@ class ConnectionIBBytestream(ConnectionBytestream): else: conn.send(nbxmpp.Error(stanza, nbxmpp.ERR_ITEM_NOT_FOUND)) + def IBBAllIqHandler(self, conn, stanza): """ Handle remote side reply about if it agree or not to receive our @@ -1001,25 +1002,9 @@ class ConnectionIBBytestream(ConnectionBytestream): else: conn.Event('IBB', 'ERROR ON SEND', file_props) elif stanza.getType() == 'result': - if file_props.direction[0] == '|': - file_props.direction = file_props.direction[1:] - self.SendHandler() - else: - conn.send(nbxmpp.Error(stanza, - nbxmpp.ERR_UNEXPECTED_REQUEST)) + self.SendHandler(file_props) break - else: - if stanza.getTag('data'): - sid = stanza.getTagAttr('data', 'sid') - file_props = FilesProp.getFilePropByTransportSid(self.name, sid) - if file_props.connected and self.IBBMessageHandler(conn, - stanza): - reply = stanza.buildReply('result') - reply.delChild('data') - conn.send(reply) - raise nbxmpp.NodeProcessed - elif syn_id == self.last_sent_ibb_id: - self.SendHandler() + class ConnectionSocks5BytestreamZeroconf(ConnectionSocks5Bytestream): -- GitLab