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
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.
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
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
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
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