Class Jabber::Connection
In: lib/xmpp4r/connection.rb
Parent: Stream
Message Presence XMPPStanza Iq Singleton IdGenerator XMPPElement X IqQuery Error Connection Client Component Client Comparable JID RuntimeError AuthenticationFailure ErrorException NoNameXmlnsRegistered SOCKS5Error REXML::Element Stream SOCKS5Bytestreams SOCKS5BytestreamsTarget SOCKS5BytestreamsInitiator XMPPElement StreamHost IqSiFileRange IqSiFile StreamHostUsed IqSi XRosterItem RosterItem IqFeature XMUCUserItem XMUCUserInvite IqPubSub Items Item Event Feature Item Identity XDataField XDataReported XDataTitle XDataInstructions IqVcard SOCKS5BytestreamsServerStreamHost TCPSocket SOCKS5Socket IqQuery IqQueryBytestreams IqQueryVersion IqQueryRoster IqQueryMUCOwner IqQueryRPC IqQueryDiscoItems IqQueryDiscoInfo IBB IBBTarget IBBInitiator Responder SimpleResponder Iq IqCommand RosterXItem XRoster RosterX X XMUCUser XMUC XDelay XData XParent MUCClient SimpleMUCClient XMLRPC::ParserWriterChooseMixin Client Server XMLRPC::ParseContentType XMLRPC::BasicServer Base DigestMD5 Plain ServiceHelper NodeHelper FileSource CallbackList Callback Semaphore StreamParser SOCKS5BytestreamsPeer SOCKS5BytestreamsServer IBBQueueItem Responder Helper MUCBrowser NodeBrowser Helper Helper lib/xmpp4r/authenticationfailure.rb lib/xmpp4r/xmppstanza.rb lib/xmpp4r/callbacks.rb lib/xmpp4r/idgenerator.rb lib/xmpp4r/connection.rb lib/xmpp4r/iq.rb lib/xmpp4r/jid.rb lib/xmpp4r/errorexception.rb lib/xmpp4r/client.rb lib/xmpp4r/stream.rb lib/xmpp4r/semaphore.rb lib/xmpp4r/streamparser.rb lib/xmpp4r/x.rb lib/xmpp4r/error.rb lib/xmpp4r/component.rb lib/xmpp4r/query.rb lib/xmpp4r/xmppelement.rb lib/xmpp4r/message.rb lib/xmpp4r/presence.rb lib/xmpp4r/bytestreams/helper/ibb/initiator.rb lib/xmpp4r/bytestreams/iq/si.rb lib/xmpp4r/bytestreams/iq/bytestreams.rb lib/xmpp4r/bytestreams/helper/socks5bytestreams/base.rb lib/xmpp4r/bytestreams/helper/socks5bytestreams/server.rb lib/xmpp4r/bytestreams/helper/socks5bytestreams/target.rb lib/xmpp4r/bytestreams/helper/socks5bytestreams/socks5.rb lib/xmpp4r/bytestreams/helper/socks5bytestreams/initiator.rb lib/xmpp4r/bytestreams/helper/ibb/base.rb lib/xmpp4r/bytestreams/helper/ibb/target.rb Bytestreams XParent lib/xmpp4r/version/iq/version.rb lib/xmpp4r/version/helper/responder.rb lib/xmpp4r/version/helper/simpleresponder.rb Version lib/xmpp4r/command/iq/command.rb lib/xmpp4r/command/helper/responder.rb Command lib/xmpp4r/roster/helper/roster.rb lib/xmpp4r/roster/iq/roster.rb lib/xmpp4r/roster/x/roster.rb Roster lib/xmpp4r/feature_negotiation/iq/feature.rb FeatureNegotiation lib/xmpp4r/muc/x/muc.rb lib/xmpp4r/muc/helper/mucclient.rb lib/xmpp4r/muc/x/mucuseritem.rb lib/xmpp4r/muc/helper/mucbrowser.rb lib/xmpp4r/muc/x/mucuserinvite.rb lib/xmpp4r/muc/iq/mucowner.rb lib/xmpp4r/muc/helper/simplemucclient.rb MUC lib/xmpp4r/rpc/helper/server.rb lib/xmpp4r/rpc/helper/client.rb lib/xmpp4r/rpc/iq/rpc.rb RPC lib/xmpp4r/sasl.rb SASL lib/xmpp4r/delay/x/delay.rb Delay lib/xmpp4r/pubsub/helper/servicehelper.rb lib/xmpp4r/pubsub/stanzas/item.rb lib/xmpp4r/pubsub/helper/nodehelper.rb lib/xmpp4r/pubsub/iq/pubsub.rb lib/xmpp4r/pubsub/stanzas/event.rb lib/xmpp4r/pubsub/helper/nodebrowser.rb lib/xmpp4r/pubsub/stanzas/items.rb PubSub lib/xmpp4r/httpbinding/client.rb HTTPBinding lib/xmpp4r/bytestreams/helper/filetransfer.rb TransferSource FileTransfer lib/xmpp4r/discovery/iq/discoinfo.rb lib/xmpp4r/discovery/iq/discoitems.rb Discovery lib/xmpp4r/dataforms/x/data.rb Dataforms lib/xmpp4r/vcard/helper/vcard.rb lib/xmpp4r/vcard/iq/vcard.rb Vcard Jabber dot/m_79_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

