Codementor Events

How to automagically use SSL in Ruby Net::HTTP

Published Oct 01, 2020
How to automagically use SSL in Ruby Net::HTTP

Today I'm learning something new about Ruby built-in Net::HTTP library. In one of project, I'm contributing we maintain a legacy application that integrates with a 3rd-party API. The 3rd-part API currently in an upgrade and we try to use the new API. In this new integration we're offered to connect to an endpoint with a non-https API base path, let say http://3rd-party-service.com (not a real service). However, as I usually use https by default I change the base path on my config to be something like https://3rd-party-service.com (notice how I add an s here).

However after we use the https in production we notice a weird bug, the code seems not sending a request to the 3rd-party service at all at least from their HTTP log. Turned out we actually send the data but we get 400 Bad Request. The error is something like

After a few debugging we found out or code looks like this

    def service_request(request_body, url)
      encoded_url = CGI.escape_html(url)
      uri = URI.parse(encoded_url)
      http = Net::HTTP.new(uri.host, uri.port)
      request = Net::HTTP::Post.new(uri.request_uri)
      request.body = request_body.to_json
      request['Content-Type'] = 'application/json'
      http.request(request)
    end

We quickly learn that the Net::HTTP is not checking whether we use https or http, we should tell it manually about the https or http. We need to add the following code

http.use_ssl = true

However, we realized that if we activate the SSL for all requests it will break the current integration. So we decided to automatically detect the secure or insecure protocol by using the following code

http.use_ssl = true if uri.instance_of? URI::HTTPS

So the whole code will look like this

    def service_request(request_body, url)
      encoded_url = CGI.escape_html(url)
      uri = URI.parse(encoded_url)
      http = Net::HTTP.new(uri.host, uri.port)
      http.use_ssl = true if uri.instance_of? URI::HTTPS
      request = Net::HTTP::Post.new(uri.request_uri)
      request.body = request_body.to_json
      request['Content-Type'] = 'application/json'
      http.request(request)
    end

About Me 😄

I'm Abdurrachman and currently, I'm managing a software development agency called Kulkul.tech. We're a web and mobile software development company providing excellent software for business. We're working with companies all over the world from a single-person business to large corporates. We are a solid remote-first firm with a high emphasis on people and clear communication.

We begin each project with understanding the client's business and problem then provide a contextual solution and applicable technology. We make sure that cooperation with us develops the business of our client.

We provide excellent engineers and designers to deliver a complete product from spec gathering, product road mapping, UI/UX design, development, QA, and DevOps.
We're experts in the following technologies:

  • JavaScript and Node.js
  • Python and Django
  • Ruby on Rails,
  • Mobile (iOS and Android) especially Flutter
  • DB: MySQL, PostgreSQL, MongoDB,
  • Frontend: Elm, React, Angular

We working in Codementor too, please reach me in Codementor if you're interested.

Discover and read more posts from Abdurrachman M
get started
post comments2Replies
Bert Bruynooghe
a year ago

Thanks, this saved my day!

Abdurrachman M
a year ago

Glad to hear that!