Merge branch 'fixibb' into 'master'
Fix IBB Closes #8196 See merge request !90
This commit is contained in:
commit
b94c827400
|
@ -380,7 +380,7 @@ class Config:
|
||||||
'http_auth': [opt_str, 'ask'], # yes, no, ask
|
'http_auth': [opt_str, 'ask'], # yes, no, ask
|
||||||
'dont_ack_subscription': [opt_bool, False, _('Jabberd2 workaround')],
|
'dont_ack_subscription': [opt_bool, False, _('Jabberd2 workaround')],
|
||||||
# proxy65 for FT
|
# proxy65 for FT
|
||||||
'file_transfer_proxies': [opt_str, 'proxy.eu.jabber.org, proxy.jabber.ru, proxy.jabbim.cz'],
|
'file_transfer_proxies': [opt_str, ''],
|
||||||
'use_ft_proxies': [opt_bool, False, _('If checked, Gajim will use your IP and proxies defined in file_transfer_proxies option for file transfer.'), True],
|
'use_ft_proxies': [opt_bool, False, _('If checked, Gajim will use your IP and proxies defined in file_transfer_proxies option for file transfer.'), True],
|
||||||
'test_ft_proxies_on_startup': [opt_bool, False, _('If True, Gajim will test file transfer proxies on startup to be sure it works. Openfire\'s proxies are known to fail this test even if they work.')],
|
'test_ft_proxies_on_startup': [opt_bool, False, _('If True, Gajim will test file transfer proxies on startup to be sure it works. Openfire\'s proxies are known to fail this test even if they work.')],
|
||||||
'msgwin-x-position': [opt_int, -1], # Default is to let the wm decide
|
'msgwin-x-position': [opt_int, -1], # Default is to let the wm decide
|
||||||
|
|
|
@ -163,7 +163,7 @@ class FileStoppedEvent(FileRequestEvent):
|
||||||
type_ = 'file-stopped'
|
type_ = 'file-stopped'
|
||||||
|
|
||||||
class FileHashErrorEvent(FileRequestEvent):
|
class FileHashErrorEvent(FileRequestEvent):
|
||||||
type_ = 'file-hash-rror'
|
type_ = 'file-hash-error'
|
||||||
|
|
||||||
class JingleIncomingEvent(Event):
|
class JingleIncomingEvent(Event):
|
||||||
type_ = 'jingle-incoming'
|
type_ = 'jingle-incoming'
|
||||||
|
|
|
@ -146,7 +146,7 @@ class StateTransfering(JingleFileTransferStates):
|
||||||
|
|
||||||
def _start_ibb_transfer(self, con):
|
def _start_ibb_transfer(self, con):
|
||||||
self.jft.file_props.transport_sid = self.jft.transport.sid
|
self.jft.file_props.transport_sid = self.jft.transport.sid
|
||||||
fp = open(self.jft.file_props.file_name, 'r')
|
fp = open(self.jft.file_props.file_name, 'rb')
|
||||||
con.OpenStream(self.jft.file_props.sid, self.jft.session.peerjid, fp,
|
con.OpenStream(self.jft.file_props.sid, self.jft.session.peerjid, fp,
|
||||||
blocksize=4096)
|
blocksize=4096)
|
||||||
|
|
||||||
|
|
|
@ -251,7 +251,7 @@ class ConnectionBytestream:
|
||||||
if field.getValue() == nbxmpp.NS_IBB:
|
if field.getValue() == nbxmpp.NS_IBB:
|
||||||
sid = file_props.sid
|
sid = file_props.sid
|
||||||
file_props.transport_sid = sid
|
file_props.transport_sid = sid
|
||||||
fp = open(file_props.file_name, 'r')
|
fp = open(file_props.file_name, 'rb')
|
||||||
self.OpenStream(sid, file_props.receiver, fp)
|
self.OpenStream(sid, file_props.receiver, fp)
|
||||||
raise nbxmpp.NodeProcessed
|
raise nbxmpp.NodeProcessed
|
||||||
|
|
||||||
|
@ -759,7 +759,6 @@ class ConnectionIBBytestream(ConnectionBytestream):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
ConnectionBytestream.__init__(self)
|
ConnectionBytestream.__init__(self)
|
||||||
self._streams = {}
|
self._streams = {}
|
||||||
self.last_sent_ibb_id = None
|
|
||||||
|
|
||||||
def IBBIqHandler(self, conn, stanza):
|
def IBBIqHandler(self, conn, stanza):
|
||||||
"""
|
"""
|
||||||
|
@ -767,12 +766,22 @@ class ConnectionIBBytestream(ConnectionBytestream):
|
||||||
"""
|
"""
|
||||||
typ = stanza.getType()
|
typ = stanza.getType()
|
||||||
log.debug('IBBIqHandler called typ->%s' % typ)
|
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)
|
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)
|
self.StreamCloseHandler(conn, stanza)
|
||||||
elif typ == 'result':
|
elif typ == 'set' and stanza.getTag('data'):
|
||||||
self.SendHandler()
|
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':
|
elif typ == 'error':
|
||||||
gajim.socks5queue.error_cb()
|
gajim.socks5queue.error_cb()
|
||||||
else:
|
else:
|
||||||
|
@ -815,18 +824,23 @@ class ConnectionIBBytestream(ConnectionBytestream):
|
||||||
file_props.disconnect_cb = None
|
file_props.disconnect_cb = None
|
||||||
file_props.continue_cb = None
|
file_props.continue_cb = None
|
||||||
file_props.syn_id = stanza.getID()
|
file_props.syn_id = stanza.getID()
|
||||||
file_props.fp = open(file_props.file_name, 'w')
|
file_props.fp = open(file_props.file_name, 'wb')
|
||||||
conn.send(rep)
|
conn.send(rep)
|
||||||
|
|
||||||
def CloseIBBStream(self, file_props):
|
def CloseIBBStream(self, file_props):
|
||||||
file_props.connected = False
|
file_props.connected = False
|
||||||
file_props.fp.close()
|
file_props.fp.close()
|
||||||
file_props.stopped = True
|
file_props.stopped = True
|
||||||
self.connection.send(nbxmpp.Protocol('iq',
|
to = file_props.receiver
|
||||||
file_props.direction[1:], 'set',
|
if file_props.direction == '<':
|
||||||
|
to = file_props.sender
|
||||||
|
self.connection.send(
|
||||||
|
nbxmpp.Protocol('iq', to, 'set',
|
||||||
payload=[nbxmpp.Node(nbxmpp.NS_IBB + ' close',
|
payload=[nbxmpp.Node(nbxmpp.NS_IBB + ' close',
|
||||||
{'sid':file_props.sid})]))
|
{'sid':file_props.transport_sid})]))
|
||||||
if file_props.session_type == 'jingle':
|
if file_props.completed:
|
||||||
|
gajim.socks5queue.complete_transfer_cb(self.name, file_props)
|
||||||
|
elif file_props.session_type == 'jingle':
|
||||||
peerjid = \
|
peerjid = \
|
||||||
file_props.receiver if file_props.type_ == 's' else file_props.sender
|
file_props.receiver if file_props.type_ == 's' else file_props.sender
|
||||||
session = self.get_jingle_session(peerjid, file_props.sid, 'file')
|
session = self.get_jingle_session(peerjid, file_props.sid, 'file')
|
||||||
|
@ -844,7 +858,7 @@ class ConnectionIBBytestream(ConnectionBytestream):
|
||||||
base64 encoding that increases size of data by 1/3.
|
base64 encoding that increases size of data by 1/3.
|
||||||
"""
|
"""
|
||||||
file_props = FilesProp.getFilePropBySid(sid)
|
file_props = FilesProp.getFilePropBySid(sid)
|
||||||
file_props.direction = '|>' + to
|
file_props.direction = '>'
|
||||||
file_props.block_size = blocksize
|
file_props.block_size = blocksize
|
||||||
file_props.fp = fp
|
file_props.fp = fp
|
||||||
file_props.seq = 0
|
file_props.seq = 0
|
||||||
|
@ -863,53 +877,41 @@ class ConnectionIBBytestream(ConnectionBytestream):
|
||||||
file_props.syn_id = syn.getID()
|
file_props.syn_id = syn.getID()
|
||||||
return file_props
|
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.
|
Send next portion of data if it is time to do it. Used internally.
|
||||||
"""
|
"""
|
||||||
log.debug('SendHandler called')
|
log.debug('SendHandler called')
|
||||||
for file_props in FilesProp.getAllFileProp():
|
if file_props.completed:
|
||||||
if not file_props.direction:
|
self.CloseIBBStream(file_props)
|
||||||
# it's socks5 bytestream
|
if file_props.paused:
|
||||||
continue
|
return
|
||||||
sid = file_props.sid
|
if not file_props.connected:
|
||||||
if file_props.direction[:2] == '|>':
|
#TODO: Reply with out of order error
|
||||||
# We waitthat other part accept stream
|
return
|
||||||
continue
|
chunk = file_props.fp.read(file_props.block_size)
|
||||||
if file_props.direction[0] == '>':
|
if chunk:
|
||||||
if file_props.paused:
|
datanode = nbxmpp.Node(nbxmpp.NS_IBB + ' data', {
|
||||||
continue
|
'sid': file_props.transport_sid,
|
||||||
if not file_props.connected:
|
'seq': file_props.seq},
|
||||||
#TODO: Reply with out of order error
|
base64.b64encode(chunk).decode('ascii'))
|
||||||
continue
|
file_props.seq += 1
|
||||||
chunk = file_props.fp.read(file_props.block_size)
|
file_props.started = True
|
||||||
if chunk:
|
if file_props.seq == 65536:
|
||||||
datanode = nbxmpp.Node(nbxmpp.NS_IBB + ' data', {
|
file_props.seq = 0
|
||||||
'sid': file_props.transport_sid,
|
file_props.syn_id = self.connection.send(
|
||||||
'seq': file_props.seq}, base64.b64encode(chunk.encode(
|
nbxmpp.Protocol(name='iq', to=file_props.receiver,
|
||||||
'utf-8')).decode('utf-8'))
|
typ='set', payload=[datanode]))
|
||||||
file_props.seq += 1
|
current_time = time.time()
|
||||||
file_props.started = True
|
file_props.elapsed_time += current_time - file_props.last_time
|
||||||
if file_props.seq == 65536:
|
file_props.last_time = current_time
|
||||||
file_props.seq = 0
|
file_props.received_len += len(chunk)
|
||||||
self.last_sent_ibb_id = self.connection.send(
|
if file_props.size == file_props.received_len:
|
||||||
nbxmpp.Protocol(name='iq', to=file_props.direction[1:],
|
file_props.completed = True
|
||||||
typ='set', payload=[datanode]))
|
gajim.socks5queue.progress_transfer_cb(self.name,
|
||||||
current_time = time.time()
|
file_props)
|
||||||
file_props.elapsed_time += current_time - file_props.last_time
|
else:
|
||||||
file_props.last_time = current_time
|
log.debug('Nothing to read, but file not completed')
|
||||||
file_props.received_len += len(chunk)
|
|
||||||
gajim.socks5queue.progress_transfer_cb(self.name,
|
|
||||||
file_props)
|
|
||||||
else:
|
|
||||||
# notify the other side about stream closing
|
|
||||||
# notify the local user about sucessfull send
|
|
||||||
# delete the local stream
|
|
||||||
self.connection.send(nbxmpp.Protocol('iq',
|
|
||||||
file_props.direction[1:], 'set',
|
|
||||||
payload=[nbxmpp.Node(nbxmpp.NS_IBB + ' close',
|
|
||||||
{'sid': file_props.transport_sid})]))
|
|
||||||
file_props.completed = True
|
|
||||||
|
|
||||||
def IBBMessageHandler(self, conn, stanza):
|
def IBBMessageHandler(self, conn, stanza):
|
||||||
"""
|
"""
|
||||||
|
@ -978,6 +980,7 @@ class ConnectionIBBytestream(ConnectionBytestream):
|
||||||
else:
|
else:
|
||||||
conn.send(nbxmpp.Error(stanza, nbxmpp.ERR_ITEM_NOT_FOUND))
|
conn.send(nbxmpp.Error(stanza, nbxmpp.ERR_ITEM_NOT_FOUND))
|
||||||
|
|
||||||
|
|
||||||
def IBBAllIqHandler(self, conn, stanza):
|
def IBBAllIqHandler(self, conn, stanza):
|
||||||
"""
|
"""
|
||||||
Handle remote side reply about if it agree or not to receive our
|
Handle remote side reply about if it agree or not to receive our
|
||||||
|
@ -999,25 +1002,9 @@ class ConnectionIBBytestream(ConnectionBytestream):
|
||||||
else:
|
else:
|
||||||
conn.Event('IBB', 'ERROR ON SEND', file_props)
|
conn.Event('IBB', 'ERROR ON SEND', file_props)
|
||||||
elif stanza.getType() == 'result':
|
elif stanza.getType() == 'result':
|
||||||
if file_props.direction[0] == '|':
|
self.SendHandler(file_props)
|
||||||
file_props.direction = file_props.direction[1:]
|
|
||||||
self.SendHandler()
|
|
||||||
else:
|
|
||||||
conn.send(nbxmpp.Error(stanza,
|
|
||||||
nbxmpp.ERR_UNEXPECTED_REQUEST))
|
|
||||||
break
|
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):
|
class ConnectionSocks5BytestreamZeroconf(ConnectionSocks5Bytestream):
|
||||||
|
|
||||||
|
|
|
@ -1271,6 +1271,11 @@ class AddNewContactWindow:
|
||||||
def _nec_gateway_prompt_received(self, obj):
|
def _nec_gateway_prompt_received(self, obj):
|
||||||
if self.adding_jid:
|
if self.adding_jid:
|
||||||
jid, transport, type_ = self.adding_jid
|
jid, transport, type_ = self.adding_jid
|
||||||
|
if obj.stanza.getError():
|
||||||
|
ErrorDialog(_('Error while adding transport contact'),
|
||||||
|
_('This error occured while adding a contact for transport '
|
||||||
|
'%s:\n\n%s') % (transport, obj.stanza.getErrorMsg()))
|
||||||
|
return
|
||||||
if obj.prompt_jid:
|
if obj.prompt_jid:
|
||||||
self._add_jid(obj.prompt_jid, type_)
|
self._add_jid(obj.prompt_jid, type_)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -70,8 +70,7 @@ class FileTransfersWindow:
|
||||||
'notify_ft_complete_checkbox')
|
'notify_ft_complete_checkbox')
|
||||||
|
|
||||||
shall_notify = gajim.config.get('notify_on_file_complete')
|
shall_notify = gajim.config.get('notify_on_file_complete')
|
||||||
self.notify_ft_checkbox.set_active(shall_notify
|
self.notify_ft_checkbox.set_active(shall_notify)
|
||||||
)
|
|
||||||
self.model = Gtk.ListStore(GdkPixbuf.Pixbuf, str, str, str, str, int,
|
self.model = Gtk.ListStore(GdkPixbuf.Pixbuf, str, str, str, str, int,
|
||||||
int, str)
|
int, str)
|
||||||
self.tree.set_model(self.model)
|
self.tree.set_model(self.model)
|
||||||
|
@ -841,7 +840,7 @@ class FileTransfersWindow:
|
||||||
if not is_row_selected:
|
if not is_row_selected:
|
||||||
# no selection, disable the buttons
|
# no selection, disable the buttons
|
||||||
self.set_all_insensitive()
|
self.set_all_insensitive()
|
||||||
elif not is_stopped:
|
elif not is_stopped and file_props.continue_cb:
|
||||||
if is_transfer_active(file_props):
|
if is_transfer_active(file_props):
|
||||||
# file transfer is active
|
# file transfer is active
|
||||||
self.toggle_pause_continue(True)
|
self.toggle_pause_continue(True)
|
||||||
|
|
|
@ -988,11 +988,6 @@ class Interface:
|
||||||
session = gajim.connections[account].get_jingle_session(jid=None,
|
session = gajim.connections[account].get_jingle_session(jid=None,
|
||||||
sid=file_props.sid)
|
sid=file_props.sid)
|
||||||
ft_win = self.instances['file_transfers']
|
ft_win = self.instances['file_transfers']
|
||||||
if not file_props.hash_:
|
|
||||||
# We disn't get the hash, sender probably don't support that
|
|
||||||
jid = file_props.sender
|
|
||||||
self.popup_ft_result(account, jid, file_props)
|
|
||||||
ft_win.set_status(file_props, 'ok')
|
|
||||||
h = Hashes()
|
h = Hashes()
|
||||||
try:
|
try:
|
||||||
file_ = open(file_props.file_name, 'rb')
|
file_ = open(file_props.file_name, 'rb')
|
||||||
|
@ -1027,14 +1022,26 @@ class Interface:
|
||||||
if file_props.stalled or file_props.paused:
|
if file_props.stalled or file_props.paused:
|
||||||
return
|
return
|
||||||
|
|
||||||
if file_props.type_ == 'r' and file_props.hash_: # we receive a file
|
if file_props.type_ == 'r': # we receive a file
|
||||||
gajim.socks5queue.remove_receiver(file_props.sid, True, True)
|
gajim.socks5queue.remove_receiver(file_props.sid, True, True)
|
||||||
# we compare hashes
|
|
||||||
if file_props.session_type == 'jingle':
|
if file_props.session_type == 'jingle':
|
||||||
# Compare hashes in a new thread
|
if file_props.hash_ and file_props.error == 0:
|
||||||
self.hashThread = Thread(target=self.__compare_hashes,
|
# We compare hashes in a new thread
|
||||||
args=(account, file_props))
|
self.hashThread = Thread(target=self.__compare_hashes,
|
||||||
self.hashThread.start()
|
args=(account, file_props))
|
||||||
|
self.hashThread.start()
|
||||||
|
else:
|
||||||
|
# We disn't get the hash, sender probably don't support that
|
||||||
|
jid = file_props.sender
|
||||||
|
self.popup_ft_result(account, jid, file_props)
|
||||||
|
if file_props.error == 0:
|
||||||
|
ft.set_status(file_props, 'ok')
|
||||||
|
session = gajim.connections[account].get_jingle_session(jid=None,
|
||||||
|
sid=file_props.sid)
|
||||||
|
# End jingle session
|
||||||
|
# TODO: only if there are no other parallel downloads in this session
|
||||||
|
if session:
|
||||||
|
session.end_session()
|
||||||
else: # we send a file
|
else: # we send a file
|
||||||
jid = file_props.receiver
|
jid = file_props.receiver
|
||||||
gajim.socks5queue.remove_sender(file_props.sid, True, True)
|
gajim.socks5queue.remove_sender(file_props.sid, True, True)
|
||||||
|
|
Loading…
Reference in New Issue