Public Class methods

Create a new connection to the given host and port, using threaded mode or not.

[Source]

    # File lib/xmpp4r/connection.rb, line 36
36:     def initialize(threaded = true)
37:       super(threaded)
38:       @host = nil
39:       @port = nil
40:       @allow_tls = true
41:       @tls = false
42:       @ssl_capath = nil
43:       @ssl_verifycb = nil
44:       @features_timeout = 10
45:       @keepalive_interval = 60
46:     end

Public Instance methods

[Source]

    # File lib/xmpp4r/connection.rb, line 79
79:     def accept_features
80:       begin
81:         Timeout::timeout(@features_timeout) {
82:           Jabber::debuglog("FEATURES: waiting...")
83:           @features_sem.wait
84:           Jabber::debuglog("FEATURES: waiting finished")
85:         }
86:       rescue Timeout::Error
87:         Jabber::debuglog("FEATURES: timed out when waiting, stream peer seems not XMPP compliant")
88:       end
89: 
90:       if @allow_tls and not is_tls? and @stream_features['starttls'] == 'urn:ietf:params:xml:ns:xmpp-tls'
91:         begin
92:           starttls
93:         rescue
94:           Jabber::debuglog("STARTTLS:\nFailure: #{$!}")
95:         end
96:       end
97:     end

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

[Source]

    # File lib/xmpp4r/connection.rb, line 74
74:     def close!
75:       @keepaliveThread.kill if @keepaliveThread and @keepaliveThread.alive?
76:       super
77:     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 53
53:     def connect(host, port)
54:       @host = host
55:       @port = port
56:       # Reset is_tls?, so that it works when reconnecting
57:       @tls = false
58: 
59:       Jabber::debuglog("CONNECTING:\n#{@host}:#{@port}")
60:       @socket = TCPSocket.new(@host, @port)
61:       start
62: 
63:       accept_features
64: 
65:       @keepaliveThread = Thread.new do
66:         Thread.current.abort_on_exception = true
67:         keepalive_loop
68:       end
69:     end

Have we gone to TLS mode?

result:[true] or [false]

[Source]

     # File lib/xmpp4r/connection.rb, line 165
165:     def is_tls?
166:       @tls
167:     end

Start the parser on the previously connected socket

[Source]

     # File lib/xmpp4r/connection.rb, line 101
101:     def start
102:       super(@socket)
103:     end

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

[Source]

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

Private Instance methods

[Source]

     # File lib/xmpp4r/connection.rb, line 169
169:     def generate_stream_start(to=nil, from=nil, id=nil, xml_lang="en", xmlns="jabber:client", version="1.0")
170:       stream_start_string = "<stream:stream xmlns:stream='http://etherx.jabber.org/streams' "
171:       stream_start_string += "xmlns='#{xmlns}' " unless xmlns.nil?
172:       stream_start_string += "to='#{to}' " unless to.nil?
173:       stream_start_string += "from='#{from}' " unless from.nil?
174:       stream_start_string += "id='#{id}' " unless id.nil?
175:       stream_start_string += "xml:lang='#{xml_lang}' " unless xml_lang.nil?
176:       stream_start_string += "version='#{version}' " unless version.nil?
177:       stream_start_string += ">"
178:       stream_start_string
179:     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 189
189:     def keepalive_loop
190:       loop do
191:         difference = @last_send + @keepalive_interval - Time.now
192:         if difference <= 0
193:           send(' ')
194:           sleep @keepalive_interval
195:         else
196:           sleep(difference)
197:         end
198:       end
199:     end

[Validate]