comparison sat/plugins/plugin_xep_0047.py @ 2927:69e4716d6268

plugins (jingle) file transfer: use initial "from" attribute as local jid instead of client.jid: while client.jid is fine in a client context, for components it's not the right jid to use: it is the jid of the component itself while the file transfer/jingle session entity may be established with this jid + a local part (e.g. if client is files.example.net, session may be established with louise@files.example.net, in which case "from" is louise@files.example.net, while client.jid will be files.example.net). As a consequence, using client.jid was causing trouble with components. This patch fixes it for jingle and plugins linked to file transfer by keeping a "local_jid" variable in the session, where the jid from the original "from" attribute is used.
author Goffi <goffi@goffi.org>
date Sun, 28 Apr 2019 08:55:13 +0200
parents 003b8b4b56a7
children ab2696e34d29
comparison
equal deleted inserted replaced
2926:4cd7545c4ebb 2927:69e4716d6268
129 129
130 session deferred is fired when transfer is finished 130 session deferred is fired when transfer is finished
131 """ 131 """
132 return self._createSession(*args, **kwargs)[DEFER_KEY] 132 return self._createSession(*args, **kwargs)[DEFER_KEY]
133 133
134 def _createSession(self, client, stream_object, to_jid, sid): 134 def _createSession(self, client, stream_object, local_jid, to_jid, sid):
135 """Called when a bytestream is imminent 135 """Called when a bytestream is imminent
136 136
137 @param stream_object(IConsumer): stream object where data will be written 137 @param stream_object(IConsumer): stream object where data will be written
138 @param local_jid(jid.JID): same as [startStream]
138 @param to_jid(jid.JId): jid of the other peer 139 @param to_jid(jid.JId): jid of the other peer
139 @param sid(unicode): session id 140 @param sid(unicode): session id
140 @return (dict): session data 141 @return (dict): session data
141 """ 142 """
142 if sid in client.xep_0047_current_stream: 143 if sid in client.xep_0047_current_stream:
143 raise exceptions.ConflictError(u"A session with this id already exists !") 144 raise exceptions.ConflictError(u"A session with this id already exists !")
144 session_data = client.xep_0047_current_stream[sid] = { 145 session_data = client.xep_0047_current_stream[sid] = {
145 "id": sid, 146 "id": sid,
146 DEFER_KEY: defer.Deferred(), 147 DEFER_KEY: defer.Deferred(),
148 "local_jid": local_jid,
147 "to": to_jid, 149 "to": to_jid,
148 "stream_object": stream_object, 150 "stream_object": stream_object,
149 "seq": -1, 151 "seq": -1,
150 "timer": reactor.callLater(TIMEOUT, self._timeOut, sid, client), 152 "timer": reactor.callLater(TIMEOUT, self._timeOut, sid, client),
151 } 153 }
283 ) 285 )
284 if sid is not None: 286 if sid is not None:
285 self._killSession(sid, client, error_condition) 287 self._killSession(sid, client, error_condition)
286 client.send(iq_elt) 288 client.send(iq_elt)
287 289
288 def startStream(self, client, stream_object, to_jid, sid, block_size=None): 290 def startStream(self, client, stream_object, local_jid, to_jid, sid, block_size=None):
289 """Launch the stream workflow 291 """Launch the stream workflow
290 292
291 @param stream_object(ifaces.IStreamProducer): stream object to send 293 @param stream_object(ifaces.IStreamProducer): stream object to send
294 @param local_jid(jid.JID): jid to use as local jid
295 This is needed for client which can be addressed with a different jid than
296 client.jid if a local part is used (e.g. piotr@file.example.net where
297 client.jid would be file.example.net)
292 @param to_jid(jid.JID): JID of the recipient 298 @param to_jid(jid.JID): JID of the recipient
293 @param sid(unicode): Stream session id 299 @param sid(unicode): Stream session id
294 @param block_size(int, None): size of the block (or None for default) 300 @param block_size(int, None): size of the block (or None for default)
295 """ 301 """
296 session_data = self._createSession(client, stream_object, to_jid, sid) 302 session_data = self._createSession(client, stream_object, local_jid, to_jid, sid)
297 303
298 if block_size is None: 304 if block_size is None:
299 block_size = XEP_0047.BLOCK_SIZE 305 block_size = XEP_0047.BLOCK_SIZE
300 assert block_size <= 65535 306 assert block_size <= 65535
301 session_data["block_size"] = block_size 307 session_data["block_size"] = block_size
302 308
303 iq_elt = client.IQ() 309 iq_elt = client.IQ()
310 iq_elt["from"] = local_jid.full()
304 iq_elt["to"] = to_jid.full() 311 iq_elt["to"] = to_jid.full()
305 open_elt = iq_elt.addElement((NS_IBB, "open")) 312 open_elt = iq_elt.addElement((NS_IBB, "open"))
306 open_elt["block-size"] = str(block_size) 313 open_elt["block-size"] = str(block_size)
307 open_elt["sid"] = sid 314 open_elt["sid"] = sid
308 open_elt["stanza"] = "iq" # TODO: manage <message> stanza ? 315 open_elt["stanza"] = "iq" # TODO: manage <message> stanza ?
321 session_data["timer"].reset(TIMEOUT) 328 session_data["timer"].reset(TIMEOUT)
322 329
323 buffer_ = session_data["stream_object"].read(session_data["block_size"]) 330 buffer_ = session_data["stream_object"].read(session_data["block_size"])
324 if buffer_: 331 if buffer_:
325 next_iq_elt = client.IQ() 332 next_iq_elt = client.IQ()
333 next_iq_elt["from"] = session_data["local_jid"].full()
326 next_iq_elt["to"] = session_data["to"].full() 334 next_iq_elt["to"] = session_data["to"].full()
327 data_elt = next_iq_elt.addElement((NS_IBB, "data")) 335 data_elt = next_iq_elt.addElement((NS_IBB, "data"))
328 seq = session_data["seq"] = (session_data["seq"] + 1) % 65535 336 seq = session_data["seq"] = (session_data["seq"] + 1) % 65535
329 data_elt["seq"] = unicode(seq) 337 data_elt["seq"] = unicode(seq)
330 data_elt["sid"] = session_data["id"] 338 data_elt["sid"] = session_data["id"]
348 @param session_data(dict): data of this streaming session 356 @param session_data(dict): data of this streaming session
349 @param client: %(doc_client)s 357 @param client: %(doc_client)s
350 @param failure_reason(unicode, None): reason of the failure, or None if steam was successful 358 @param failure_reason(unicode, None): reason of the failure, or None if steam was successful
351 """ 359 """
352 iq_elt = client.IQ() 360 iq_elt = client.IQ()
361 iq_elt["from"] = session_data["local_jid"].full()
353 iq_elt["to"] = session_data["to"].full() 362 iq_elt["to"] = session_data["to"].full()
354 close_elt = iq_elt.addElement((NS_IBB, "close")) 363 close_elt = iq_elt.addElement((NS_IBB, "close"))
355 close_elt["sid"] = session_data["id"] 364 close_elt["sid"] = session_data["id"]
356 iq_elt.send() 365 iq_elt.send()
357 self._killSession(session_data["id"], client, failure_reason) 366 self._killSession(session_data["id"], client, failure_reason)