Class Jabber::Connection
In: lib/xmpp4r/connection.rb
Parent: Stream
XMPPElement ErrorResponse XMPPStanza X IqQuery Message Presence Iq JabberError ComponentAuthenticationFailure ArgumentError SOCKS5Error ServerError NoNameXmlnsRegistered ClientAuthenticationFailure Connection Client Component Client Singleton IdGenerator Comparable JID StandardError REXML::Element Stream IqQuery IqQueryRoster IqQueryBytestreams IqQueryVersion IqQueryRPC IqQueryMUCOwner IqQueryMUCAdmin IqQueryDiscoItems IqQueryDiscoInfo XRosterItem RosterXItem XMPPElement RosterItem StreamHost IqSiFile IqSiFileRange IqSi StreamHostUsed IqFeature C Body HTML UserItem XMUCUserInvite Configuration Items Item IqPubSub Publish Event IqPubSubOwner Subscription Unsubscribe Tune XDataField XDataReported XDataTitle XDataInstructions Feature Item Identity IqVcard XRoster RosterX X XMUC XMUCUser XDelay XData Iq IqCommand SOCKS5Bytestreams SOCKS5BytestreamsTarget SOCKS5BytestreamsInitiator SOCKS5BytestreamsServerStreamHost TCPSocket SOCKS5Socket IBB IBBTarget IBBInitiator Responder SimpleResponder XMLRPC::ParserWriterChooseMixin Client Server XMLRPC::ParseContentType XMLRPC::BasicServer MUCClient SimpleMUCClient MUC::UserItem XMUCUserItem IqQueryMUCAdminItem XParent SubscriptionConfig NodeConfig OwnerNodeConfig EventItems EventItem ServiceHelper NodeHelper Base Anonymous DigestMD5 Plain PubSub::ServiceHelper Helper FileSource Base Bot CallbackList Callback StreamParser Semaphore Helper Responder SOCKS5BytestreamsPeer SOCKS5BytestreamsServer IBBQueueItem Helper MUCBrowser NodeBrowser Helper Responder 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 lib/xmpp4r/roster/x/roster.rb lib/xmpp4r/roster/helper/roster.rb lib/xmpp4r/roster/iq/roster.rb Roster lib/xmpp4r/command/iq/command.rb lib/xmpp4r/command/helper/responder.rb Command XParent 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/version/helper/responder.rb lib/xmpp4r/version/helper/simpleresponder.rb lib/xmpp4r/version/iq/version.rb Version lib/xmpp4r/feature_negotiation/iq/feature.rb FeatureNegotiation lib/xmpp4r/caps/helper/helper.rb lib/xmpp4r/caps/c.rb Caps lib/xmpp4r/rpc/helper/server.rb lib/xmpp4r/rpc/helper/client.rb lib/xmpp4r/rpc/iq/rpc.rb RPC lib/xmpp4r/xhtml/html.rb XHTML 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/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/sasl.rb SASL lib/xmpp4r/httpbinding/client.rb HTTPBinding lib/xmpp4r/tune/helper/helper.rb lib/xmpp4r/tune/tune.rb UserTune lib/xmpp4r/dataforms/x/data.rb Dataforms lib/xmpp4r/bytestreams/helper/filetransfer.rb TransferSource FileTransfer lib/xmpp4r/discovery/iq/discoinfo.rb lib/xmpp4r/discovery/helper/responder.rb lib/xmpp4r/discovery/iq/discoitems.rb Discovery 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_99_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 95
 95:     def accept_features
 96:       begin
 97:         Timeout::timeout(@features_timeout) {
 98:           Jabber::debuglog("FEATURES: waiting...")
 99:           @features_sem.wait
100:           Jabber::debuglog("FEATURES: waiting finished")
101:         }
102:       rescue Timeout::Error
103:         Jabber::debuglog("FEATURES: timed out when waiting, stream peer seems not XMPP compliant")
104:       end
105: 
106:       if @allow_tls and not is_tls? and @stream_features['starttls'] == 'urn:ietf:params:xml:ns:xmpp-tls'
107:         begin
108:           starttls
109:         rescue
110:           Jabber::debuglog("STARTTLS:\nFailure: #{$!}")
111:         end
112:       end
113:     end

Closing connection: first kill keepaliveThread, then call Stream#close!

[Source]

    # File lib/xmpp4r/connection.rb, line 90
90:     def close!
91:       @keepaliveThread.kill if @keepaliveThread and @keepaliveThread.alive?
92:       super
93:     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 181
181:     def is_tls?
182:       @tls
183:     end

Start the parser on the previously connected socket

[Source]

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

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

[Source]

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

Private Instance methods

[Source]

     # File lib/xmpp4r/connection.rb, line 185
185:     def generate_stream_start(to=nil, from=nil, id=nil, xml_lang="en", xmlns="jabber:client", version="1.0")
186:       stream_start_string = "<stream:stream xmlns:stream='http://etherx.jabber.org/streams' "
187:       stream_start_string += "xmlns='#{xmlns}' " unless xmlns.nil?
188:       stream_start_string += "to='#{to}' " unless to.nil?
189:       stream_start_string += "from='#{from}' " unless from.nil?
190:       stream_start_string += "id='#{id}' " unless id.nil?
191:       stream_start_string += "xml:lang='#{xml_lang}' " unless xml_lang.nil?
192:       stream_start_string += "version='#{version}' " unless version.nil?
193:       stream_start_string += ">"
194:       stream_start_string
195:     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 205
205:     def keepalive_loop
206:       loop do
207:         difference = @last_send + @keepalive_interval - Time.now
208:         if difference <= 0
209:           send(' ')
210:           sleep @keepalive_interval
211:         else
212:           sleep(difference)
213:         end
214:       end
215:     end

[Validate]