I’m trying to connect to the server https://www.xpiron.com/schedule in a ruby script. However, when I try connecting:
require 'open-uri'
doc = open('https://www.xpiron.com/schedule')
I get the following error message:
OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv2/v3 read server hello A: sslv3 alert unexpected message
from /usr/local/lib/ruby/1.9.1/net/http.rb:678:in `connect'
from /usr/local/lib/ruby/1.9.1/net/http.rb:678:in `block in connect'
from /usr/local/lib/ruby/1.9.1/timeout.rb:44:in `timeout'
from /usr/local/lib/ruby/1.9.1/timeout.rb:87:in `timeout'
from /usr/local/lib/ruby/1.9.1/net/http.rb:678:in `connect'
from /usr/local/lib/ruby/1.9.1/net/http.rb:637:in `do_start'
from /usr/local/lib/ruby/1.9.1/net/http.rb:626:in `start'
from /usr/local/lib/ruby/1.9.1/net/http.rb:1168:in `request'
from /usr/local/lib/ruby/1.9.1/net/http.rb:888:in `get'
from (irb):32
from /usr/local/bin/irb:12:in `<main>'
I’m running Ruby 1.9.2p180. It seems to work on some other machines, so it could be a configuration problem with OpenSSL or Ruby. I tried reinstalling all the SSL libraries, and rebuilding Ruby from scratch, but nothing seems to work. Has anyone encountered this problem?
Update
On the non-working machine, the openssl version is 0.9.8o 01 Jun 2010
On the working machine, it’s 0.9.8k 25 Mar 2009
So the more recent one seems to be breaking.
Furthermore, if I use a different HTTP client (Patron, based on libcurl), it works:
require 'patron'
sess = Patron::Session.new
sess.timeout = 5
url = 'https://www.xpiron.com/schedule'
resp = sess.get(url)
puts "#{resp.body}"
So this appears to be an issue with Ruby’s OpenSSL bindings.
Just to answer my own question.
The problem seems to be with how Ruby negotiates SSL connections. There’s an error in Xpiron’s TLS mechanism, and it throws an error instead of retrying to other SSL versions.
If you force the SSL version to 3.0, it works:
I also created an issue on Ruby’s bug tracker.