コンパスAPIからAPIを引っ張ってくる時に、以下のエラーが頻出してどツボにハマったので、二度とはまらないように脱出方法をメモ。
OpenSSL::SSL::SSLError (SSL_connect returned=1 errno=0 state=SSLv2/v3 read server hello A: unknown protocol)
エラーコード
require 'net/http'
require 'uri'
require 'json'
$ uri = Addressable::URI.parse("https://connpass.com/api/v1/event/?keyword=#名古屋&ym=201907,201908&count=30&order=5")
$ http = Net::HTTP.new(uri.host, uri.port)
$ http.use_ssl = true
$ http.verify_mode = OpenSSL::SSL::VERIFY_PEER
$ http.open_timeout = 5
$ http.read_timeout = 10
$ response = http.get(uri.request_uri)
実行すると、
OpenSSL::SSL::SSLError (SSL_connect returned=1 errno=0 state=SSLv2/v3 read server hello A: unknown protocol)
というエラーが発生。
色々試す
調べてみると、RubyがSSL証明書を見つけることが出来ないがために、SSL接続によるHTTP通信に失敗しているみたい。
そのため、SSL証明書をダウンロードし、
$ http.ca_file = './cacert.pem'
にて、CA証明書ファイルのパスを指定する。
すると、
require 'net/http'
require 'uri'
require 'json'
$ uri = Addressable::URI.parse("https://connpass.com/api/v1/event/?keyword=#名古屋&ym=201907,201908&count=30&order=5")
$ http = Net::HTTP.new(uri.host, uri.port)
$ http.use_ssl = true
$ http.verify_mode = OpenSSL::SSL::VERIFY_PEER
$ http.ca_file = './cacert.pem'
$ http.open_timeout = 5
$ http.read_timeout = 10
$ response = http.get(uri.request_uri)
↓
OpenSSL::SSL::SSLError (SSL_connect returned=1 errno=0 state=SSLv2/v3 read server hello A: unknown protocol)
なぜ...
解決策
$ http = Net::HTTP.new(uri.host, uri.port) # これを
↓
$ http = Net::HTTP.new(uri.host, uri.inferred_port) # に変換
日本語のURIをパースしたかったため、AddressableというGemを使用していたんですが、Net::HTTP.new(uri.host, uri.port)する際に、portではなくinferred_portと明示させなくてはいけないみたい。
三時間ほどの泥沼から脱出。。。
#参考ソース