Class Jabber::FileTransfer::Helper
In: lib/xmpp4r/bytestreams/helper/filetransfer.rb
Parent: Object
Message Presence XMPPStanza Iq XMPPElement ErrorResponse X IqQuery JabberError ComponentAuthenticationFailure ArgumentError SOCKS5Error ServerError NoNameXmlnsRegistered ClientAuthenticationFailure Connection Client Component Client Singleton IdGenerator Comparable JID StandardError REXML::Element Stream IqQuery IqQueryVersion IqQueryRoster IqQueryBytestreams IqQueryRPC IqQueryMUCOwner IqQueryMUCAdmin IqQueryDiscoItems IqQueryDiscoInfo Responder SimpleResponder XRosterItem RosterXItem XMPPElement RosterItem IqFeature StreamHost IqSiFile IqSiFileRange IqSi StreamHostUsed C Body HTML UserItem XMUCUserInvite Tune Configuration Items Item IqPubSub Publish Event IqPubSubOwner Subscription Unsubscribe Feature Item Identity XDataField XDataReported XDataTitle XDataInstructions IqVcard XRoster RosterX X XMUC XMUCUser XDelay XData Iq IqCommand SOCKS5Bytestreams SOCKS5BytestreamsTarget SOCKS5BytestreamsInitiator SOCKS5BytestreamsServerStreamHost TCPSocket SOCKS5Socket IBB IBBTarget IBBInitiator XMLRPC::ParserWriterChooseMixin Client Server XMLRPC::ParseContentType XMLRPC::BasicServer MUCClient SimpleMUCClient MUC::UserItem XMUCUserItem IqQueryMUCAdminItem XParent Base Anonymous DigestMD5 Plain PubSub::ServiceHelper Helper SubscriptionConfig NodeConfig OwnerNodeConfig EventItems EventItem ServiceHelper NodeHelper FileSource Base Bot CallbackList Callback StreamParser Semaphore Helper Responder SOCKS5BytestreamsPeer SOCKS5BytestreamsServer IBBQueueItem Helper MUCBrowser NodeBrowser Responder Helper Helper lib/xmpp4r/message.rb lib/xmpp4r/connection.rb lib/xmpp4r/xmppstanza.rb lib/xmpp4r/iq.rb lib/xmpp4r/callbacks.rb lib/xmpp4r/idgenerator.rb lib/xmpp4r/stream.rb lib/xmpp4r/client.rb lib/xmpp4r/jid.rb lib/xmpp4r/x.rb lib/xmpp4r/streamparser.rb lib/xmpp4r/semaphore.rb lib/xmpp4r/errors.rb lib/xmpp4r/component.rb lib/xmpp4r/presence.rb lib/xmpp4r/xmppelement.rb lib/xmpp4r/query.rb XParent lib/xmpp4r/version/helper/responder.rb lib/xmpp4r/version/helper/simpleresponder.rb lib/xmpp4r/version/iq/version.rb Version lib/xmpp4r/roster/x/roster.rb lib/xmpp4r/roster/helper/roster.rb lib/xmpp4r/roster/iq/roster.rb Roster lib/xmpp4r/feature_negotiation/iq/feature.rb FeatureNegotiation lib/xmpp4r/command/iq/command.rb lib/xmpp4r/command/helper/responder.rb Command lib/xmpp4r/bytestreams/iq/si.rb lib/xmpp4r/bytestreams/helper/ibb/initiator.rb lib/xmpp4r/bytestreams/helper/socks5bytestreams/base.rb lib/xmpp4r/bytestreams/iq/bytestreams.rb lib/xmpp4r/bytestreams/helper/socks5bytestreams/initiator.rb lib/xmpp4r/bytestreams/helper/socks5bytestreams/target.rb lib/xmpp4r/bytestreams/helper/socks5bytestreams/socks5.rb lib/xmpp4r/bytestreams/helper/ibb/target.rb lib/xmpp4r/bytestreams/helper/socks5bytestreams/server.rb lib/xmpp4r/bytestreams/helper/ibb/base.rb Bytestreams lib/xmpp4r/caps/helper/helper.rb lib/xmpp4r/caps/c.rb Caps lib/xmpp4r/xhtml/html.rb XHTML lib/xmpp4r/rpc/helper/server.rb lib/xmpp4r/rpc/helper/client.rb lib/xmpp4r/rpc/iq/rpc.rb RPC lib/xmpp4r/muc/iq/mucadminitem.rb lib/xmpp4r/muc/x/muc.rb lib/xmpp4r/muc/item.rb lib/xmpp4r/muc/helper/simplemucclient.rb lib/xmpp4r/muc/iq/mucadmin.rb lib/xmpp4r/muc/helper/mucbrowser.rb lib/xmpp4r/muc/x/mucuseritem.rb lib/xmpp4r/muc/x/mucuserinvite.rb lib/xmpp4r/muc/iq/mucowner.rb lib/xmpp4r/muc/helper/mucclient.rb MUC lib/xmpp4r/delay/x/delay.rb Delay lib/xmpp4r/sasl.rb SASL lib/xmpp4r/tune/helper/helper.rb lib/xmpp4r/tune/tune.rb UserTune lib/xmpp4r/pubsub/children/item.rb lib/xmpp4r/pubsub/children/configuration.rb lib/xmpp4r/pubsub/children/subscription.rb lib/xmpp4r/pubsub/helper/servicehelper.rb lib/xmpp4r/pubsub/children/unsubscribe.rb lib/xmpp4r/pubsub/children/publish.rb lib/xmpp4r/pubsub/children/event.rb lib/xmpp4r/pubsub/iq/pubsub.rb lib/xmpp4r/pubsub/helper/nodebrowser.rb lib/xmpp4r/pubsub/helper/nodehelper.rb lib/xmpp4r/pubsub/children/items.rb lib/xmpp4r/pubsub/children/subscription_config.rb lib/xmpp4r/pubsub/children/node_config.rb PubSub lib/xmpp4r/httpbinding/client.rb HTTPBinding lib/xmpp4r/discovery/iq/discoinfo.rb lib/xmpp4r/discovery/helper/responder.rb lib/xmpp4r/discovery/iq/discoitems.rb Discovery lib/xmpp4r/dataforms/x/data.rb Dataforms lib/xmpp4r/bytestreams/helper/filetransfer.rb TransferSource FileTransfer lib/xmpp4r/vcard/helper/vcard.rb lib/xmpp4r/vcard/iq/vcard.rb Vcard lib/xmpp4r/framework/base.rb lib/xmpp4r/framework/bot.rb Framework Jabber dot/m_99_0.png

