check file integrity when transfer is completed

This commit is contained in:
Jefry Lagrange 2012-01-23 22:28:07 -05:00
parent c51fb07d09
commit 5142ebd626
5 changed files with 35 additions and 15 deletions

View File

@ -157,7 +157,7 @@ class ConnectionJingle(object):
transport = JingleTransportIBB()
c = JingleFileTransfer(jingle, transport=transport,
file_props=file_props, use_security=use_security)
c.hash_algo = self.__hash_support(contact)
jingle.hash_algo = self.__hash_support(contact)
jingle.add_content('file' + helpers.get_random_string_16(), c)
jingle.start_session()
return c.transport.sid

View File

@ -103,9 +103,7 @@ class JingleFileTransfer(JingleContent):
self.media = 'file'
self.nominated_cand = {}
# Hash algorithm that we are using to calculate the integrity of the
# file. Could be 'md5', 'sha-1', etc...
self.hash_algo = None
def __on_session_initiate(self, stanza, content, error, action):
gajim.nec.push_incoming_event(FileRequestReceivedEvent(None,
@ -117,14 +115,16 @@ class JingleFileTransfer(JingleContent):
self.hashThread.start()
def __calcHash(self):
if self.hash_algo == None:
if self.session.hash_algo == None:
return
try:
file = open(self.file_props['file-name'], 'r')
except:
return
h = xmpp.Hashes()
h.calculateHash(self.hash_algo, file)
hash = h.calculateHash(self.session.hash_algo, file)
self.file_props['hash'] = hash
h.addHash(hash, self.session.hash_algo)
checksum = xmpp.Node(tag='checksum',
payload=[xmpp.Node(tag='file', payload=[h])])
checksum.setNamespace(xmpp.NS_JINGLE_FILE_TRANSFER)

View File

@ -98,6 +98,9 @@ class JingleSession(object):
self.accepted = True # is this session accepted by user
# Hash algorithm that we are using to calculate the integrity of the
# file. Could be 'md5', 'sha-1', etc...
self.hash_algo = None
self.file_hash = None
# callbacks to call on proper contents
# use .prepend() to add new callbacks, especially when you're going
@ -424,9 +427,11 @@ class JingleSession(object):
for hash in hashes.getChildren():
algo = hash.getAttr('algo')
if algo in xmpp.Hashes.supported:
self.hash_algo = algo
data = hash.getData()
# This only works because there is only one session
# per file in jingleFT
self.file_hash = data
print data
raise xmpp.NodeProcessed
self.__send_error(stanza, 'feature-not-implemented', 'unsupported-info', type_='modify')
raise xmpp.NodeProcessed

View File

@ -1067,7 +1067,6 @@ class Hashes(Node):
"""
hl = None
hash = None
# file_string can be a string or a file
if type(file_string) == str: # if it is a string
if algo == 'md5':
@ -1104,7 +1103,7 @@ class Hashes(Node):
hl.update(line)
hash = hl.hexdigest()
self.addHash(hash, algo)
return hash
def addHash(self, hash, algo):
"""

View File

@ -71,6 +71,7 @@ from session import ChatControlSession
import common.sleepy
from common.xmpp import idlequeue
from common.xmpp import Hashes
from common.zeroconf import connection_zeroconf
from common import resolver
from common import caps_cache
@ -908,6 +909,22 @@ class Interface:
self.last_ftwindow_update = time.time()
self.instances['file_transfers'].set_progress(file_props['type'],
file_props['sid'], file_props['received-len'])
def __compare_hashes(self, account, file_props):
session = gajim.connections[account].get_jingle_session(jid=None,
sid=file_props['session-sid'])
h = Hashes()
try:
file = open(file_props['file-name'], 'r')
except:
return
hash = h.calculateHash(session.hash_algo, file)
# If the hash we received and the hash of the file are the same,
# then the file is not corrupt
if session.file_hash == hash:
print "they are te same"
# End jingle session
if session:
session.end_session()
def handle_event_file_rcv_completed(self, account, file_props):
ft = self.instances['file_transfers']
@ -919,18 +936,17 @@ class Interface:
if 'stalled' in file_props and file_props['stalled'] or \
'paused' in file_props and file_props['paused']:
return
if file_props['type'] == 'r': # we receive a file
jid = unicode(file_props['sender'])
# Compare hashes in a new thread
self.hashThread = Thread(target=self.__compare_hashes,
args=(account, file_props))
self.hashThread.start()
gajim.socks5queue.remove_receiver(file_props['sid'], True, True)
else: # we send a file
jid = unicode(file_props['receiver'])
gajim.socks5queue.remove_sender(file_props['sid'], True, True)
# End jingle session
session = gajim.connections[account].get_jingle_session(jid,
sid=file_props['session-sid'])
if session:
session.end_session()
if helpers.allow_popup_window(account):
if file_props['error'] == 0: