Issue regarding http POST api call using ruby code - ruby-on-rails

I am going to access the Riskscreen api to authenticate users. To test the api I have written a ruby code snippet to make sample POST call to get the number of tokens I have from the Riskscreen api.
My code is:
require 'uri'
require 'net/http'
require 'net/https'
require 'json'
#toSend = {}.to_json
uri = URI.parse("https://api.riskscreen.com/api/v1/user/tokens")
https = Net::HTTP.new(uri.host,uri.port)
https.use_ssl = true
https.verify_mode = OpenSSL::SSL::VERIFY_NONE
header = {'api-key': 'my api key','Content-Type': 'application/json', 'Accept': 'application/json'}
req = Net::HTTP::Post.new(uri.path, header)
req.body = "[ #{#toSend} ]"
res = https.request(req)
puts "------------"
puts "Response #{res.code} #{res.message}: #{res.body}"
But I am getting the following error:
Response 400 Bad Request
If I change the header line to
header = {'api-key'=> 'my-api-key','Content-Type'=> 'application/json', 'Accept'=> 'application/json'}
then I am getting this error:
Response 401 Unauthorized
Sticking with this for a while. Please help me to sort out this.

Header's keys must be String instead of Symbol
header = {'api-key' => 'my api key','Content-Type' => 'application/json', 'Accept' => 'application/json'}
Another issue is net/http is capitalize header automatically, api-key -> Api-Key which cause Authorization Error on your server. One solution is to create new class to wrap api-key to prevent Ruby do that
class HeaderCaseSensitive < String
def capitalize
self
end
def split(*args)
super.each do |str|
HeaderCaseSensitive.new(str)
end
end
def to_s
self
end
end
Then change header:
header = {HeaderCaseSensitive.new('api-key') => 'xxxx','Content-Type' => 'application/json', 'Accept' => 'application/json'}
To sum up, following code will work:
require 'uri'
require 'net/http'
require 'net/https'
require 'json'
class HeaderCaseSensitive < String
def capitalize
self
end
def split(*args)
super.each do |str|
HeaderCaseSensitive.new(str)
end
end
def to_s
self
end
end
#toSend = {}.to_json
uri = URI.parse("https://api.riskscreen.com/api/v1/user/tokens")
https = Net::HTTP.new(uri.host,uri.port)
https.use_ssl = true
https.verify_mode = OpenSSL::SSL::VERIFY_NONE
header = {HeaderCaseSensitive.new('api-key') => 'xxx','Content-Type' => 'application/json', 'Accept' => 'application/json'}
https.set_debug_output($stdout)
req = Net::HTTP::Post.new(uri.path, header)
req.body = "[ #{#toSend} ]"
res = https.request(req)
puts "------------"
puts "Response #{res.code} #{res.message}: #{res.body}"

Can you try remove:
req.body = "[ #{#toSend} ]"
and replace by:
req.set_form_data({})
# or
req.body = "{}"
Sorry, I'm not sure about that.

Related

How to call JDoodle API from local Rails server?

