Class: Jabber::Connection

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

The connection class manages the TCP connection to the Jabber server

### Methods

accept_features close! connect is_tls? new start starttls

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

new()

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

accept_features()

[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

close!()

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(host, port)

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

is_tls?()

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()

Start the parser on the previously connected socket

[Source]

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

starttls()

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

[Validate]