### Home Classes Methods

### In Files

- lib/xmpp4r/bytestreams/helper/filetransfer.rb

### Parent

Object

### Methods

- ::new
- #accept
- #add_incoming_callback
- #decline
- #offer

### Files

- CHANGELOG
- COPYING
- LICENSE
- README.rdoc
- README_ruby19.txt

### Class/Module Index

Quicksearch

- Jabber
- Jabber::ArgumentError
- Jabber::Bytestreams
- Jabber::Bytestreams::IBB
- Jabber::Bytestreams::IBBInitiator
- Jabber::Bytestreams::IBBQueueItem
- Jabber::Bytestreams::IBBTarget
- Jabber::Bytestreams::IqQueryBytestreams
- Jabber::Bytestreams::IqSi
- Jabber::Bytestreams::IqSiFile
- Jabber::Bytestreams::IqSiFileRange
- Jabber::Bytestreams::SOCKS5Bytestreams
- Jabber::Bytestreams::SOCKS5BytestreamsInitiator
- Jabber::Bytestreams::SOCKS5BytestreamsPeer
- Jabber::Bytestreams::SOCKS5BytestreamsServer
- Jabber::Bytestreams::SOCKS5BytestreamsServerStreamHost
- Jabber::Bytestreams::SOCKS5BytestreamsTarget
- Jabber::Bytestreams::SOCKS5Socket
- Jabber::Bytestreams::StreamHost
- Jabber::Bytestreams::StreamHostUsed
- Jabber::Callback
- Jabber::CallbackList
- Jabber::Caps
- Jabber::Caps::C
- Jabber::Caps::Helper
- Jabber::Client
- Jabber::ClientAuthenticationFailure
- Jabber::Command
- Jabber::Command::IqCommand
- Jabber::Command::Responder
- Jabber::Component
- Jabber::ComponentAuthenticationFailure
- Jabber::Connection
- Jabber::Connection::SSLSocketUTF8
- Jabber::Dataforms
- Jabber::Dataforms::XData
- Jabber::Dataforms::XDataField
- Jabber::Dataforms::XDataInstructions
- Jabber::Dataforms::XDataReported
- Jabber::Dataforms::XDataTitle
- Jabber::Delay
- Jabber::Delay::XDelay
- Jabber::Discovery
- Jabber::Discovery::Feature
- Jabber::Discovery::Helper
- Jabber::Discovery::Identity
- Jabber::Discovery::IqQueryDiscoInfo
- Jabber::Discovery::IqQueryDiscoItems
- Jabber::Discovery::Item
- Jabber::Discovery::Responder
- Jabber::EntityTime
- Jabber::EntityTime::IqTime
- Jabber::EntityTime::Responder
- Jabber::ErrorResponse
- Jabber::FeatureNegotiation
- Jabber::FeatureNegotiation::IqFeature
- Jabber::FileTransfer
- Jabber::FileTransfer::FileSource
- Jabber::FileTransfer::Helper
- Jabber::FileTransfer::TransferSource
- Jabber::Framework
- Jabber::Framework::Base
- Jabber::Framework::Bot
- Jabber::HTTPBinding
- Jabber::HTTPBinding::Client
- Jabber::IdGenerator
- Jabber::InvalidChatState
- Jabber::Iq
- Jabber::IqQuery
- Jabber::JID
- Jabber::JabberError
- Jabber::LastActivity
- Jabber::LastActivity::Helper
- Jabber::LastActivity::IqQueryLastActivity
- Jabber::MUC
- Jabber::MUC::IqQueryMUCAdmin
- Jabber::MUC::IqQueryMUCAdminItem
- Jabber::MUC::IqQueryMUCOwner
- Jabber::MUC::MUCBrowser
- Jabber::MUC::MUCClient
- Jabber::MUC::SimpleMUCClient
- Jabber::MUC::UserItem
- Jabber::MUC::XMUC
- Jabber::MUC::XMUCUser
- Jabber::MUC::XMUCUserInvite
- Jabber::MUC::XMUCUserItem
- Jabber::Message
- Jabber::NoNameXmlnsRegistered
- Jabber::NotConnected
- Jabber::Observable
- Jabber::Observable::Contact
- Jabber::Observable::PubSub
- Jabber::Observable::PubSub::AlreadySet
- Jabber::Observable::PubSub::NoService
- Jabber::Observable::Subscriptions
- Jabber::Presence
- Jabber::PubSub
- Jabber::PubSub::Configuration
- Jabber::PubSub::Event
- Jabber::PubSub::EventItem
- Jabber::PubSub::EventItems
- Jabber::PubSub::IqPubSub
- Jabber::PubSub::IqPubSubOwner
- Jabber::PubSub::Item
- Jabber::PubSub::Items
- Jabber::PubSub::NodeBrowser
- Jabber::PubSub::NodeConfig
- Jabber::PubSub::NodeHelper
- Jabber::PubSub::OAuthPubSubStreamHelper
- Jabber::PubSub::OAuthServiceHelper
- Jabber::PubSub::OwnerNodeConfig
- Jabber::PubSub::Publish
- Jabber::PubSub::Retract
- Jabber::PubSub::ServiceHelper
- Jabber::PubSub::Subscription
- Jabber::PubSub::SubscriptionConfig
- Jabber::PubSub::Unsubscribe
- Jabber::RPC
- Jabber::RPC::Client
- Jabber::RPC::IqQueryRPC
- Jabber::RPC::Server
- Jabber::Reliable
- Jabber::Reliable::Connection
- Jabber::Reliable::Listener
- Jabber::Roster
- Jabber::Roster::Helper
- Jabber::Roster::Helper::RosterItem
- Jabber::Roster::IqQueryRoster
- Jabber::Roster::RosterItem
- Jabber::Roster::RosterX
- Jabber::Roster::RosterXItem
- Jabber::Roster::XRoster
- Jabber::Roster::XRosterItem
- Jabber::SASL
- Jabber::SASL::Anonymous
- Jabber::SASL::Base
- Jabber::SASL::DigestMD5
- Jabber::SASL::Plain
- Jabber::SOCKS5Error
- Jabber::Semaphore
- Jabber::ServerDisconnected
- Jabber::Stream
- Jabber::Stream::ThreadBlock
- Jabber::StreamParser
- Jabber::Test
- Jabber::Test::ListenerMocker
- Jabber::UserLocation
- Jabber::UserLocation::Helper
- Jabber::UserLocation::Location
- Jabber::UserTune
- Jabber::UserTune::Helper
- Jabber::UserTune::Tune
- Jabber::Vcard
- Jabber::Vcard::Helper
- Jabber::Vcard::IqVcard
- Jabber::Version
- Jabber::Version::IqQueryVersion
- Jabber::Version::Responder
- Jabber::Version::SimpleResponder
- Jabber::X
- Jabber::XHTML
- Jabber::XHTML::Body
- Jabber::XHTML::HTML
- Jabber::XMPPElement
- Jabber::XMPPStanza
- Jabber::XParent
- REXML
- REXML::Element
- REXML::IOSource
- XMLRPC
- XMLRPC::Create
- Base64
- ObservableThing
- QObserver
- ThreadStore

No matching classes.

# Jabber::FileTransfer::Helper

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

### 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

new(stream) click to toggle source

Create a new FileTransfer instance

    # 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

### Public Instance Methods

accept(iq, offset=nil, length=nil) click to toggle source

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

    # 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.options.keys.include?(Bytestreams::NS_BYTESTREAMS) and @allow_bytestreams
        stream_method.values = [Bytestreams::NS_BYTESTREAMS]
        stream_method.options = []
        @stream.send(answer)

        Bytestreams::SOCKS5BytestreamsTarget.new(@stream, oldsi.id, iq.from, iq.to)
      elsif stream_method.options.keys.include?(Bytestreams::IBB::NS_IBB) and @allow_ibb
        stream_method.values = [Bytestreams::IBB::NS_IBB]
        stream_method.options = []
        @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) click to toggle source

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

    # 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) click to toggle source

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

    # 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) click to toggle source

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]

    # 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.options = 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

[Validate]

Generated with the Darkfish Rdoc Generator 2.