I'm trying to write an HTTPS client in Ruby. It will connect to the server using HTTPS, passing an authentication token (obtained through a separate login process) and an SSL client certificate.
I'm doing the following with rest-client:
client = RestClient::Resource.new(url,
:ssl_client_cert => OpenSSL::X509::Certificate.new(File.read('./certificate/client-2048.pem')),
:ssl_client_key => OpenSSL::PKey::RSA.new(File.read('./certificate/client-2048.key'), ''),
:verify_ssl => OpenSSL::SSL::VERIFY_NONE)
# ...
headers = {
'X-Application' => APP_KEY,
'X-Authentication' => @session_token,
'content-type' => 'application/json',
'Accept' => 'application/json'
}
response = client.post(request, headers)
This works, but what I'd like to do is use keep-alive to avoid having to go through the whole process of bringing up the connection each time I want to make a request. The delay involved makes the monitoring application I'm writing much less useful.
However, what I can't seem to find is a Ruby library that offers the following:
There's a pull request languishing for rest-client that should provide it. httparty has persistent_httparty but if it supports SSL Client Certificates, there's no documentation for it.
I could fork rest-client, merge the pull-request which has by now bit-rotted, and use that. But surely I'm missing something here ... is there an existing library that offers what I'm looking for? Or some documentation for httparty which explains SSL Client Certificate use with that library?
Any assistance would be greatly appreciated.
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