Mercurial > libervia-backend
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 }) |