comparison src/plugins/plugin_xep_0096.py @ 398:cb0285372818

File transfer: - proxy managed in XEP-0065 (Socks5 bytestream) - bug: fixed a bad id used during stream negociation
author Goffi <goffi@goffi.org>
date Wed, 05 Oct 2011 16:49:57 +0200
parents 8f3551ceee17
children 22788653ae8d
comparison
equal deleted inserted replaced
397:ccfd69d090c3 398:cb0285372818
68 try: 68 try:
69 del self._waiting_for_approval[approval_id] 69 del self._waiting_for_approval[approval_id]
70 except KeyError: 70 except KeyError:
71 warning(_("kill id called on a non existant approval id")) 71 warning(_("kill id called on a non existant approval id"))
72 72
73 def transferRequest(self, from_jid, si_id, si_mime_type, si_el, profile): 73 def transferRequest(self, iq_id, from_jid, si_id, si_mime_type, si_el, profile):
74 """Called when a file transfer is requested 74 """Called when a file transfer is requested
75 @param iq_id: id of the iq request
75 @param from_jid: jid of the sender 76 @param from_jid: jid of the sender
76 @param si_id: Stream Initiation session id 77 @param si_id: Stream Initiation session id
77 @param si_mime_type: Mime type of the file (or default "application/octet-stream" if unknown) 78 @param si_mime_type: Mime type of the file (or default "application/octet-stream" if unknown)
78 @param si_el: domish.Element of the request 79 @param si_el: domish.Element of the request
79 @param profile: %(doc_profile)s""" 80 @param profile: %(doc_profile)s"""
100 file_desc = unicode(file_child_el) 101 file_desc = unicode(file_child_el)
101 elif file_child_el.name == "range": 102 elif file_child_el.name == "range":
102 can_range = True 103 can_range = True
103 else: 104 else:
104 warning(_("No file element found")) 105 warning(_("No file element found"))
105 self.host.plugins["XEP-0095"].sendBadRequestError(si_id, from_jid, profile) 106 self.host.plugins["XEP-0095"].sendBadRequestError(iq_id, from_jid, profile)
106 return 107 return
107 108
108 if feature_elts: 109 if feature_elts:
109 feature_el = feature_elts[0] 110 feature_el = feature_elts[0]
110 form = data_form.Form.fromElement(feature_el.firstChildElement()) 111 form = data_form.Form.fromElement(feature_el.firstChildElement())
111 try: 112 try:
112 stream_method = self.host.plugins["XEP-0020"].negociate(feature_el, 'stream-method',self.managed_stream_m) 113 stream_method = self.host.plugins["XEP-0020"].negociate(feature_el, 'stream-method',self.managed_stream_m)
113 except KeyError: 114 except KeyError:
114 warning(_("No stream method found")) 115 warning(_("No stream method found"))
115 self.host.plugins["XEP-0095"].sendBadRequestError(si_id, from_jid, profile) 116 self.host.plugins["XEP-0095"].sendBadRequestError(iq_id, from_jid, profile)
116 return 117 return
117 if not stream_method: 118 if not stream_method:
118 warning(_("Can't find a valid stream method")) 119 warning(_("Can't find a valid stream method"))
119 self.host.plugins["XEP-0095"].sendFailedError(si_id, from_jid, profile) 120 self.host.plugins["XEP-0095"].sendFailedError(iq_id, from_jid, profile)
120 return 121 return
121 else: 122 else:
122 warning(_("No feature element found")) 123 warning(_("No feature element found"))
123 self.host.plugins["XEP-0095"].sendBadRequestError(si_id, from_jid, profile) 124 self.host.plugins["XEP-0095"].sendBadRequestError(iq_id, from_jid, profile)
124 return 125 return
125 126
126 #if we are here, the transfer can start, we just need user's agreement 127 #if we are here, the transfer can start, we just need user's agreement
127 data={ "filename":filename, "from":from_jid, "size":file_size, "date":file_date, "hash":file_hash, "desc":file_desc, "can_range": str(can_range) } 128 data={ "filename":filename, "id": iq_id, "from":from_jid, "size":file_size, "date":file_date, "hash":file_hash, "desc":file_desc, "can_range": str(can_range) }
128 self._waiting_for_approval[si_id] = [data, reactor.callLater(300, self._kill_id, si_id), stream_method, [], profile] 129 self._waiting_for_approval[si_id] = [data, reactor.callLater(300, self._kill_id, si_id), stream_method, [], profile]
129 130
130 self.host.askConfirmation(si_id, "FILE_TRANSFER", data, self.confirmationCB) 131 self.host.askConfirmation(si_id, "FILE_TRANSFER", data, self.confirmationCB)
131 132
132 133
135 @param dest_path: path of the destination file 136 @param dest_path: path of the destination file
136 @param can_range: True if the file pointer can be moved 137 @param can_range: True if the file pointer can be moved
137 @return: File Object""" 138 @return: File Object"""
138 return open(dest_path, "ab" if can_range else "wb") 139 return open(dest_path, "ab" if can_range else "wb")
139 140
140 def confirmationCB(self, id, accepted, frontend_data): 141 def confirmationCB(self, sid, accepted, frontend_data):
141 """Called on confirmation answer 142 """Called on confirmation answer
142 @param id: file transfer session id 143 @param sid: file transfer session id
143 @param accepted: True if file transfer is accepted 144 @param accepted: True if file transfer is accepted
144 @param frontend_data: data sent by frontend""" 145 @param frontend_data: data sent by frontend"""
145 data, timeout, stream_method, failed_methods, profile = self._waiting_for_approval[id] 146 data, timeout, stream_method, failed_methods, profile = self._waiting_for_approval[sid]
146 can_range = data['can_range'] == "True" 147 can_range = data['can_range'] == "True"
147 range_offset = 0 148 range_offset = 0
148 if accepted: 149 if accepted:
149 if timeout.active(): 150 if timeout.active():
150 timeout.cancel() 151 timeout.cancel()
151 try: 152 try:
152 dest_path = frontend_data['dest_path'] 153 dest_path = frontend_data['dest_path']
153 except KeyError: 154 except KeyError:
154 error(_('dest path not found in frontend_data')) 155 error(_('dest path not found in frontend_data'))
155 del(self._waiting_for_approval[id]) 156 del(self._waiting_for_approval[sid])
156 return 157 return
157 if stream_method == self.host.plugins["XEP-0065"].NAMESPACE: 158 if stream_method == self.host.plugins["XEP-0065"].NAMESPACE:
158 file_obj = self._getFileObject(dest_path, can_range) 159 file_obj = self._getFileObject(dest_path, can_range)
159 range_offset = file_obj.tell() 160 range_offset = file_obj.tell()
160 self.host.plugins["XEP-0065"].prepareToReceive(jid.JID(data['from']), id, file_obj, int(data["size"]), self._transferSucceeded, self._transferFailed) 161 self.host.plugins["XEP-0065"].prepareToReceive(jid.JID(data['from']), sid, file_obj, int(data["size"]), self._transferSucceeded, self._transferFailed)
161 #self.host.plugins["XEP-0065"].setData(data, id)
162 elif stream_method == self.host.plugins["XEP-0047"].NAMESPACE: 162 elif stream_method == self.host.plugins["XEP-0047"].NAMESPACE:
163 file_obj = self._getFileObject(dest_path, can_range) 163 file_obj = self._getFileObject(dest_path, can_range)
164 range_offset = file_obj.tell() 164 range_offset = file_obj.tell()
165 self.host.plugins["XEP-0047"].prepareToReceive(jid.JID(data['from']), id, file_obj, int(data["size"]), self._transferSucceeded, self._transferFailed) 165 self.host.plugins["XEP-0047"].prepareToReceive(jid.JID(data['from']), sid, file_obj, int(data["size"]), self._transferSucceeded, self._transferFailed)
166 else: 166 else:
167 error(_("Unknown stream method, this should not happen at this stage, cancelling transfer")) 167 error(_("Unknown stream method, this should not happen at this stage, cancelling transfer"))
168 del(self._waiting_for_approval[id]) 168 del(self._waiting_for_approval[sid])
169 return 169 return
170 170
171 #we can send the iq result 171 #we can send the iq result
172 feature_elt = self.host.plugins["XEP-0020"].chooseOption({'stream-method':stream_method}) 172 feature_elt = self.host.plugins["XEP-0020"].chooseOption({'stream-method':stream_method})
173 misc_elts = [] 173 misc_elts = []
175 if can_range: 175 if can_range:
176 range_elt = domish.Element(('', "range")) 176 range_elt = domish.Element(('', "range"))
177 range_elt['offset'] = str(range_offset) 177 range_elt['offset'] = str(range_offset)
178 #TODO: manage range length 178 #TODO: manage range length
179 misc_elts.append(range_elt) 179 misc_elts.append(range_elt)
180 self.host.plugins["XEP-0095"].acceptStream(id, data['from'], feature_elt, misc_elts, profile) 180 self.host.plugins["XEP-0095"].acceptStream(data["id"], data['from'], feature_elt, misc_elts, profile)
181 else: 181 else:
182 debug (_("Transfer [%s] refused"), id) 182 debug (_("Transfer [%s] refused"), sid)
183 self.host.plugins["XEP-0095"].sendRejectedError (id, data['from'], profile=profile) 183 self.host.plugins["XEP-0095"].sendRejectedError (data["id"], data['from'], profile=profile)
184 del(self._waiting_for_approval[id]) 184 del(self._waiting_for_approval[sid])
185 185
186 def _transferSucceeded(self, sid, file_obj, stream_method): 186 def _transferSucceeded(self, sid, file_obj, stream_method):
187 """Called by the stream method when transfer successfuly finished 187 """Called by the stream method when transfer successfuly finished
188 @param id: stream id""" 188 @param id: stream id"""
189 file_obj.close() 189 file_obj.close()
287 info(_('Transfer %s successfuly finished') % sid) 287 info(_('Transfer %s successfuly finished') % sid)
288 file_obj.close() 288 file_obj.close()
289 289
290 def sendFailureCb(self, sid, file_obj, stream_method, reason): 290 def sendFailureCb(self, sid, file_obj, stream_method, reason):
291 file_obj.close() 291 file_obj.close()
292 warning(_('Transfer %(id)s failed with stream method %(s_method)s') % { 'id': sid, s_method: stream_method }) 292 warning(_('Transfer %(id)s failed with stream method %(s_method)s') % { 'id': sid, "s_method": stream_method })