| 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