Class | Jabber::Connection |
In: |
lib/xmpp4r/connection.rb
|
Parent: | Stream |
The connection class manages the TCP connection to the Jabber server
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 |
Create a new connection to the given host and port, using threaded mode or not.
# 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
# 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.
# 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] |
# File lib/xmpp4r/connection.rb, line 148 148: def is_tls? 149: @tls 150: end
Start the parser on the previously connected socket
# 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)
# 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
# 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