How to invoke HTTP POST method over SSL in ruby? How to invoke HTTP POST method over SSL in ruby? ruby ruby

How to invoke HTTP POST method over SSL in ruby?


You are close, but not quite there. Try something like this instead:

uri = URI.parse("https://auth.api.rackspacecloud.com")http = Net::HTTP.new(uri.host, uri.port)http.use_ssl = truehttp.verify_mode = OpenSSL::SSL::VERIFY_NONErequest = Net::HTTP::Post.new("/v1.1/auth")request.add_field('Content-Type', 'application/json')request.body = {'credentials' => {'username' => 'username', 'key' => 'key'}}.to_jsonresponse = http.request(request)

This will set the Content-Type header as well as post the JSON in the body, rather than in the form data as your code had it. With the sample credentials, it still fails, but I suspect it should work with real data in there.


There's a very good explanation of how to make a JSON POST request with Net::HTTP at this link.

I would recommend using a library like HTTParty. It's well-documented, you can just set up your class like so:

class RackSpaceClient  include HTTParty  base_uri "https://auth.api.rackspacecloud.com/"  format :json  headers 'Accept' => 'application/json'  #methods to do whateverend

It looks like the main difference between the Ruby code you placed there, and the curl request, is that the curl request is POSTing JSON (content-type application/json) to the endpoint, whereas request.set_form_data is going to send a form in the body of the POST request (content-type application/x-www-form-urlencoded). You have to make sure the content going both ways is of type application/json.


All others are too long here is a ONE LINER:

Net::HTTP.start('auth.api.rackspacecloud.com', :use_ssl => true).post(      '/v1.1/auth', {:credentials => {:username => "username",:key => "key"}}.to_json,      initheader={'Content-Type' => 'application/json'}    )

* to_json needs require 'json'


OR if you want to

  • NOT verify the hosts
  • be more readable
  • ensure the connection is closed once you're done

then:

ssl_opts={:use_ssl => true, :verify_mode => OpenSSL::SSL::VERIFY_NONE}Net::HTTP.start('auth.api.rackspacecloud.com', ssl_opts) { |secure_connection|  secure_connection.post(      '/v1.1/auth', {:credentials => {:username => "username",:key => "key"}}.to_json,      initheader={'Content-Type' => 'application/json'}    )}

In case it's tough to remember what params go where:

  • SSL options are per connection so you specify them while opening the connection.
  • You can reuse the connection for multiple REST calls to same base url. Think of thread safety of course.
  • Header is a "request header" and hence specified per request. I.e. in calls to get/post/patch/....
  • HTTP.start(): Creates a new Net::HTTP object, then additionally opens the TCP connection and HTTP session.
  • HTTP.new(): Creates a new Net::HTTP object without opening a TCP connection or HTTP session.