The FileTransfer helper provides the ability to respond to incoming and to offer outgoing file-transfers.

Methods

Attributes

allow_bytestreams  [RW]  Set this to false if you don‘t want to use SOCKS5Bytestreams
allow_ibb  [RW]  Set this to false if you don‘t want to use IBB
my_jid  [RW]  Set this if you want to use this helper in a Component

Public Class methods

Create a new FileTransfer instance

[Source]

     # File lib/xmpp4r/bytestreams/helper/filetransfer.rb, line 139
139:       def initialize(stream)
140:         @stream = stream
141:         @my_jid = nil
142:         @allow_bytestreams = true
143:         @allow_ibb = true
144: 
145:         @incoming_cbs = CallbackList.new
146: 
147:         @stream.add_iq_callback(150, self) { |iq|
148:           if iq.type == :set
149:             file = iq.first_element('si/file')
150:             field = nil
151:             iq.each_element('si/feature/x') { |e| field = e.field('stream-method') }
152: 
153:             if file and field
154:               @incoming_cbs.process(iq, file)
155:               true
156:             else
157:               false
158:             end
159:           else
160:             false
161:           end
162:         }
163:       end

Public Instance methods

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

[Source]

     # File lib/xmpp4r/bytestreams/helper/filetransfer.rb, line 186
186:       def accept(iq, offset=nil, length=nil)
187:         oldsi = iq.first_element('si')
188: 
189:         answer = iq.answer(false)
190:         answer.type = :result
191: 
192:         si = answer.add(Bytestreams::IqSi.new)
193:         if (offset or length) and oldsi.file.range
194:           si.add(Bytestreams::IqSiFile.new)
195:           si.file.add(Bytestreams::IqSiFileRange.new(offset, length))
196:         end
197:         si.add(FeatureNegotiation::IqFeature.new.import(oldsi.feature))
198:         si.feature.x.type = :submit
199:         stream_method = si.feature.x.field('stream-method')
200: 
201:         if stream_method.options.keys.include?(Bytestreams::NS_BYTESTREAMS) and @allow_bytestreams
202:           stream_method.values = [Bytestreams::NS_BYTESTREAMS]
203:           stream_method.options = []
204:           @stream.send(answer)
205: 
206:           Bytestreams::SOCKS5BytestreamsTarget.new(@stream, oldsi.id, iq.from, iq.to)
207:         elsif stream_method.options.keys.include?(Bytestreams::IBB::NS_IBB) and @allow_ibb
208:           stream_method.values = [Bytestreams::IBB::NS_IBB]
209:           stream_method.options = []
210:           @stream.send(answer)
211: 
212:           Bytestreams::IBBTarget.new(@stream, oldsi.id, iq.from, iq.to)
213:         else
214:           eanswer = iq.answer(false)
215:           eanswer.type = :error
216:           eanswer.add(ErrorResponse.new('bad-request')).type = :cancel
217:           eanswer.error.add(REXML::Element.new('no-valid-streams')).add_namespace('http://jabber.org/protocol/si')
218:           @stream.send(eanswer)
219: 
220:           nil
221:         end
222:       end

