Class Jabber::Connection
In: lib/xmpp4r/connection.rb
Parent: Stream
Message Presence XMPPStanza Iq XMPPElement ErrorResponse X IqQuery JabberError ComponentAuthenticationFailure ArgumentError InvalidChatState SOCKS5Error ServerError NoNameXmlnsRegistered ServerDisconnected ClientAuthenticationFailure Connection Client Component Connection Client Singleton IdGenerator Comparable JID Enumerable CallbackList Items Publish StandardError REXML::Element Stream XMPPElement Location IqFeature StreamHost IqSiFile IqSiFileRange IqSi StreamHostUsed XRosterItem RosterItem C Body HTML UserItem XMUCUserInvite Configuration Retract IqPubSub Item IqPubSubOwner Event Subscription Unsubscribe Tune XDataField XDataReported XDataTitle XDataInstructions Feature Item Identity IqVcard PubSub::ServiceHelper Helper Helper SOCKS5Bytestreams SOCKS5BytestreamsTarget SOCKS5BytestreamsInitiator SOCKS5BytestreamsServerStreamHost TCPSocket SOCKS5Socket IqQuery IqQueryBytestreams IqQueryRoster IqQueryVersion IqQueryRPC IqQueryMUCOwner IqQueryMUCAdmin IqQueryDiscoItems IqQueryDiscoInfo IqQueryLastActivity IBB IBBTarget IBBInitiator RosterXItem XRoster RosterX X XDelay XMUC XMUCUser XData Responder SimpleResponder Iq IqCommand XMLRPC::ParserWriterChooseMixin Client Server XMLRPC::ParseContentType XMLRPC::BasicServer MUCClient SimpleMUCClient MUC::UserItem XMUCUserItem IqQueryMUCAdminItem XParent SubscriptionConfig NodeConfig OwnerNodeConfig EventItems ServiceHelper OAuthServiceHelper NodeHelper EventItem Base Anonymous DigestMD5 Plain FileSource Base Bot Callback StreamParser Semaphore SOCKS5BytestreamsPeer SOCKS5BytestreamsServer IBBQueueItem Helper Responder Helper Listener MUCBrowser NodeBrowser ListenerMocker Helper Responder Helper 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/location/helper/helper.rb lib/xmpp4r/location/location.rb UserLocation lib/xmpp4r/feature_negotiation/iq/feature.rb FeatureNegotiation 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/roster/x/roster.rb lib/xmpp4r/roster/helper/roster.rb lib/xmpp4r/roster/iq/roster.rb Roster lib/xmpp4r/version/helper/responder.rb lib/xmpp4r/version/helper/simpleresponder.rb lib/xmpp4r/version/iq/version.rb Version lib/xmpp4r/command/iq/command.rb lib/xmpp4r/command/helper/responder.rb Command lib/xmpp4r/caps/helper/helper.rb lib/xmpp4r/caps/c.rb Caps lib/xmpp4r/reliable.rb Reliable lib/xmpp4r/delay/x/delay.rb Delay 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/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/helper/oauth_service_helper.rb lib/xmpp4r/pubsub/children/event.rb lib/xmpp4r/pubsub/iq/pubsub.rb lib/xmpp4r/pubsub/children/retract.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 OAuthPubSubStreamHelper PubSub lib/xmpp4r/httpbinding/client.rb HTTPBinding lib/xmpp4r/tune/helper/helper.rb lib/xmpp4r/tune/tune.rb UserTune lib/xmpp4r/sasl.rb SASL lib/xmpp4r/test/listener_mocker.rb Test lib/xmpp4r/dataforms/x/data.rb Dataforms lib/xmpp4r/discovery/helper/helper.rb lib/xmpp4r/discovery/iq/discoinfo.rb lib/xmpp4r/discovery/helper/responder.rb lib/xmpp4r/discovery/iq/discoitems.rb Discovery lib/xmpp4r/bytestreams/helper/filetransfer.rb TransferSource FileTransfer lib/xmpp4r/last/helper/helper.rb lib/xmpp4r/last/iq/last.rb LastActivity lib/xmpp4r/framework/base.rb lib/xmpp4r/framework/bot.rb Framework lib/xmpp4r/vcard/helper/vcard.rb lib/xmpp4r/vcard/iq/vcard.rb Vcard Jabber dot/m_110_0.png

The connection class manages the TCP connection to the Jabber server

Methods

Attributes

allow_tls  [RW]  Allow TLS negotiation? Defaults to true
features_timeout  [RW]  How many seconds to wait for <stream:features/> before proceeding
host  [R] 
keepalive_interval  [RW]  Keep-alive interval in seconds, defaults to 60 (see private method keepalive_loop for implementation details)
port  [R] 
ssl_capath  [RW]  Optional CA-Path for TLS-handshake
ssl_verifycb  [RW]  Optional callback for verification of SSL peer
use_ssl  [RW]  whether to use the old and deprecated SSL protocol Defaults to false

Public Class methods

Create a new connection to the given host and port

[Source]

    # File lib/xmpp4r/connection.rb, line 41
41:     def initialize
42:       super()
43:       @host = nil
44:       @port = nil
45:       @allow_tls = defined? OpenSSL
46:       @tls = false
47:       @ssl_capath = nil
48:       @ssl_verifycb = nil
49:       @features_timeout = 10
50:       @keepalive_interval = 60
51:       @use_ssl = false
52:     end

Public Instance methods