I am calling the JDoodle API with post request from my local machine Rails server with valid id and secrete. I am not getting desired response. Please suggest me if i am doing wrong....
My Ruby function to make api call
def run_Jddodle_API
require 'net/http'
require 'uri'
require 'json'
uri = URI.parse("https://api.jdoodle.com/v1/execute")
request = Net::HTTP::Post.new(uri)
request.content_type = "application/json; charset=UTF-8"
request.body = {
"clientId" => "ddc371fd*************c8efbae",
"clientSecret" => "4ee8e79a225***************************a8ee7f331aeeca603",
"script" => "<?php printf(\"hello RAJA\"); ?>",
"language" => "php",
"versionIndex" => "0"
}.to_json
req_options = { use_ssl: uri.scheme == "https", }
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
http.request(request)
end
puts response.body
end
And the response is
{"error":"Unauthorized Request","statusCode":401}
try changing this line:
request.content_type = "application/json; charset=UTF-8"
to this:
request.content_type = "application/json"
I changed the code as below and it worked but can't say why.?
require 'uri'
require 'net/http'
require 'net/https'
url = URI("https://api.jdoodle.com/v1/execute")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url.path)
request["Content-Type"] = 'application/json'
request.body = {
"script" => params[:code],
"language" => params[:lang],
"versionIndex" => params[:version],
"clientId" => "dc37******************efbae",
"clientSecret" => "4ee8e79a225a5525*******************************************"
}.to_json
response = http.request(request)
puts response.read_body`

FCM API Bad Request

I'm trying to push a notification through FCM from my Ruby on Rails project, here is my code:
require 'net/http'
require 'json'
def send_notifications
log = Logger.new("log/notifications.log")
begin
uri = URI.parse("https://fcm.googleapis.com/fcm/send")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
key = '...'
hash = {:notification => {:sound => "default", :title => "test", :text => "test", :badge => "0"}, :data => {:targetID => "1", :to => "..."}}
req = Net::HTTP::Post.new(uri.path, {'Content-Type' => 'application/json', 'Authorization' => "key=#{key}"})
req.body = hash.to_json
response = http.request(req)
log.debug("response #{response.body}")
rescue => e
log.debug("failed #{e}")
end
end
I'm getting Bad Request 400 error, and debugging the response body only shows this: "to"
Please help me debug this issue. Thank you

Rails - net/http is working but same request is not working in httparty

I'm trying to do a request in httparty but it's not working
require 'httparty'
module PvWatch
class Client
include HTTParty
# base_uri ENV["pv_watch_endpoint"]
def login
response = self.class.post('http://pvwatch.xxx.xxx.xxx.net/api/v1/login', options)
end
def options
{
headers: {
'content-type' => 'application/json',
'access-key' => 'FORGET ABOUT THIS',
'authorization' => 'uri=api/v1/login'
},
body: {
username: "case",
password: "123"
}
}
end
end
end
the weird thing is that when i do the request with net/http is working and i don't know what i'm doing wrong with httparty
require 'uri'
require 'net/http'
module PvWatch
class Client
def login
url = URI("http://pvwatch.xxx.xxx.xxx.net/api/v1/login")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/x-www-form-urlencoded'
request["access-key"] = 'FORGET ABOUT THIS'
request["authorization"] = 'uri=api/v1/login'
request.body = "username=case&password=123"
response = http.request(request)
puts response.read_body
end
end
end
any idea what i'm doing wrong?

Missing query parameters on x-www-form-urlencoded POST request and net/http

I have a post request with headers and query parameters that I want to fire with net/http. The request returns 200 but the response body says: {\"error\":\"invalid_request\",\"error_description\":\"Required query parameter 'grant_type' missing.\"}
This is the complete function I call:
def Search.request_oauth_access_token
require 'net/http'
uri = URI.parse('https://request.url/oauth2/access_token')
params = {
'grant_type' => 'my:grant:type'
}
headers = {
'Authorization' => 'Basic sldhfgKGsdfgGOI23==',
'Content-Type' => 'application/x-www-form-urlencoded'
}
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri.request_uri, headers)
query = URI.encode_www_form_component(params)
request.body = query
response = http.request(request)
p response.body
end
I am using Rails 5.0.2.
Solved it. Turned out that I had a syntax error in the params definition.
This was the correct way of defining it:
params = {
grant_type: 'my:grant:type'
}
And then in the request:
query = URI.encode_www_form(params)
http.request(request, query)
The simplest way is using ruby core library:
require "uri"
require "net/http"
params = {
'field1' => 'Nothing is less important',
'field2' => 'Submit'
}
x = Net::HTTP.post_form(URI.parse('http://www.yahoo.com/web/ch05/formpost.asp'), params)
puts x.body
This saved my day
You can also change your params syntax to the following:
params = [ [ "param1", "value1" ], [ "param2", "value2" ], [ "param3", "value3" ] ]

Parametrized get request in Ruby?

How do I make an HTTP GET request with parameters in Ruby?
It's easy to do when you're POSTing:
require 'net/http'
require 'uri'
HTTP.post_form URI.parse('http://www.example.com/search.cgi'),
{ "q" => "ruby", "max" => "50" }
But I see no way of passing GET parameters as a hash using 'net/http'.
Since version 1.9.2 (I think) you can actually pass the parameters as a hash to the URI::encode_www_form method like this:
require 'uri'
uri = URI.parse('http://www.example.com/search.cgi')
params = { :q => "ruby", :max => "50" }
# Add params to URI
uri.query = URI.encode_www_form( params )
and then fetch the result, depending on your preference
require 'open-uri'
puts uri.open.read
or
require 'net/http'
puts Net::HTTP.get(uri)
Use the following method:
require 'net/http'
require 'cgi'
def http_get(domain,path,params)
return Net::HTTP.get(domain, "#{path}?".concat(params.collect { |k,v| "#{k}=#{CGI::escape(v.to_s)}" }.join('&'))) if not params.nil?
return Net::HTTP.get(domain, path)
end
params = {:q => "ruby", :max => 50}
print http_get("www.example.com", "/search.cgi", params)
require 'net/http' require 'uri'
uri = URI.parse( "http://www.google.de/search" ); params = {'q'=>'cheese'}
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Get.new(uri.path)
request.set_form_data( params )
# instantiate a new Request object
request = Net::HTTP::Get.new( uri.path+ '?' + request.body )
response = http.request(request)
puts response.body
I would expect it to work without the second instantiation as it would be the first request-objects or the http-object's job but it worked for me this way.
Net::HTTP.get_print 'localhost', '/cgi-bin/badstore.cgi?searchquery=crystal&action=search&x=11&y=15'
or
uri = URI.parse("http://localhost")
req = Net::HTTP::Get.new("/cgi-bin/badstore.cgi?searchquery=crystal&action=search&x=11&y=15")
http = Net::HTTP.new(uri.host, uri.port)
response = http.start do |http|
http.request(req)
end
Use Excon:
conn = Excon.new('http://www.example.com/search.cgi')
conn.get(:query => { "q" => "ruby", "max" => "50" })
new to stack overflow and I guess I can't comment, but #chris.moose is missing double quotes in his function def. line 5 should be:
return Net::HTTP.get(domain, "#{path}?".concat(params.collect { |k,v| "#{k}=#{CGI::escape(v.to_s)}" }.reverse.join('&'))) if not params.nil?
or here's the whole thing redefined for copy/pasting
require 'net/http'
require 'cgi'
def http_get(domain,path,params)
return Net::HTTP.get(domain, "#{path}?".concat(params.collect { |k,v| "#{k}=#{CGI::escape(v.to_s)}" }.reverse.join('&'))) if not params.nil?
return Net::HTTP.get(domain, path)
end
<3
-mike
This is the easiest way to do it
require 'net/http' require 'uri'
#siteurl = "http://www.google.de/search/#{#yourquery}"
define your query
#yourquery = "whatever"
uri = URI.parse( "#siteurl" );
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Get.new(uri.path)
# instantiate a new Request object
request = Net::HTTP::Get.new( uri.path+ '?' + request.body )
response = http.request(request)
puts response.body
Might not be perfect but at least you get the idea.

Resources