Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making an API call over SSL in Ruby

I have a method that works just fine for calls to non-ssl apis, but it gives me the following error response whenever I request https-only apis:

757: unexpected token at '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
Reason: You're speaking plain HTTP to an SSL-enabled server port.<br />
 Instead use the HTTPS scheme to access this URL, please.<br />
</p>
</body></html>

The method is fairly straightforward:

def my_service_api_call(path = nil, query = nil)
  my_service_api_key = ENV["MY_SERVICE_KEY"]
  api_path = "#{path}/?api_key=#{my_service_api_key}&#{query}"
  url = URI.parse(api_path)
  req = Net::HTTP::Get.new(api_path)
  res = Net::HTTP.start(url.host, url.port) { |http| http.request(req) }
  JSON.parse(res.body)["results"]
end

This works great over http but fails over https-only. Is there an equivalent way to do HTTPS requests?

like image 931
Tyler Avatar asked Apr 23 '26 06:04

Tyler


2 Answers

There's a more elegant way to reuse your instance of Net::HTTP and enable requests over HTTPS:

http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE # Sets the HTTPS verify mode
@data = http.get(uri.request_uri) 

Notice the use of use_ssl. From the documentation:

Turn on/off SSL. This flag must be set before starting session. If you change use_ssl value after session started, a Net::HTTP object raises IOError.

Note also that the usage of VERIFY_NONE is controversial, since it doesn't force the validity of of certificates to be checked. For many applications and users, this will not bear any negative ramifications. In cases where certificate validity should be checked, this post suggests the following:

Securely transfer the correct certificate and update the default certificate store or set the ca file instead.

like image 80
zeantsoi Avatar answered Apr 24 '26 18:04

zeantsoi


You need to set use_ssl to true:

like this:

        http = Net::HTTP.new(uri.hostname, uri.port)
        http.use_ssl = true
        http.verify_mode = OpenSSL::SSL::VERIFY_NONE
        http.ssl_version = :SSLv3
like image 42
bjhaid Avatar answered Apr 24 '26 18:04

bjhaid



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!