Search code examples
rubyconnection-timeoutnet-httpruby-1.8.7

Net::HTTP not sending request


I have the following method in our Ruby 1.8.7 project:

def self.ping_server
  request_data = get_request_data

  uri = 'another_server.our_company.com'
  https = Net::HTTP.new(uri)
  https.use_ssl = true
  path = "/our_service"
  data = request_data.to_json
  response = https.post(path, data, {'Content-Type' => 'application/json'})

  return response
end

Whenever I run this method, I get the following time out error:

Completed 500 Internal Server Error in 128936ms

Errno::ETIMEDOUT (Connection timed out - connect(2)):
  lib/my_class.rb:51:in `ping_our_server'

I checked with a coworker who has access to the logs for another_server.our_company.com. My request isn't arriving at the other server.

What should I do to get my request to work?


EDIT: On further inspection, this is what I think is happening (but I'm not completely sure): Our other server will only accept HTTPS requests, but it looks like my request is being sent over HTTP for some reason. Is there something I need to add to make sure my request is sent over HTTPS?


Solution

  • According to this website, this is how you send an HTTPS request:

    require "net/https"
    require "uri"
    
    uri = URI.parse("https://secure.com/")
    http = Net::HTTP.new(uri.host, uri.port)
    http.use_ssl = true
    http.verify_mode = OpenSSL::SSL::VERIFY_NONE
    
    request = Net::HTTP::Get.new(uri.request_uri)
    
    response = http.request(request)
    response.body
    response.status
    response["header-here"] # All headers are lowercase
    

    According to this website (which is linked from my first link), you should also do this to close up a vulnerability in the net/https library:

    To get going, you need a local CA certificates bundle, the official curl site maintains an up to date cacert.pem / ca-bundle.crt file containing all of the major certificates if you need one.

    Next, after a gem install always_verify_ssl_certificates, you can be up and running with a test as simply as:

    require 'always_verify_ssl_certificates'
    AlwaysVerifySSLCertificates.ca_file = "/path/path/path/cacert.pem"
    
    http= Net::HTTP.new('https://some.ssl.site', 443)
    http.use_ssl = true
    req = Net::HTTP::Get.new('/')
    response = http.request(req)
    

    If the site has a bad certificate an error will be raised at this point. If not, a legitimate HTTP response object will be returned.