Curl get request in Ruby - ruby

Would be very grateful if someone could help me convert this curl request into ruby?I have Been trying for a while and can't get the syntax correct.
curl -v -H "Content-Type: application/json" -H "X-Knack-Application-Id:000000" -H "X-Knack-REST-API-Key:000000" https://api.knackhq.com/v1/objects/object_6/records
tried:
uri = URI('https://api.knackhq.com/v1/objects/object_1/records')
Net::HTTP.start(uri.host, uri.port,
:use_ssl => uri.scheme == 'https') do |http|
request = Net::HTTP::Post.new uri
# API details of Knack
request["X-Knack-Application-Id"] = '56e72cd003219158'
request["X-Knack-REST-API-Key"] = 'd9c343d2-2a4b-291e0712a63a'
end

There are at least two issues.
First, in the cURL command you don't specify a method, hence by default it is a GET, but you use POST in Ruby.
Secondly, you are missing the part where you execute the HTTP request
http.request(request)
Here's the code:
uri = URI('https://api.knackhq.com/v1/objects/object_1/records')
req = Net::HTTP::Get.new(uri)
req["X-Knack-Application-Id"] = '56e72cd003219158'
req["X-Knack-REST-API-Key"] = 'd9c343d2-2a4b-291e0712a63a'
res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
http.request(req)
end
More examples are available in the Net::HTTP documentation.

Did you try some gems? I often use RestClient for api reqests, here is my example:
RestClient.post("https://api.knackhq.com/v1/objects/object_6/records", {}, {"X-Knack-REST-API-Key" => "000000", "X-Knack-Application-Id"=>"000000"})
More information about: https://github.com/rest-client/rest-client

Related

How to use httparty instead of net/http or curl

I have a curl request which works
curl -X GET -k 'https://APIADDRESSHERE' -u 'USERNAME:PASSWORD' -H 'Content-Type: application/json'
I can also get this working in ruby:
require 'net/http'
require 'uri'
require 'openssl'
uri = URI.parse("https://APIADDRESSHERE")
request = Net::HTTP::Get.new(uri)
request.basic_auth("USERNAME", "PASSWORD")
request.content_type = "application/json"
req_options = {
use_ssl: uri.scheme == "https",
verify_mode: OpenSSL::SSL::VERIFY_NONE,
}
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
http.request(request)
end
However when I try this with httparty I keep getting a 401 error saying:
An Authentication object was not found in the SecurityContext This request requires HTTP authentication.
I have tried a lot of variations of the following but I'm stuck.
response = HTTParty.get('https://APIURLHERE', {"headers": { "Authorization:" => "BASE64ENCODEDUSERNAMEANDPASSWORD", "Content-Type" => "application/json" }})
Have you tried the following?
response = HTTParty.get('https://APIURLHERE', headers: { "Authorization:" => "BASE64ENCODEDUSERNAMEANDPASSWORD", "Content-Type" => "application/json" })
Ok I made a simple mistake somewhere along the way because the original solution from the similar post worked... Dont know how it didnt work 50 times last time I was working on this but it was clearly an error on my part somewhere.

Net https requests gives me what appears to be hex

In ruby, I'm doing an HTTP GET request to a website that uses SSL, and for some reason it only gives me the data I need when proxying it through an HTTP proxy (burp suite).
For example:
if uri.port == 443
response = Net::HTTP.start(uri.host, uri.port, "172.16.38.182", "8080", :use_ssl => true, :verify_mode => OpenSSL::SSL::VERIFY_NONE) {|http|
http.request(request)
}
else
response = Net::HTTP.start(uri.host, uri.port) {|http|
http.request(request)
}
end
by proxying this through BurpSuite, I can see the data that I need. But if I try this below:
if uri.port == 443
response = Net::HTTP.start(uri.host, uri.port, :use_ssl => true, :verify_mode => OpenSSL::SSL::VERIFY_NONE) {|http|
http.request(request)
}
else
response = Net::HTTP.start(uri.host, uri.port) {|http|
http.request(request)
}
end
then I get hex characters that looks like this:
Any idea why this would be the case? Is it because of the specific SSL/TLS version used or something and the web application proxy knows how to interact with it but net/https doesn't? can't figure this out.
Turns out the reason this looks the way it does is because it's returned with gzip encoding.
I was able to successfully decode it by using the following:
if response['content-encoding'] == 'gzip'
gz = Zlib::GzipReader.new(StringIO.new(response.body.to_s))
uncompressed_string = gz.read
end

How to convert curl to Ruby Net::HTTP with -X GET -G options?

