Class Jabber::Connection
In: lib/xmpp4r/connection.rb
Parent: Stream

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] 
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 32
32:     def initialize(threaded = true)
33:       super(threaded)
34:       @host = nil
35:       @port = nil
36:       @allow_tls = true
37:       @tls = false
38:       @ssl_capath = nil
39:       @ssl_verifycb = nil
40:       @features_timeout = 10
41:     end

Public Instance methods

[Source]

    # File lib/xmpp4r/connection.rb, line 59
59:     def accept_features
60:       begin
61:         Timeout::timeout(@features_timeout) {
62:           Jabber::debuglog("FEATURES: waiting...")
63:           @features_lock.lock
64:           @features_lock.unlock
65:           Jabber::debuglog("FEATURES: waiting finished")
66:         }
67:       rescue Timeout::Error
68:         Jabber::debuglog("FEATURES: timed out when waiting, stream peer seems not XMPP compliant")
69:       end
70: 
71:       if @allow_tls and not is_tls? and @stream_features['starttls'] == 'urn:ietf:params:xml:ns:xmpp-tls'
72:         begin
73:           starttls
74:         rescue
75:           Jabber::debuglog("STARTTLS:\nFailure: #{$!}")
76:         end
77:       end
78:     end

Connects to the Jabber server through a TCP Socket and starts the Jabber parser.

[Source]

    # File lib/xmpp4r/connection.rb, line 46
46:     def connect(host, port)
47:       @host = host
48:       @port = port
49:       # Reset is_tls?, so that it works when reconnecting
50:       @tls = false
51: 
52:       Jabber::debuglog("CONNECTING:\n#{@host}:#{@port}")
53:       @socket = TCPSocket.new(@host, @port)
54:       start
55: 
56:       accept_features
57:     end

Have we gone to TLS mode?

result:[true] or [false]

[Source]

     # File lib/xmpp4r/connection.rb, line 148
148:     def is_tls?
149:       @tls
150:     end

Start the parser on the previously connected socket

[Source]

    # File lib/xmpp4r/connection.rb, line 82
82:     def start
83:       @features_lock.lock
84: 
85:       super(@socket)
86:     end

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

[Source]

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

Private Instance methods

[Source]

     # File lib/xmpp4r/connection.rb, line 152
152:     def generate_stream_start(to=nil, from=nil, id=nil, xml_lang="en", xmlns="jabber:client", version="1.0")
153:       stream_start_string = "<stream:stream xmlns:stream='http://etherx.jabber.org/streams' "
154:       stream_start_string += "xmlns='#{xmlns}' " unless xmlns.nil?
155:       stream_start_string += "to='#{to}' " unless to.nil?
156:       stream_start_string += "from='#{from}' " unless from.nil?
157:       stream_start_string += "id='#{id}' " unless id.nil?      
158:       stream_start_string += "xml:lang='#{xml_lang}' " unless xml_lang.nil?
159:       stream_start_string += "version='#{version}' " unless version.nil?
160:       stream_start_string += ">"
161:       stream_start_string
162:     end

[Validate]