在Ruby

时间:2017-02-09 17:03:32

标签: ruby ssl

我有一个发出http请求的服务,它看起来像这样:

require 'net/http'

class SenderNameService
  def get_names(id)
    domain = "http://www.somedomain.com"
    path = "/api/orchards/users/#{id}"
    url = URI.parse(domain + path)

    req = Net::HTTP::Get.new(url.to_s)
    token = generate_token
    req.add_field("Authorization", token)

    http = Net::HTTP.new(url.host, url.port)
    http.use_ssl = true
    res = http.start do |http|
      http.request(req)
    end

    if res.code == '200'
      return JSON.parse(res.body)
    else
      raise StandardError, "Request for sender names failed"
    end
  end

  private

  def generate_token
    #Some JWT token generating logic goes here.
  end
end

当我提出请求时,我收到此错误:

OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv2/v3 read server hello A: unknown protocol
from .rbenv/versions/2.3.3/lib/ruby/2.3.0/net/http.rb:933:in `connect_nonblock'

发生了什么事?这个错误意味着什么?

更新:当我将http更改为https时,错误会得到修复。发生了什么事?

2 个答案:

答案 0 :(得分:2)

http.use_ssl = true
     

更新:当我将http更改为https时,错误得到修复。发生了什么事?

默认情况下,http URL使用端口80,通常只有一个服务器只能说HTTP。而https URL则使用端口443,其中说服HTTPS的服务器所在的位置。但是,您尝试在没有支持TLS的服务器侦听的http端口上强制执行HTTPS(即TLS + HTTP)。这意味着您的客户端启动与此服务器的TLS握手,但不会获得TLS响应,而是获得HTTP响应。尝试将响应解释为TLS会导致您看到的错误,即未知协议。

答案 1 :(得分:0)

该版本的Ruby使用http.rb中的connect_nonblock进行连接,该连接请求连接到给定套接字。套接字必须有一个地址和一个端口,所以它可能失败了,因为它试图通过端口443( http.use_ssl = true )连接到https地址,所以你应该使用https代替http(需要实现服务器端SSL)或将http.use_ssl设置为 false 。请参阅:http://apidock.com/ruby/Socket/connect_nonblock