I was using https://jhawthorn.github.io/curl-to-ruby/ to convert curl commands to Net::HTTP code. However the following cannot be converted using the jhawthorn resource:
curl -H "Content-type: application/json" -H "Authorization: Token token=$PAGERDUTY_ACCESS_KEY" -X GET -G --data-urlencode "since=2017-01-16" --data-urlencode "until=2017-01-17" "https://company.pagerduty.com/api/v1/schedules"
I have described my exact problem in this github issue: https://github.com/jhawthorn/curl-to-ruby/issues/8
This is my current function that uses the Net::HTTP gem:
#!/usr/bin/env ruby
require 'json'
require 'net/http'
require 'uri'
def get_pagerduty_hash(ending='')
uri = URI.parse("https://company.pagerduty.com/api/v1/schedules#{ending}")
request = Net::HTTP::Get.new(uri)
request.content_type = "application/json"
request["Authorization"] = "Token token=#{ENV['PAGERDUTY_ACCESS_KEY']}"
req_options = {
use_ssl: uri.scheme == "https",
}
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
http.request(request)
end
return JSON.parse(response.body).to_hash
end
How can I change this to correctly use the date part of the original curl command:
-X GET -G --data-urlencode "since=2017-01-16" --data-urlencode "until=2017-01-17"
You have to use the URI.encode_www_form function:
#!/usr/bin/env ruby
require 'json'
require 'net/http'
require 'uri'
def get_pagerduty_hash(ending='')
uri = URI.parse("https://company.pagerduty.com/api/v1/schedules#{ending}")
params = { :since => '2017-01-16', :until => '2017-01-17' }
uri.query = URI.encode_www_form(params)
request = Net::HTTP::Get.new(uri)
request.content_type = "application/json"
request["Authorization"] = "Token token=#{ENV['PAGERDUTY_ACCESS_KEY']}"
req_options = {
use_ssl: uri.scheme == "https",
}
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
http.request(request)
end
return JSON.parse(response.body).to_hash
end
urlencode means that the data is encoded in the URL
url = URI.parse('http://example.com')
url.query = "since=2017-01-16&until=2017-01-17"
puts url
# => http://example.com?since=2017-01-16&until=2017-01-17

How to turn curl request with user and password into ruby NET::HTTP for https site?

I have a ruby script that I'm using to get info from a web page and update the page. I am getting some json info from the web page with:
`curl -s -u #{username}:#{password} #{HTTPS_PAGE_URL}`
And then I am updating the page with:
`curl -s -u #{username}:#{password} -X PUT -H 'Content-Type: application/json' -d'#{new_page_json_info}' #{HTTPS_PAGE_URL}`
I want to use Net::HTTP to do this instead. How can I do this?
For reference here is the confluence doc that I used to create the curl command in the first place: https://developer.atlassian.com/confdev/confluence-server-rest-api/confluence-rest-api-examples
can try doing something like:
uri = URI.parse("http://google.com/")
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Get.new(uri.request_uri)
request.basic_auth("username", "password")
Thank you http://jhawthorn.github.io/curl-to-ruby
That solved it. All you have to do is give that website your curl command and it will convert it into a ruby script.
For the first curl (this gets the json info from a page and sends it to stdout):
#!/usr/bin/env ruby
require 'net/http'
require 'uri'
uri = URI.parse("https://my.page.io/rest/api/content/")
request = Net::HTTP::Get.new(uri)
request.basic_auth("username", "password")
req_options = {
use_ssl: uri.scheme == "https",
}
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
http.request(request)
end
# response.code
puts JSON.parse(response.body).to_hash
For the second (this updates the json info on a page):
#!/usr/bin/env ruby
require 'net/http'
require 'uri'
require 'json'
uri = URI.parse("https://my.page.io/rest/api/content/")
request = Net::HTTP::Put.new(uri)
request.basic_auth("username", "password")
request.content_type = "application/json"
request.body = "{Test:blah}"
req_options = {
use_ssl: uri.scheme == "https",
}
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
http.request(request)
end

Ruby API (RabbitMQ create user)

Started working on Ruby a week back. Writing an API to connect to RabbitMQ messaging queue. The command line for adding a new user works.
$ curl -i -u guest:guest -H "content-type:application/json" -XPUT -d'{"password":"pwd","tags":"administrator"}' http://localhost:15672/api/users/username
I need to make this Http Put request from Ruby. The following is my code:
def test_add_user
uri = URI.parse('http://localhost:15672/api/users/karthik/')
uri.to_s
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Put.new(uri.path)
request.basic_auth 'guest', 'guest'
request['Content-Type'] = 'application/json'
request['Accept'] = 'application/json'
request.set_form_data({'password' => 'secret', 'tags' => 'management'})
http.start do |http|
res = http.request(request)
puts res
end
end
This is the result I get
o.test_add_user
#<Net::HTTPUnsupportedMediaType:0x007fd7fb6fe1d8>
=> nil
Does Media type exception relate with Content-Type?
Only application/json is allowed
Should I use anything like to_json? If yes, where should it be used? Thanks in advance.
Regards
Karthik
Thank you Hector and ptd. Fixed it. Attached the working code for future reference.
def test_add_user
uri = URI.parse('http://localhost:15672/api/users/Test1/')
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Put.new(uri.path)
request.basic_auth 'guest', 'guest'
request['Content-Type'] = 'application/json'
request['Accept'] = 'application/json'
request.body = {'password' => 'secret', 'tags' => 'management'}.to_json
http.start do |http|
res = http.request(request)
puts res
end
end
Adds a new user to the RabbitMQ queue

Resources