Ruby SSL_read: tlsv1 警报协议版本

Ruby SSL_read: tlsv1 alert protocol version

我正在编写一个简单的 ssl web 客户端,它在不添加 ssl 支持的情况下运行良好。现在我已经添加了 ssl 功能来获取请求,我收到了这个错误消息:

SSL_read: tlsv1 alert protocol version

google了一下,我得出的结论是检查openssl版本,我可以看到它支持TLSv1.2。我什至创建了一个上下文来显式强制 tlsv1.2 但仍然是相同的错误消息。我的 openssl 版本:

ruby -ropenssl -e 'puts OpenSSL::OPENSSL_VERSION' ===> OpenSSL 1.0.1f 6 Jan 2014

我的代码:

    require 'socket'
    require 'openssl'

    puts "Please select:"
    puts "get ==> to use GET method"
    puts "post ==> to use POST method"
    method = gets.chomp.downcase

    case method
    when "get"
      print "Please enter the domain name to get the http: "
      domain = "www." << gets.chomp
      print "Now enter the page you want to get: "
      page = gets.chomp

      # opening socket
      soc = TCPSocket.new domain, 443
      ctx = OpenSSL::SSL::SSLContext.new
      ctx.ssl_version = :TLSv1_2
      ssl = OpenSSL::SSL::SSLSocket.new(soc, ctx)
      ssl.sync_close = true
      ssl.connect
      soc.puts "GET #{page} HTTP/1.1\nHost: #{domain}\n\n\n"
      while line = ssl.gets
        puts line
      end
    when "post"
      print "Please enter the domain name to post the http:"
      domain = gets.chomp.downcase
      print "Now enter the post form page:"
      form_page = gets.chomp.downcase
      puts "Please enter the parameters of POST and related values one at a time:"
      puts "(\"done\" to end input)"
      post_variable = []
      while true
        print "Parameter:"
        parameter = gets.chomp.downcase
        break if parameter == "done"
        print "Value:"
        value = gets.chomp.downcase
        break if  value == "done"
        post_variable.push("#{parameter}=#{value}")
        post_sentense = post_variable.join("&")
      end
      # opening socket
      soc = TCPSocket.new domain, 80
      soc.puts "POST #{form_page} HTTP/1.1\nHost: #{domain}\nContent-Length: #{post_sentense.length}\n\n\n#{post_variable}"
      while line = soc.gets
        puts line
      end
    else
      puts "wrong input!!!"
    end

我要提一下,输入的域名应该没有www,页面通常是/index.html。 有人可以帮我解决这个问题吗???

我发现了问题。这一行:

soc.puts "GET #{page} HTTP/1.1\nHost: #{domain}\n\n\n"

应该是这样的:

ssl.puts "GET #{page} HTTP/1.1\nHost: #{domain}\n\n\n"

我不完全知道为什么,但我认为通过将消息发送到套接字而不是 ssl,它参与了 ssl 协商并且没有让协商完成该过程。