Add a callback which will be invoked upon an incoming file-transfer

block takes two arguments:

You may then invoke accept or decline

[Source]

     # File lib/xmpp4r/bytestreams/helper/filetransfer.rb, line 172
172:       def add_incoming_callback(priority = 0, ref = nil, &block)
173:         @incoming_cbs.add(priority, ref, block)
174:       end

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

[Source]

     # File lib/xmpp4r/bytestreams/helper/filetransfer.rb, line 228
228:       def decline(iq)
229:         answer = iq.answer(false)
230:         answer.type = :error
231:         error = answer.add(ErrorResponse.new('forbidden', 'Offer declined'))
232:         error.type = :cancel
233:         @stream.send(answer)
234:       end

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]

[Source]

     # File lib/xmpp4r/bytestreams/helper/filetransfer.rb, line 250
250:       def offer(jid, source, desc=nil, from=nil)
251:         from = from || @my_jid || @stream.jid
252:         session_id = Jabber::IdGenerator.instance.generate_id
253: 
254:         offered_methods = {}
255:         if @allow_bytestreams
256:           offered_methods[Bytestreams::NS_BYTESTREAMS] = nil
257:         end
258:         if @allow_ibb
259:           offered_methods[Bytestreams::IBB::NS_IBB] = nil
260:         end
261: 
262:         iq = Iq.new(:set, jid)
263:         iq.from = from
264:         si = iq.add(Bytestreams::IqSi.new(session_id, Bytestreams::PROFILE_FILETRANSFER, source.mime))
265: 
266:         file = si.add(Bytestreams::IqSiFile.new(source.filename, source.size))
267:         file.hash = source.md5
268:         file.date = source.date
269:         file.description = desc if desc
270:         file.add(Bytestreams::IqSiFileRange.new) if source.can_range?
271: 
272:         feature = si.add(REXML::Element.new('feature'))
273:         feature.add_namespace 'http://jabber.org/protocol/feature-neg'
274:         x = feature.add(Dataforms::XData.new(:form))
275:         stream_method_field = x.add(Dataforms::XDataField.new('stream-method', :list_single))
276:         stream_method_field.options = offered_methods
277: 
278:         begin
279:           stream_method = nil
280:           response = nil
281:           @stream.send_with_id(iq) do |r|
282:             response = r
283:             si = response.first_element('si')
284:             if si and si.feature and si.feature.x
285:               stream_method = si.feature.x.field('stream-method').values.first
286: 
287:               if si.file and si.file.range
288:                 if source.can_range?
289:                   source.seek(si.file.range.offset) if si.file.range.offset
290:                   source.length = si.file.range.length if si.file.range.length
291:                 else
292:                   source.read(si.file.range.offset)
293:                 end
294:               end
295:             end
296:           end
297:         rescue ServerError => e
298:           if e.error.code == 403  # Declined
299:             return false
300:           else
301:             raise e
302:           end
303:         end
304: 
305:         if stream_method == Bytestreams::NS_BYTESTREAMS and @allow_bytestreams
306:           Bytestreams::SOCKS5BytestreamsInitiator.new(@stream, session_id, from, jid)
307:         elsif stream_method == Bytestreams::IBB::NS_IBB and @allow_ibb
308:           Bytestreams::IBBInitiator.new(@stream, session_id, from, jid)
309:         else  # Target responded with a stream_method we didn't offer
310:           eanswer = response.answer
311:           eanswer.type = :error
312:           eanswer.add ErrorResponse.new('bad-request')
313:           @stream.send(eanswer)
314:           nil
315:         end
316:       end

[Validate]