Общие сведения:
- Руби 1.9.3
- Рельсы 3.2.16
- виндовс 7 х64
Проблема
Я пытаюсь исправить печально известный
SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed
ошибку, включив мои сертификаты в каждый HTTP-запрос, который я выполняю. Для этого делаю обезьянку патчем Net::HTTP#use_ssl=
:
# lib/gem_ext/net_http.rb
require 'open-uri'
require 'net/https'
module Net
class HTTP
alias_method :original_use_ssl=, :use_ssl=
def use_ssl=(flag)
store = OpenSSL::X509::Store.new
store.set_default_paths # Auto-include the system CAs.
Dir[Rails.root + 'config/certificates/*'].each do |cert|
puts "Adding cert: #{cert}"
store.add_cert(OpenSSL::X509::Certificate.new(File.read(cert)))
end
self.cert_store = store
self.verify_mode = OpenSSL::SSL::VERIFY_PEER
self.original_use_ssl = flag
end
end
end
Теперь запросы выполняются с использованием Net::HTTP
, например:
> uri = URI.parse('https://internal-app/secure_url.json?foo=bar')
> Net::HTTP.start(uri.host, uri.port, :read_timeout => 10.minutes, :use_ssl => uri.scheme == 'https') do |http|
> http.request Net::HTTP::Get.new(uri.request_uri)
> end
Adding cert: config/certificates/cert1.cer
Adding cert: config/certificates/cert2.cer
=> #<Net::HTTPOK 200 OK readbody=true>
Работайте идеально.
Однако, когда я пытаюсь использовать OpenURI, который, как я думал, был просто оболочкой для Net::HTTP (и других операций ввода-вывода), например:
> require 'open-uri'
> open('https://our-all/secure_url.json?foo=bar', 'r', :read_timeout => 10.minutes)
Adding cert: config/certificates/cert1.cer
Adding cert: config/certificates/cert2.cer
#<Class:0x870e2e0>: SSL_connect returned=1 errno=0 state=SSLv3 read server certi
from D:/Ruby/Ruby193/lib/ruby/1.9.1/net/http.rb:800:in `connect'
from D:/Ruby/Ruby193/lib/ruby/1.9.1/net/http.rb:800:in `block in connect
Итак, я вижу, что мой исправленный метод обезьяны срабатывает («Добавление сертификата ..»), но все же я получаю сообщение об ошибке. Кажется, что что-то другое перевешивает его. Любые идеи?
Спасибо