HTTP library for Ruby with HTTPS, SSL Client Certificate and Keep-Alive support?

柔情痞子 提交于 2019-11-29 04:34:53
RJHunter

Is there something that already works?

I believe the HTTP client library Faraday is focus of more Ruby community action is these days.

It comes with a :net_http_persistent adapter, which supports SSL client certificates. You can probably do something like this:

ssl_options = {
  cert: OpenSSL::X509::Certificate.new(File.read('./certificate/client-2048.pem')),
  key:  OpenSSL::PKey::RSA.new(File.read('./certificate/client-2048.key'), 'mypassword')
}
conn = Faraday.new(url: 'https://example.com', ssl: ssl_options) do |faraday|
  faraday.adapter = Faraday::Adapter::NetHttpPersistent
end

conn.get '/my-resource'

HTTParty

According to the specs:

... the resulting connection when providing PEM certificates when scheme is https

  • uses the provided PEM certificate
  • will verify the certificate

You can use the pem classmethod to provide a client certificate in PEM format.

REST Client

It's not as dead as all that -- Larry Gilbert (@L2G) is still merging in pull requests and keeping the lights on. He's nodded his general approval in the issue tracker. I suspect it's just not at the top of his priority queue at the moment.

The guy who sent in that pull request, @byroot, has been keeping his code up to date so you shouldn't need to do much at all while you wait.

The Ruby standard library's Net::HTTP API satisfies the requirements you listed: HTTPS support, SSL Client Certificate support and Keep-Alive.

Since Net::HTTP can be instantiated and reused without block semantics, it's also easy to wrap in your own library.

#!/usr/bin/env ruby
#
# https://gist.github.com/sheldonh/4693e2eca35b62b22c55

require 'openssl'
require 'net/http'
require 'json'

class Gist

  DEFAULT_OPTIONS = {
    use_ssl: true,
    verify_mode: OpenSSL::SSL::VERIFY_PEER,
    keep_alive_timeout: 30,
    cert: OpenSSL::X509::Certificate.new(File.read('./client.cert.pem')),
    key: OpenSSL::PKey::RSA.new(File.read('./client.key.pem'))
  }


  def initialize(http = nil)
    if http
      @http = http
    else
      @http = Net::HTTP.start("api.github.com", 443, DEFAULT_OPTIONS)
    end
  end

  def fetch(id, file)
    response = @http.request Net::HTTP::Get.new "/gists/#{id}"
    JSON.parse(response.body)["files"][file]["content"]
  end

end


gist = Gist.new
puts gist.fetch "fc5b5c42ff2e22171f09", "gistfile1.txt"  # Lorem ipsum
puts gist.fetch "4693e2eca35b62b22c55", "gist.rb" # This script
Paulo Fidalgo

Have you tried mechanize?

According to the examples you can pass a client certification like this:

require 'rubygems'
require 'mechanize'

# create Mechanize instance
agent = Mechanize.new

# set the path of the certificate file
agent.cert = 'example.cer'

# set the path of the private key file
agent.key = 'example.key'

# get the login form & fill it out with the username/password
login_form = agent.get("http://example.com/login_page").form('Login')
login_form.Userid = 'TestUser'
login_form.Password = 'TestPassword'

# submit login form
agent.submit(login_form, login_form.buttons.first)

According to this topic, you may need to force mechanize to use SSLV3:

page = Mechanize.new{|a| a.ssl_version, a.verify_mode = 'SSLv3', OpenSSL::SSL::VERIFY_NONE}.get "https://yourHTTPSurl"
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!