Class: Jabber::FileTransfer::Helper
- Inherits:
-
Object
- Object
- Jabber::FileTransfer::Helper
- Defined in:
- lib/xmpp4r/bytestreams/helper/filetransfer.rb
Overview
The FileTransfer helper provides the ability to respond to incoming and to offer outgoing file-transfers.
Instance Attribute Summary collapse
-
#allow_bytestreams ⇒ Object
Set this to false if you don’t want to use SOCKS5Bytestreams.
-
#allow_ibb ⇒ Object
Set this to false if you don’t want to use IBB.
-
#my_jid ⇒ Object
Set this if you want to use this helper in a Component.
Instance Method Summary collapse
-
#accept(iq, offset = nil, length = nil) ⇒ Object
Accept an incoming file-transfer, to be used in a block given to add_incoming_callback.
-
#add_incoming_callback(priority = 0, ref = nil, &block) ⇒ Object
Add a callback which will be invoked upon an incoming file-transfer.
-
#decline(iq) ⇒ Object
- Decline an incoming file-transfer, to be used in a block given to add_incoming_callback iq
- Iq
-
of file-transfer we want to decline.
-
#initialize(stream) ⇒ Helper
constructor
Create a new FileTransfer instance.
-
#offer(jid, source, desc = nil, from = nil) ⇒ Object
Offer a file to somebody.
Constructor Details
#initialize(stream) ⇒ Helper
Create a new FileTransfer instance
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/xmpp4r/bytestreams/helper/filetransfer.rb', line 141 def initialize(stream) @stream = stream @my_jid = nil @allow_bytestreams = true @allow_ibb = true @incoming_cbs = CallbackList.new @stream.add_iq_callback(150, self) { |iq| if iq.type == :set file = iq.first_element('si/file') field = nil iq.each_element('si/feature/x') { |e| field = e.field('stream-method') } if file and field @incoming_cbs.process(iq, file) true else false end else false end } end |
Instance Attribute Details
#allow_bytestreams ⇒ Object
Set this to false if you don’t want to use SOCKS5Bytestreams
134 135 136 |
# File 'lib/xmpp4r/bytestreams/helper/filetransfer.rb', line 134 def allow_bytestreams @allow_bytestreams end |
#allow_ibb ⇒ Object
Set this to false if you don’t want to use IBB
137 138 139 |
# File 'lib/xmpp4r/bytestreams/helper/filetransfer.rb', line 137 def allow_ibb @allow_ibb end |
#my_jid ⇒ Object
Set this if you want to use this helper in a Component
131 132 133 |
# File 'lib/xmpp4r/bytestreams/helper/filetransfer.rb', line 131 def my_jid @my_jid end |
Instance Method Details
#accept(iq, offset = nil, length = nil) ⇒ Object
Accept an incoming file-transfer, to be used in a block given to add_incoming_callback
offset and length will be ignored if there is no ‘si/file/range’ in iq.
- iq
- Iq
-
of file-transfer we want to accept
- offset
- Fixnum
-
or [nil]
- length
- Fixnum
-
or [nil]
- result
- Bytestreams::SOCKS5BytestreamsTarget
-
or [Bytestreams::IBBTarget] or [nil] if no valid stream-method
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 |
# File 'lib/xmpp4r/bytestreams/helper/filetransfer.rb', line 188 def accept(iq, offset=nil, length=nil) oldsi = iq.first_element('si') answer = iq.answer(false) answer.type = :result si = answer.add(Bytestreams::IqSi.new) if (offset or length) and oldsi.file.range si.add(Bytestreams::IqSiFile.new) si.file.add(Bytestreams::IqSiFileRange.new(offset, length)) end si.add(FeatureNegotiation::IqFeature.new.import(oldsi.feature)) si.feature.x.type = :submit stream_method = si.feature.x.field('stream-method') if stream_method..keys.include?(Bytestreams::NS_BYTESTREAMS) and @allow_bytestreams stream_method.values = [Bytestreams::NS_BYTESTREAMS] stream_method. = [] @stream.send(answer) Bytestreams::SOCKS5BytestreamsTarget.new(@stream, oldsi.id, iq.from, iq.to) elsif stream_method..keys.include?(Bytestreams::IBB::NS_IBB) and @allow_ibb stream_method.values = [Bytestreams::IBB::NS_IBB] stream_method. = [] @stream.send(answer) Bytestreams::IBBTarget.new(@stream, oldsi.id, iq.from, iq.to) else eanswer = iq.answer(false) eanswer.type = :error eanswer.add(ErrorResponse.new('bad-request')).type = :cancel eanswer.error.add(REXML::Element.new('no-valid-streams')).add_namespace('http://jabber.org/protocol/si') @stream.send(eanswer) nil end end |
#add_incoming_callback(priority = 0, ref = nil, &block) ⇒ Object
Add a callback which will be invoked upon an incoming file-transfer
block takes two arguments:
-
Iq
-
Bytestreams::IqSiFile in the Iq
You may then invoke accept or decline
174 175 176 |
# File 'lib/xmpp4r/bytestreams/helper/filetransfer.rb', line 174 def add_incoming_callback(priority = 0, ref = nil, &block) @incoming_cbs.add(priority, ref, block) end |
#decline(iq) ⇒ Object
Decline an incoming file-transfer, to be used in a block given to add_incoming_callback
- iq
- Iq
-
of file-transfer we want to decline
230 231 232 233 234 235 236 |
# File 'lib/xmpp4r/bytestreams/helper/filetransfer.rb', line 230 def decline(iq) answer = iq.answer(false) answer.type = :error error = answer.add(ErrorResponse.new('forbidden', 'Offer declined')) error.type = :cancel @stream.send(answer) end |
#offer(jid, source, desc = nil, from = nil) ⇒ Object
Offer a file to somebody
Will wait for a response from the peer
The result is a stream which you can configure, or nil if the peer responded with an invalid stream-method.
May raise an ServerError
- jid
- JID
-
to send the file to
- source
-
File-transfer source, implementing the FileSource interface
- desc
- String
-
or [nil] Optional file description
- from
- String
-
or [nil] Optional jid for components
- result
- Bytestreams::SOCKS5BytestreamsInitiator
-
or [Bytestreams::IBBInitiator] or [nil]
252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 |
# File 'lib/xmpp4r/bytestreams/helper/filetransfer.rb', line 252 def offer(jid, source, desc=nil, from=nil) from = from || @my_jid || @stream.jid session_id = Jabber::IdGenerator.instance.generate_id offered_methods = {} if @allow_bytestreams offered_methods[Bytestreams::NS_BYTESTREAMS] = nil end if @allow_ibb offered_methods[Bytestreams::IBB::NS_IBB] = nil end iq = Iq.new(:set, jid) iq.from = from si = iq.add(Bytestreams::IqSi.new(session_id, Bytestreams::PROFILE_FILETRANSFER, source.mime)) file = si.add(Bytestreams::IqSiFile.new(source.filename, source.size)) file.hash = source.md5 file.date = source.date file.description = desc if desc file.add(Bytestreams::IqSiFileRange.new) if source.can_range? feature = si.add(REXML::Element.new('feature')) feature.add_namespace 'http://jabber.org/protocol/feature-neg' x = feature.add(Dataforms::XData.new(:form)) stream_method_field = x.add(Dataforms::XDataField.new('stream-method', :list_single)) stream_method_field. = offered_methods begin stream_method = nil response = nil @stream.send_with_id(iq) do |r| response = r si = response.first_element('si') if si and si.feature and si.feature.x stream_method = si.feature.x.field('stream-method').values.first if si.file and si.file.range if source.can_range? source.seek(si.file.range.offset) if si.file.range.offset source.length = si.file.range.length if si.file.range.length else source.read(si.file.range.offset) end end end end rescue ServerError => e if e.error.code == 403 # Declined return false else raise e end end if stream_method == Bytestreams::NS_BYTESTREAMS and @allow_bytestreams Bytestreams::SOCKS5BytestreamsInitiator.new(@stream, session_id, from, jid) elsif stream_method == Bytestreams::IBB::NS_IBB and @allow_ibb Bytestreams::IBBInitiator.new(@stream, session_id, from, jid) else # Target responded with a stream_method we didn't offer eanswer = response.answer eanswer.type = :error eanswer.add ErrorResponse.new('bad-request') @stream.send(eanswer) nil end end |