annotate src/plugins/plugin_xep_0234.py @ 2489:e2a7bb875957

plugin pipe/stream, file transfert: refactoring and improvments: this is a big patch as things had to be changed at the same time. - changed methods using profile argument to use client instead - move SatFile in a new tools.stream module, has it should be part of core, not a plugin - new IStreamProducer interface, to handler starting a pull producer - new FileStreamObject which create a stream producer/consumer from a SatFile - plugin pipe is no more using unix named pipe, as it complicate the thing, special care need to be taken to not block, and it's generally not necessary. Instead a socket is now used, so the plugin has been renomed to jingle stream. - bad connection/error should be better handler in jingle stream plugin, and code should not block anymore - jp pipe commands have been updated accordingly fix bug 237
author Goffi <goffi@goffi.org>
date Thu, 08 Feb 2018 00:37:42 +0100
parents 0046283a285d
children 7ad5f2c4e34a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1934
2daf7b4c6756 use of /usr/bin/env instead of /usr/bin/python in shebang
Goffi <goffi@goffi.org>
parents: 1766
diff changeset
1 #!/usr/bin/env python2
1528
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
2 # -*- coding: utf-8 -*-
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
3
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
4 # SAT plugin for Jingle File Transfer (XEP-0234)
2483
0046283a285d dates update
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
5 # Copyright (C) 2009-2018 Jérôme Poisson (goffi@goffi.org)
1528
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
6
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
7 # This program is free software: you can redistribute it and/or modify
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
8 # it under the terms of the GNU Affero General Public License as published by
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
9 # the Free Software Foundation, either version 3 of the License, or
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
10 # (at your option) any later version.
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
11
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
12 # This program is distributed in the hope that it will be useful,
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
15 # GNU Affero General Public License for more details.
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
16
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
17 # You should have received a copy of the GNU Affero General Public License
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
19
1574
babd97d80049 plugins XEP-0234, file: moved file request dialog to file plugin
Goffi <goffi@goffi.org>
parents: 1571
diff changeset
20 from sat.core.i18n import _
1528
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
21 from sat.core.constants import Const as C
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
22 from sat.core.log import getLogger
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
23 log = getLogger(__name__)
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
24 from sat.core import exceptions
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
25 from wokkel import disco, iwokkel
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
26 from zope.interface import implements
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
27 from sat.tools import utils
2489
e2a7bb875957 plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
28 from sat.tools import stream
1528
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
29 import os.path
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
30 from twisted.words.xish import domish
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
31 from twisted.words.protocols.jabber import jid
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
32 from twisted.python import failure
1566
ec3848916ee8 plugin ip: implemented XEP-0279 for external ip retrieval + fixed bad exception handling
Goffi <goffi@goffi.org>
parents: 1557
diff changeset
33 from twisted.words.protocols.jabber.xmlstream import XMPPHandler
1571
c668081eba1c plugins XEP-0234, XEP-0260, XEP-0261: jingle session termination is managed by application (XEP-0234) instead of transport
Goffi <goffi@goffi.org>
parents: 1568
diff changeset
34 from twisted.internet import defer
1620
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
35 from twisted.internet import reactor
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
36 from twisted.internet import error as internet_error
1528
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
37
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
38
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
39 NS_JINGLE_FT = 'urn:xmpp:jingle:apps:file-transfer:4'
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
40
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
41 PLUGIN_INFO = {
2145
33c8c4973743 core (plugins): added missing contants + use of new constants in PLUGIN_INFO
Goffi <goffi@goffi.org>
parents: 2144
diff changeset
42 C.PI_NAME: "Jingle File Transfer",
33c8c4973743 core (plugins): added missing contants + use of new constants in PLUGIN_INFO
Goffi <goffi@goffi.org>
parents: 2144
diff changeset
43 C.PI_IMPORT_NAME: "XEP-0234",
33c8c4973743 core (plugins): added missing contants + use of new constants in PLUGIN_INFO
Goffi <goffi@goffi.org>
parents: 2144
diff changeset
44 C.PI_TYPE: "XEP",
33c8c4973743 core (plugins): added missing contants + use of new constants in PLUGIN_INFO
Goffi <goffi@goffi.org>
parents: 2144
diff changeset
45 C.PI_PROTOCOLS: ["XEP-0234"],
33c8c4973743 core (plugins): added missing contants + use of new constants in PLUGIN_INFO
Goffi <goffi@goffi.org>
parents: 2144
diff changeset
46 C.PI_DEPENDENCIES: ["XEP-0166", "XEP-0300", "FILE"],
33c8c4973743 core (plugins): added missing contants + use of new constants in PLUGIN_INFO
Goffi <goffi@goffi.org>
parents: 2144
diff changeset
47 C.PI_MAIN: "XEP_0234",
33c8c4973743 core (plugins): added missing contants + use of new constants in PLUGIN_INFO
Goffi <goffi@goffi.org>
parents: 2144
diff changeset
48 C.PI_HANDLER: "yes",
33c8c4973743 core (plugins): added missing contants + use of new constants in PLUGIN_INFO
Goffi <goffi@goffi.org>
parents: 2144
diff changeset
49 C.PI_DESCRIPTION: _("""Implementation of Jingle File Transfer""")
1528
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
50 }
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
51
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
52
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
53 class XEP_0234(object):
1571
c668081eba1c plugins XEP-0234, XEP-0260, XEP-0261: jingle session termination is managed by application (XEP-0234) instead of transport
Goffi <goffi@goffi.org>
parents: 1568
diff changeset
54 # TODO: assure everything is closed when file is sent or session terminate is received
1620
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
55 # TODO: call self._f.unregister when unloading order will be managing (i.e. when dependencies will be unloaded at the end)
1528
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
56
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
57 def __init__(self, host):
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
58 log.info(_("plugin Jingle File Transfer initialization"))
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
59 self.host = host
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
60 self._j = host.plugins["XEP-0166"] # shortcut to access jingle
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
61 self._j.registerApplication(NS_JINGLE_FT, self)
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
62 self._f = host.plugins["FILE"]
1585
846a39900fa6 plugins XEP-0096, XEP-0260, file: sendFile method is managed by file plugin, which choose the best available method + progress_id fix
Goffi <goffi@goffi.org>
parents: 1575
diff changeset
63 self._f.register(NS_JINGLE_FT, self.fileJingleSend, priority = 10000, method_name=u"Jingle")
1618
0de5f210fe56 plugin XEP-0300: implemented hashing:
Goffi <goffi@goffi.org>
parents: 1598
diff changeset
64 self._hash = self.host.plugins["XEP-0300"]
1528
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
65 host.bridge.addMethod("fileJingleSend", ".plugin", in_sign='sssss', out_sign='', method=self._fileJingleSend)
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
66
2144
1d3f73e065e1 core, jp: component handling + client handling refactoring:
Goffi <goffi@goffi.org>
parents: 1934
diff changeset
67 def getHandler(self, client):
1528
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
68 return XEP_0234_handler()
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
69
1585
846a39900fa6 plugins XEP-0096, XEP-0260, file: sendFile method is managed by file plugin, which choose the best available method + progress_id fix
Goffi <goffi@goffi.org>
parents: 1575
diff changeset
70 def _getProgressId(self, session, content_name):
846a39900fa6 plugins XEP-0096, XEP-0260, file: sendFile method is managed by file plugin, which choose the best available method + progress_id fix
Goffi <goffi@goffi.org>
parents: 1575
diff changeset
71 """Return a unique progress ID
846a39900fa6 plugins XEP-0096, XEP-0260, file: sendFile method is managed by file plugin, which choose the best available method + progress_id fix
Goffi <goffi@goffi.org>
parents: 1575
diff changeset
72
846a39900fa6 plugins XEP-0096, XEP-0260, file: sendFile method is managed by file plugin, which choose the best available method + progress_id fix
Goffi <goffi@goffi.org>
parents: 1575
diff changeset
73 @param session(dict): jingle session
846a39900fa6 plugins XEP-0096, XEP-0260, file: sendFile method is managed by file plugin, which choose the best available method + progress_id fix
Goffi <goffi@goffi.org>
parents: 1575
diff changeset
74 @param content_name(unicode): name of the content
846a39900fa6 plugins XEP-0096, XEP-0260, file: sendFile method is managed by file plugin, which choose the best available method + progress_id fix
Goffi <goffi@goffi.org>
parents: 1575
diff changeset
75 @return (unicode): unique progress id
846a39900fa6 plugins XEP-0096, XEP-0260, file: sendFile method is managed by file plugin, which choose the best available method + progress_id fix
Goffi <goffi@goffi.org>
parents: 1575
diff changeset
76 """
846a39900fa6 plugins XEP-0096, XEP-0260, file: sendFile method is managed by file plugin, which choose the best available method + progress_id fix
Goffi <goffi@goffi.org>
parents: 1575
diff changeset
77 return u'{}_{}'.format(session['id'], content_name)
846a39900fa6 plugins XEP-0096, XEP-0260, file: sendFile method is managed by file plugin, which choose the best available method + progress_id fix
Goffi <goffi@goffi.org>
parents: 1575
diff changeset
78
1567
268fda4236ca plugins XE0166, XEP-0234, XEP-0260, XEP-0261: renamed session key managing other peer's jid to "peer_jid" instead of "to_jid"
Goffi <goffi@goffi.org>
parents: 1566
diff changeset
79 def _fileJingleSend(self, peer_jid, filepath, name="", file_desc="", profile=C.PROF_KEY_NONE):
2489
e2a7bb875957 plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
80 client = self.host.getClient(profile)
e2a7bb875957 plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
81 return self.fileJingleSend(client, jid.JID(peer_jid), filepath, name or None, file_desc or None)
1528
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
82
2489
e2a7bb875957 plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
83 def fileJingleSend(self, client, peer_jid, filepath, name, file_desc=None):
1585
846a39900fa6 plugins XEP-0096, XEP-0260, file: sendFile method is managed by file plugin, which choose the best available method + progress_id fix
Goffi <goffi@goffi.org>
parents: 1575
diff changeset
84 """Send a file using jingle file transfer
846a39900fa6 plugins XEP-0096, XEP-0260, file: sendFile method is managed by file plugin, which choose the best available method + progress_id fix
Goffi <goffi@goffi.org>
parents: 1575
diff changeset
85
846a39900fa6 plugins XEP-0096, XEP-0260, file: sendFile method is managed by file plugin, which choose the best available method + progress_id fix
Goffi <goffi@goffi.org>
parents: 1575
diff changeset
86 @param peer_jid(jid.JID): destinee jid
846a39900fa6 plugins XEP-0096, XEP-0260, file: sendFile method is managed by file plugin, which choose the best available method + progress_id fix
Goffi <goffi@goffi.org>
parents: 1575
diff changeset
87 @param filepath(str): absolute path of the file
846a39900fa6 plugins XEP-0096, XEP-0260, file: sendFile method is managed by file plugin, which choose the best available method + progress_id fix
Goffi <goffi@goffi.org>
parents: 1575
diff changeset
88 @param name(unicode, None): name of the file
846a39900fa6 plugins XEP-0096, XEP-0260, file: sendFile method is managed by file plugin, which choose the best available method + progress_id fix
Goffi <goffi@goffi.org>
parents: 1575
diff changeset
89 @param file_desc(unicode, None): description of the file
846a39900fa6 plugins XEP-0096, XEP-0260, file: sendFile method is managed by file plugin, which choose the best available method + progress_id fix
Goffi <goffi@goffi.org>
parents: 1575
diff changeset
90 @return (D(unicode)): progress id
846a39900fa6 plugins XEP-0096, XEP-0260, file: sendFile method is managed by file plugin, which choose the best available method + progress_id fix
Goffi <goffi@goffi.org>
parents: 1575
diff changeset
91 """
846a39900fa6 plugins XEP-0096, XEP-0260, file: sendFile method is managed by file plugin, which choose the best available method + progress_id fix
Goffi <goffi@goffi.org>
parents: 1575
diff changeset
92 progress_id_d = defer.Deferred()
2489
e2a7bb875957 plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
93 self._j.initiate(client,
e2a7bb875957 plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
94 peer_jid,
1528
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
95 [{'app_ns': NS_JINGLE_FT,
1557
22f0307864b4 plugin XEP-0234: "senders" handling
Goffi <goffi@goffi.org>
parents: 1556
diff changeset
96 'senders': self._j.ROLE_INITIATOR,
1528
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
97 'app_kwargs': {'filepath': filepath,
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
98 'name': name,
1585
846a39900fa6 plugins XEP-0096, XEP-0260, file: sendFile method is managed by file plugin, which choose the best available method + progress_id fix
Goffi <goffi@goffi.org>
parents: 1575
diff changeset
99 'file_desc': file_desc,
846a39900fa6 plugins XEP-0096, XEP-0260, file: sendFile method is managed by file plugin, which choose the best available method + progress_id fix
Goffi <goffi@goffi.org>
parents: 1575
diff changeset
100 'progress_id_d': progress_id_d},
2489
e2a7bb875957 plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
101 }])
1585
846a39900fa6 plugins XEP-0096, XEP-0260, file: sendFile method is managed by file plugin, which choose the best available method + progress_id fix
Goffi <goffi@goffi.org>
parents: 1575
diff changeset
102 return progress_id_d
1528
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
103
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
104 # jingle callbacks
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
105
2489
e2a7bb875957 plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
106 def jingleSessionInit(self, client, session, content_name, filepath, name, file_desc, progress_id_d):
1598
b144babc2658 core, plugin file: fixed progress id + data is now returned by getProgress, instead of being an argument to fill
Goffi <goffi@goffi.org>
parents: 1585
diff changeset
107 progress_id_d.callback(self._getProgressId(session, content_name))
1528
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
108 content_data = session['contents'][content_name]
1556
cbfbe028d099 plugin XEP-0166, XEP-0234, XEP-0261:
Goffi <goffi@goffi.org>
parents: 1529
diff changeset
109 application_data = content_data['application_data']
cbfbe028d099 plugin XEP-0166, XEP-0234, XEP-0261:
Goffi <goffi@goffi.org>
parents: 1529
diff changeset
110 assert 'file_path' not in application_data
cbfbe028d099 plugin XEP-0166, XEP-0234, XEP-0261:
Goffi <goffi@goffi.org>
parents: 1529
diff changeset
111 application_data['file_path'] = filepath
cbfbe028d099 plugin XEP-0166, XEP-0234, XEP-0261:
Goffi <goffi@goffi.org>
parents: 1529
diff changeset
112 file_data = application_data['file_data'] = {}
1528
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
113 file_data['date'] = utils.xmpp_date()
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
114 file_data['desc'] = file_desc or ''
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
115 file_data['media-type'] = "application/octet-stream" # TODO
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
116 file_data['name'] = os.path.basename(filepath) if name is None else name
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
117 file_data['size'] = os.path.getsize(filepath)
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
118 desc_elt = domish.Element((NS_JINGLE_FT, 'description'))
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
119 file_elt = desc_elt.addElement("file")
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
120 for name in ('date', 'desc', 'media-type', 'name', 'size'):
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
121 file_elt.addElement(name, content=unicode(file_data[name]))
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
122 file_elt.addElement("range") # TODO
1618
0de5f210fe56 plugin XEP-0300: implemented hashing:
Goffi <goffi@goffi.org>
parents: 1598
diff changeset
123 file_elt.addChild(self._hash.buildHashElt())
1528
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
124 return desc_elt
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
125
2489
e2a7bb875957 plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
126 def jingleRequestConfirmation(self, client, action, session, content_name, desc_elt):
1528
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
127 """This method request confirmation for a jingle session"""
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
128 content_data = session['contents'][content_name]
1557
22f0307864b4 plugin XEP-0234: "senders" handling
Goffi <goffi@goffi.org>
parents: 1556
diff changeset
129 if content_data['senders'] not in (self._j.ROLE_INITIATOR, self._j.ROLE_RESPONDER):
22f0307864b4 plugin XEP-0234: "senders" handling
Goffi <goffi@goffi.org>
parents: 1556
diff changeset
130 log.warning(u"Bad sender, assuming initiator")
22f0307864b4 plugin XEP-0234: "senders" handling
Goffi <goffi@goffi.org>
parents: 1556
diff changeset
131 content_data['senders'] = self._j.ROLE_INITIATOR
1528
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
132 # first we grab file informations
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
133 try:
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
134 file_elt = desc_elt.elements(NS_JINGLE_FT, 'file').next()
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
135 except StopIteration:
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
136 raise failure.Failure(exceptions.DataError)
1585
846a39900fa6 plugins XEP-0096, XEP-0260, file: sendFile method is managed by file plugin, which choose the best available method + progress_id fix
Goffi <goffi@goffi.org>
parents: 1575
diff changeset
137 file_data = {'progress_id': self._getProgressId(session, content_name)}
1528
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
138 for name in ('date', 'desc', 'media-type', 'name', 'range', 'size'):
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
139 try:
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
140 file_data[name] = unicode(file_elt.elements(NS_JINGLE_FT, name).next())
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
141 except StopIteration:
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
142 file_data[name] = ''
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
143
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
144 try:
1620
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
145 hash_algo, file_data['hash_given'] = self._hash.parseHashElt(file_elt)
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
146 except exceptions.NotFound:
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
147 raise failure.Failure(exceptions.DataError)
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
148
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
149 if hash_algo is not None:
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
150 file_data['hash_algo'] = hash_algo
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
151 file_data['hash_hasher'] = hasher = self._hash.getHasher(hash_algo)
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
152 file_data['data_cb'] = lambda data: hasher.update(data)
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
153
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
154 try:
1575
833bdb227b16 plugins XEP-0234, file: moved human file size conversion to file plugi
Goffi <goffi@goffi.org>
parents: 1574
diff changeset
155 file_data['size'] = int(file_data['size'])
1528
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
156 except ValueError:
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
157 raise failure.Failure(exceptions.DataError)
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
158
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
159 name = file_data['name']
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
160 if '/' in name or '\\' in name:
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
161 log.warning(u"File name contain path characters, we replace them: {}".format(name))
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
162 file_data['name'] = name.replace('/', '_').replace('\\', '_')
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
163
1556
cbfbe028d099 plugin XEP-0166, XEP-0234, XEP-0261:
Goffi <goffi@goffi.org>
parents: 1529
diff changeset
164 content_data['application_data']['file_data'] = file_data
1528
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
165
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
166 # now we actualy request permission to user
1574
babd97d80049 plugins XEP-0234, file: moved file request dialog to file plugin
Goffi <goffi@goffi.org>
parents: 1571
diff changeset
167 def gotConfirmation(confirmed):
babd97d80049 plugins XEP-0234, file: moved file request dialog to file plugin
Goffi <goffi@goffi.org>
parents: 1571
diff changeset
168 if confirmed:
babd97d80049 plugins XEP-0234, file: moved file request dialog to file plugin
Goffi <goffi@goffi.org>
parents: 1571
diff changeset
169 finished_d = content_data['finished_d'] = defer.Deferred()
2489
e2a7bb875957 plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
170 args = [client, session, content_name, content_data]
1574
babd97d80049 plugins XEP-0234, file: moved file request dialog to file plugin
Goffi <goffi@goffi.org>
parents: 1571
diff changeset
171 finished_d.addCallbacks(self._finishedCb, self._finishedEb, args, None, args)
babd97d80049 plugins XEP-0234, file: moved file request dialog to file plugin
Goffi <goffi@goffi.org>
parents: 1571
diff changeset
172 return confirmed
babd97d80049 plugins XEP-0234, file: moved file request dialog to file plugin
Goffi <goffi@goffi.org>
parents: 1571
diff changeset
173
2489
e2a7bb875957 plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
174 d = self._f.getDestDir(client, session['peer_jid'], content_data, file_data, stream_object=True)
1574
babd97d80049 plugins XEP-0234, file: moved file request dialog to file plugin
Goffi <goffi@goffi.org>
parents: 1571
diff changeset
175 d.addCallback(gotConfirmation)
babd97d80049 plugins XEP-0234, file: moved file request dialog to file plugin
Goffi <goffi@goffi.org>
parents: 1571
diff changeset
176 return d
1528
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
177
2489
e2a7bb875957 plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
178 def jingleHandler(self, client, action, session, content_name, desc_elt):
1528
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
179 content_data = session['contents'][content_name]
1556
cbfbe028d099 plugin XEP-0166, XEP-0234, XEP-0261:
Goffi <goffi@goffi.org>
parents: 1529
diff changeset
180 application_data = content_data['application_data']
cbfbe028d099 plugin XEP-0166, XEP-0234, XEP-0261:
Goffi <goffi@goffi.org>
parents: 1529
diff changeset
181 if action in (self._j.A_ACCEPTED_ACK,):
1528
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
182 pass
1556
cbfbe028d099 plugin XEP-0166, XEP-0234, XEP-0261:
Goffi <goffi@goffi.org>
parents: 1529
diff changeset
183 elif action == self._j.A_SESSION_INITIATE:
cbfbe028d099 plugin XEP-0166, XEP-0234, XEP-0261:
Goffi <goffi@goffi.org>
parents: 1529
diff changeset
184 file_elt = desc_elt.elements(NS_JINGLE_FT, 'file').next()
cbfbe028d099 plugin XEP-0166, XEP-0234, XEP-0261:
Goffi <goffi@goffi.org>
parents: 1529
diff changeset
185 try:
cbfbe028d099 plugin XEP-0166, XEP-0234, XEP-0261:
Goffi <goffi@goffi.org>
parents: 1529
diff changeset
186 file_elt.elements(NS_JINGLE_FT, 'range').next()
cbfbe028d099 plugin XEP-0166, XEP-0234, XEP-0261:
Goffi <goffi@goffi.org>
parents: 1529
diff changeset
187 except StopIteration:
cbfbe028d099 plugin XEP-0166, XEP-0234, XEP-0261:
Goffi <goffi@goffi.org>
parents: 1529
diff changeset
188 # initiator doesn't manage <range>, but we do so we advertise it
cbfbe028d099 plugin XEP-0166, XEP-0234, XEP-0261:
Goffi <goffi@goffi.org>
parents: 1529
diff changeset
189 log.debug("adding <range> element")
cbfbe028d099 plugin XEP-0166, XEP-0234, XEP-0261:
Goffi <goffi@goffi.org>
parents: 1529
diff changeset
190 file_elt.addElement('range')
1528
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
191 elif action == self._j.A_SESSION_ACCEPT:
2489
e2a7bb875957 plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
192 assert not 'stream_object' in content_data
1620
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
193 file_data = application_data['file_data']
1556
cbfbe028d099 plugin XEP-0166, XEP-0234, XEP-0261:
Goffi <goffi@goffi.org>
parents: 1529
diff changeset
194 file_path = application_data['file_path']
1620
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
195 size = file_data['size']
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
196 # XXX: hash security is not critical here, so we just take the higher mandatory one
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
197 hasher = file_data['hash_hasher'] = self._hash.getHasher('sha-256')
2489
e2a7bb875957 plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
198 content_data['stream_object'] = stream.FileStreamObject(
e2a7bb875957 plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
199 self.host,
e2a7bb875957 plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
200 client,
e2a7bb875957 plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
201 file_path,
e2a7bb875957 plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
202 uid=self._getProgressId(session, content_name),
e2a7bb875957 plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
203 size=size,
e2a7bb875957 plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
204 data_cb=lambda data: hasher.update(data),
e2a7bb875957 plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
205 )
1571
c668081eba1c plugins XEP-0234, XEP-0260, XEP-0261: jingle session termination is managed by application (XEP-0234) instead of transport
Goffi <goffi@goffi.org>
parents: 1568
diff changeset
206 finished_d = content_data['finished_d'] = defer.Deferred()
2489
e2a7bb875957 plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
207 args = [client, session, content_name, content_data]
1571
c668081eba1c plugins XEP-0234, XEP-0260, XEP-0261: jingle session termination is managed by application (XEP-0234) instead of transport
Goffi <goffi@goffi.org>
parents: 1568
diff changeset
208 finished_d.addCallbacks(self._finishedCb, self._finishedEb, args, None, args)
1528
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
209 else:
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
210 log.warning(u"FIXME: unmanaged action {}".format(action))
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
211 return desc_elt
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
212
2489
e2a7bb875957 plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
213 def jingleSessionInfo(self, client, action, session, content_name, jingle_elt):
1620
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
214 """Called on session-info action
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
215
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
216 manage checksum, and ignore <received/> element
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
217 """
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
218 # TODO: manage <received/> element
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
219 content_data = session['contents'][content_name]
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
220 elts = [elt for elt in jingle_elt.elements() if elt.uri == NS_JINGLE_FT]
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
221 if not elts:
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
222 return
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
223 for elt in elts:
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
224 if elt.name == 'received':
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
225 pass
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
226 elif elt.name == 'checksum':
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
227 # we have received the file hash, we need to parse it
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
228 if content_data['senders'] == session['role']:
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
229 log.warning(u"unexpected checksum received while we are the file sender")
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
230 raise exceptions.DataError
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
231 info_content_name = elt['name']
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
232 if info_content_name != content_name:
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
233 # it was for an other content...
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
234 return
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
235 file_data = content_data['application_data']['file_data']
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
236 try:
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
237 file_elt = elt.elements((NS_JINGLE_FT, 'file')).next()
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
238 except StopIteration:
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
239 raise exceptions.DataError
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
240 algo, file_data['hash_given'] = self._hash.parseHashElt(file_elt)
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
241 if algo != file_data.get('hash_algo'):
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
242 log.warning(u"Hash algorithm used in given hash ({peer_algo}) doesn't correspond to the one we have used ({our_algo})"
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
243 .format(peer_algo=algo, our_algo=file_data.get('hash_algo')))
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
244 else:
2489
e2a7bb875957 plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
245 self._receiverTryTerminate(client, session, content_name, content_data)
1620
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
246 else:
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
247 raise NotImplementedError
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
248
2489
e2a7bb875957 plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
249 def _sendCheckSum(self, client, session, content_name, content_data):
1620
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
250 """Send the session-info with the hash checksum"""
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
251 file_data = content_data['application_data']['file_data']
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
252 hasher = file_data['hash_hasher']
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
253 hash_ = hasher.hexdigest()
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
254 log.debug(u"Calculated hash: {}".format(hash_))
2489
e2a7bb875957 plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
255 iq_elt, jingle_elt = self._j.buildSessionInfo(client, session)
1620
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
256 checksum_elt = jingle_elt.addElement((NS_JINGLE_FT, 'checksum'))
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
257 checksum_elt['creator'] = content_data['creator']
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
258 checksum_elt['name'] = content_name
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
259 file_elt = checksum_elt.addElement('file')
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
260 file_elt.addChild(self._hash.buildHashElt(hash_))
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
261 iq_elt.send()
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
262
2489
e2a7bb875957 plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
263 def _receiverTryTerminate(self, client, session, content_name, content_data, last_try=False):
1620
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
264 """Try to terminate the session
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
265
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
266 This method must only be used by the receiver.
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
267 It check if transfer is finished, and hash available,
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
268 if everything is OK, it check hash and terminate the session
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
269 @param last_try(bool): if True this mean than session must be terminated even given hash is not available
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
270 @return (bool): True if session was terminated
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
271 """
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
272 if not content_data.get('transfer_finished', False):
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
273 return False
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
274 file_data = content_data['application_data']['file_data']
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
275 hash_given = file_data.get('hash_given')
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
276 if hash_given is None:
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
277 if last_try:
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
278 log.warning(u"sender didn't sent hash checksum, we can't check the file")
2489
e2a7bb875957 plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
279 self._j.delayedContentTerminate(client, session, content_name)
e2a7bb875957 plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
280 content_data['stream_object'].close()
1620
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
281 return True
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
282 return False
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
283 hasher = file_data['hash_hasher']
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
284 hash_ = hasher.hexdigest()
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
285
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
286 if hash_ == hash_given:
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
287 log.info(u"Hash checked, file was successfully transfered: {}".format(hash_))
1626
63cef4dbf2a4 core, plugins file, XEP-0234, bridge: progression api enhancement:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
288 progress_metadata = {'hash': hash_,
63cef4dbf2a4 core, plugins file, XEP-0234, bridge: progression api enhancement:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
289 'hash_algo': file_data['hash_algo'],
63cef4dbf2a4 core, plugins file, XEP-0234, bridge: progression api enhancement:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
290 'hash_verified': C.BOOL_TRUE
63cef4dbf2a4 core, plugins file, XEP-0234, bridge: progression api enhancement:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
291 }
63cef4dbf2a4 core, plugins file, XEP-0234, bridge: progression api enhancement:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
292 error = None
1620
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
293 else:
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
294 log.warning(u"Hash mismatch, the file was not transfered correctly")
1626
63cef4dbf2a4 core, plugins file, XEP-0234, bridge: progression api enhancement:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
295 progress_metadata=None
63cef4dbf2a4 core, plugins file, XEP-0234, bridge: progression api enhancement:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
296 error = u"Hash mismatch: given={algo}:{given}, calculated={algo}:{our}".format(
63cef4dbf2a4 core, plugins file, XEP-0234, bridge: progression api enhancement:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
297 algo = file_data['hash_algo'],
63cef4dbf2a4 core, plugins file, XEP-0234, bridge: progression api enhancement:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
298 given = hash_given,
63cef4dbf2a4 core, plugins file, XEP-0234, bridge: progression api enhancement:
Goffi <goffi@goffi.org>
parents: 1620
diff changeset
299 our = hash_)
1620
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
300
2489
e2a7bb875957 plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
301 self._j.delayedContentTerminate(client, session, content_name)
e2a7bb875957 plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
302 content_data['stream_object'].close(progress_metadata, error)
1620
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
303 # we may have the last_try timer still active, so we try to cancel it
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
304 try:
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
305 content_data['last_try_timer'].cancel()
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
306 except (KeyError, internet_error.AlreadyCalled):
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
307 pass
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
308 return True
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
309
2489
e2a7bb875957 plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
310 def _finishedCb(self, dummy, client, session, content_name, content_data):
1753
27a140aa5023 plugin XEP-0234: log file transfer "terminated" instead of "completed", as the file may not be complete (check is done after)
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
311 log.info(u"File transfer terminated")
1571
c668081eba1c plugins XEP-0234, XEP-0260, XEP-0261: jingle session termination is managed by application (XEP-0234) instead of transport
Goffi <goffi@goffi.org>
parents: 1568
diff changeset
312 if content_data['senders'] != session['role']:
1620
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
313 # we terminate the session only if we are the receiver,
1571
c668081eba1c plugins XEP-0234, XEP-0260, XEP-0261: jingle session termination is managed by application (XEP-0234) instead of transport
Goffi <goffi@goffi.org>
parents: 1568
diff changeset
314 # as recommanded in XEP-0234 §2 (after example 6)
1620
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
315 content_data['transfer_finished'] = True
2489
e2a7bb875957 plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
316 if not self._receiverTryTerminate(client, session, content_name, content_data):
1620
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
317 # we have not received the hash yet, we wait 5 more seconds
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
318 content_data['last_try_timer'] = reactor.callLater(
2489
e2a7bb875957 plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
319 5, self._receiverTryTerminate, client, session, content_name, content_data, last_try=True)
1620
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
320 else:
4dd07d026214 plugin XEP-0234: hash checksum proper handling
Goffi <goffi@goffi.org>
parents: 1618
diff changeset
321 # we are the sender, we send the checksum
2489
e2a7bb875957 plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
322 self._sendCheckSum(client, session, content_name, content_data)
e2a7bb875957 plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
323 content_data['stream_object'].close()
1571
c668081eba1c plugins XEP-0234, XEP-0260, XEP-0261: jingle session termination is managed by application (XEP-0234) instead of transport
Goffi <goffi@goffi.org>
parents: 1568
diff changeset
324
2489
e2a7bb875957 plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
325 def _finishedEb(self, failure, client, session, content_name, content_data):
1669
697effba0310 plugin pipe: rewritten plugin as a jingle application. The current implentation can, in some cases, block the backend, and is experimental only. Improvments are needed in the future.
Goffi <goffi@goffi.org>
parents: 1626
diff changeset
326 log.warning(u"Error while streaming file: {}".format(failure))
2489
e2a7bb875957 plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
327 content_data['stream_object'].close()
e2a7bb875957 plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
328 self._j.contentTerminate(client, session, content_name, reason=self._j.REASON_FAILED_TRANSPORT)
1571
c668081eba1c plugins XEP-0234, XEP-0260, XEP-0261: jingle session termination is managed by application (XEP-0234) instead of transport
Goffi <goffi@goffi.org>
parents: 1568
diff changeset
329
1528
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
330
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
331 class XEP_0234_handler(XMPPHandler):
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
332 implements(iwokkel.IDisco)
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
333
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
334 def getDiscoInfo(self, requestor, target, nodeIdentifier=''):
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
335 return [disco.DiscoFeature(NS_JINGLE_FT)]
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
336
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
337 def getDiscoItems(self, requestor, target, nodeIdentifier=''):
1c71d7335d02 plugin XEP-0234: jingle file transfer first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
338 return []