[Source]

     # File lib/xmpp4r/connection.rb, line 96
 96:     def accept_features
 97:       begin
 98:         Timeout::timeout(@features_timeout) {
 99:           Jabber::debuglog("FEATURES: waiting...")
100:           @features_sem.wait
101:           Jabber::debuglog("FEATURES: waiting finished")
102:         }
103:       rescue Timeout::Error
104:         Jabber::debuglog("FEATURES: timed out when waiting, stream peer seems not XMPP compliant")
105:       end
106: 
107:       if @allow_tls and not is_tls? and @stream_features['starttls'] == 'urn:ietf:params:xml:ns:xmpp-tls'
108:         begin
109:           starttls
110:         rescue
111:           Jabber::debuglog("STARTTLS:\nFailure: #{$!}")
112:         end
113:       end
114:     end

Closing connection: first kill keepaliveThread (but only if it‘s not me), then call Stream#close!

[Source]

    # File lib/xmpp4r/connection.rb, line 90
90:     def close!
91:       @keepaliveThread.kill if @keepaliveThread and @keepaliveThread.alive? and @keepaliveThread != Thread.current
92:       super
93:       @keepaliveThread.kill if @keepaliveThread and @keepaliveThread.alive?
94:     end

Connect to the Jabber server through a TCP Socket, start the Jabber parser, invoke to accept_features to wait for TLS, start the keep-alive thread

[Source]

    # File lib/xmpp4r/connection.rb, line 59
59:     def connect(host, port)
60:       @host = host
61:       @port = port
62:       # Reset is_tls?, so that it works when reconnecting
63:       @tls = false
64: 
65:       Jabber::debuglog("CONNECTING:\n#{@host}:#{@port}")
66:       @socket = TCPSocket.new(@host, @port)
67: 
68:       # We want to use the old and deprecated SSL protocol (usually on port 5223)
69:       if @use_ssl
70:         ssl = OpenSSL::SSL::SSLSocket.new(@socket)
71:         ssl.connect # start SSL session
72:         ssl.sync_close = true
73:         Jabber::debuglog("SSL connection established.")
74:         @socket = ssl
75:       end
76: 
77:       start
78: 
79:       accept_features
80: 
81:       @keepaliveThread = Thread.new do
82:         Thread.current.abort_on_exception = true
83:         keepalive_loop
84:       end
85:     end

Have we gone to TLS mode?

result:[true] or [false]

[Source]

     # File lib/xmpp4r/connection.rb, line 182
182:     def is_tls?
183:       @tls
184:     end

Start the parser on the previously connected socket

[Source]

     # File lib/xmpp4r/connection.rb, line 118
118:     def start
119:       super(@socket)
120:     end

Do a <starttls/> (will be automatically done by connect if stream peer supports this)

[Source]

     # File lib/xmpp4r/connection.rb, line 125
125:     def starttls
126:       stls = REXML::Element.new('starttls')
127:       stls.add_namespace('urn:ietf:params:xml:ns:xmpp-tls')
128: 
129:       reply = nil
130:       send(stls) { |r|
131:         reply = r
132:         true
133:       }
134:       if reply.name != 'proceed'
135:         raise ServerError.new(reply.first_element('error'))
136:       end
137:       # Don't be interrupted
138:       stop
139: 
140:       begin
141:         error = nil
142: 
143:         # Context/user set-able stuff
144:         ctx = OpenSSL::SSL::SSLContext.new
145:         if @ssl_capath
146:           ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER
147:           ctx.ca_path = @ssl_capath
148:         else
149:           ctx.verify_mode = OpenSSL::SSL::VERIFY_NONE
150:         end
151:         ctx.verify_callback = @ssl_verifycb
152: 
153:         # SSL connection establishing
154:         sslsocket = OpenSSL::SSL::SSLSocket.new(@socket, ctx)
155:         sslsocket.sync_close = true
156:         Jabber::debuglog("TLSv1: OpenSSL handshake in progress")
157:         sslsocket.connect
158: 
159:         # Make REXML believe it's a real socket
160:         class << sslsocket
161:           def kind_of?(o)
162:             o == IO ? true : super
163:           end
164:         end
165: 
166:         # We're done and will use it
167:         @tls = true
168:         @socket = sslsocket
169:       rescue
170:         error = $!
171:       ensure
172:         Jabber::debuglog("TLSv1: restarting parser")
173:         start
174:         accept_features
175:         raise error if error
176:       end
177:     end

Private Instance methods

[Source]

     # File lib/xmpp4r/connection.rb, line 186
186:     def generate_stream_start(to=nil, from=nil, id=nil, xml_lang="en", xmlns="jabber:client", version="1.0")
187:       stream_start_string = "<stream:stream xmlns:stream='http://etherx.jabber.org/streams' "
188:       stream_start_string += "xmlns='#{xmlns}' " unless xmlns.nil?
189:       stream_start_string += "to='#{to}' " unless to.nil?
190:       stream_start_string += "from='#{from}' " unless from.nil?
191:       stream_start_string += "id='#{id}' " unless id.nil?
192:       stream_start_string += "xml:lang='#{xml_lang}' " unless xml_lang.nil?
193:       stream_start_string += "version='#{version}' " unless version.nil?
194:       stream_start_string += ">"
195:       stream_start_string
196:     end

A loop to send "keep alive" data to prevent the Jabber connection from closing for inactivity.

This loop sends a single white-space character if no other data has been sent in the last @keepalive_interval seconds.

[Source]

     # File lib/xmpp4r/connection.rb, line 206
206:     def keepalive_loop
207:       loop do
208:         unless is_connected?
209:           Thread.current.kill
210:         end
211:         difference = @last_send + @keepalive_interval - Time.now
212:         if difference <= 0
213:           send(' ')
214:           sleep @keepalive_interval
215:         else
216:           sleep(difference)
217:         end
218:       end
219:     end

[Validate]