Ruby https POST with headers - ruby

How can I make a Https post with a header in Ruby with a json?
I have tried:
uri = URI.parse("https://...")
https = Net::HTTP.new(uri.host,uri.port)
req = Net::HTTP::Post.new(uri.path)
req['foo'] = bar
res = https.request(req)
puts res.body

The problem it was a json. This solve my problem. Anyway, my question was not clear, so the bounty goes to Juri
require 'uri'
require 'net/http'
require 'net/https'
require 'json'
#toSend = {
"date" => "2012-07-02",
"aaaa" => "bbbbb",
"cccc" => "dddd"
}.to_json
uri = URI.parse("https:/...")
https = Net::HTTP.new(uri.host,uri.port)
https.use_ssl = true
req = Net::HTTP::Post.new(uri.path, initheader = {'Content-Type' =>'application/json'})
req['foo'] = 'bar'
req.body = "[ #{#toSend} ]"
res = https.request(req)
puts "Response #{res.code} #{res.message}: #{res.body}"

Try:
require 'net/http'
require 'net/https'
uri = URI.parse("https://...")
https = Net::HTTP.new(uri.host,uri.port)
https.use_ssl = true
req = Net::HTTP::Post.new(uri.path)
req['foo'] = bar
res = https.request(req)
puts res.body

Here's a cleaner way to use Net::HTTP. If you just want to get the response and throw other objects away this is quite useful.
require 'net/http'
require 'json'
uri = URI("https://example.com/path")
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
req = Net::HTTP::Post.new(uri)
req['Content-Type'] = 'application/json'
# The body needs to be a JSON string, use whatever you know to parse Hash to JSON
req.body = {a: 1}.to_json
http.request(req)
end
# The "res" is what you need, get content from "res.body". It's a JSON string too.

A secure-by-default example:
require 'net/http'
require 'net/https'
req = Net::HTTP::Post.new("/some/page.json", {'Content-Type' =>'application/json'})
req.body = your_post_body_json_or_whatever
http = Net::HTTP.new('www.example.com', 443)
http.use_ssl = true
http.ssl_version = :TLSv1 # ruby >= 2.0 supports :TLSv1_1 and :TLSv1_2.
# SSLv3 is broken at time of writing (POODLE), and it's old anyway.
http.verify_mode = OpenSSL::SSL::VERIFY_PEER # please don't use verify_none.
# if you want to verify a server is from a certain signing authority,
# (self-signed certs, for example), do this:
http.ca_file = 'my-signing-authority.crt'
response = http.start {|http| http.request(req) }

Its working, you can pass data and header like this:
header = {header part}
data = {"a"=> "123"}
uri = URI.parse("https://anyurl.com")
https = Net::HTTP.new(uri.host,uri.port)
https.use_ssl = true
req = Net::HTTP::Post.new(uri.path, header)
req.body = data.to_json
res = https.request(req)
puts "Response #{res.code} #{res.message}: #{res.body}"

Related

How to use awesome_print for Ruby file that makes a HTTP request

This is my code:
require 'net/https'
uri = URI('https://api.clever.com/v1.1/sections')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
request = Net::HTTP::Get.new(uri.request_uri)
request.add_field 'Authorization', 'Bearer DEMO_TOKEN'
response = http.request(request)
puts response.body
The problem is that my code output is gross and hard to read in terminal. I'm trying to clean it up with awesome print but it isn't working... this is what I'm trying:
require 'net/https'
require 'awesome_print'
uri = URI('https://api.clever.com/v1.1/sections')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
request = Net::HTTP::Get.new(uri.request_uri)
request.add_field 'Authorization', 'Bearer DEMO_TOKEN'
response = http.request(request)
ap response.body
but it's not formatting at all the way I need it to. Any idea what's going on?
The problem is that you need to print the Hash, not the raw String. So use JSON.parse(response.body) would solve your problem.
Alternatively, use pp and json, they are all from stdlib.
require 'net/https'
require 'pp'
require 'json'
uri = URI('https://api.clever.com/v1.1/sections')
Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
request = Net::HTTP::Get.new(uri)
request["authorization"] = "Bearer DEMO_TOKEN"
http.request(request) do |response|
pp JSON.parse(response.body)
end
end
But ultimately, I would recommend to use pry for debugging. It just make life easier 10x for debuging.
gem install pry
Then change above code to:
require 'net/https'
require 'pry'
require 'json'
uri = URI('https://api.clever.com/v1.1/sections')
Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
request = Net::HTTP::Get.new(uri)
request["authorization"] = "Bearer DEMO_TOKEN"
http.request(request) do |response|
res = JSON.parse(response.body)
binding.pry
end
end
After running the file in your terminal, it will paused at where you put binding.pry. Then type res, you will see the nicely formatted hash.
Have fun with pry!
parse your response.body to JSON and use pretty_generate() function, built into later versions of JSON.
require 'net/https'
require 'json'
uri = URI('https://api.clever.com/v1.1/sections')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
request = Net::HTTP::Get.new(uri.request_uri)
request.add_field 'Authorization', 'Bearer DEMO_TOKEN'
response = http.request(request)
myjson = JSON.parse(response.body)
puts JSON.pretty_generate(myjson)
Which will give you output:
{
"data": {
"course_name": "Fine Arts, Class 703",
"course_number": "703",
"created": "2014-02-26T21:15:38.324Z",
"district": "4fd43cc56d11340000000005",
"grade": "7",
"last_modified": "2015-09-30T21:08:09.877Z",
"name": "Fine Arts, Class 703 - 703 - A. Ortiz (Section 3)",
"period": "7",
"school": "530e595026403103360ff9ff",
"sis_id": "674",
"students": [
"530e5960049e75a9262cff59",
"530e5960049e75a9262cff99",
"530e5961049e75a9262cffd5",
"530e5961049e75a9262d001c",
"530e5961049e75a9262d008a",
"530e5962049e75a9262d0144",
"530e5962049e75a9262d0155",
"530e5962049e75a9262d015e",
"530e5963049e75a9262d0200",
"530e5963049e75a9262d022d",
"530e5963049e75a9262d023a",
"530e5964049e75a9262d0275",
"530e5964049e75a9262d029b",
"530e5964049e75a9262d02c0",
"530e5964049e75a9262d02de",
"530e5965049e75a9262d034a",
"530e5965049e75a9262d0354",
"530e5965049e75a9262d03c7",
"530e5966049e75a9262d0419",
"530e5966049e75a9262d046d",
"530e5966049e75a9262d0489",
"530e5967049e75a9262d0560",
"530e5967049e75a9262d05b4",
"530e5967049e75a9262d05bb",
"530e5968049e75a9262d0621",
"530e5968049e75a9262d0637"
],
"subject": "arts and music",
"teacher": "530e5955d50c310f36112bec",
....
....
# I have not post full output but it's pretty good and well structured
awesome print is print your Ruby data structures (Hash, Array etc.) in an easy to read format. Not for HTML!
If you want to format HTML in an easy to read manner, take a look at Nokogiri. Example:
require 'nokogiri'
# your response html
html = response.body
doc = Nokogiri::XML(html,&:noblanks)
puts doc.to_xhtml(indent:4)

unable to get the XML response using 'Get' request through 'Ruby' language

I am not able to get the xml response after triggering 'GET' request using Ruby language.My Current Code is as follows:
require 'net/https'
require 'uri'
require 'base64'
base_url = '<URL>'
app_guid = '<App GUID Value>'
format = "xml"
# Example using bug.fetch
params = {
"appGUID" => app_guid,
"format" => format,
"method" => "bug.fetch",
"bugId" => "1234567"
}
puts "XML Response"
res = Net::HTTP.post_form(URI.parse(base_url), params)
puts res.body
As Frederick notes, your code is making a POST request. If you want to use GET do:
uri = URI.parse(base_url)
uri.query = URI.encode_www_form(params)
res = Net::HTTP.get_response(uri)
If you still encounter errors, you may wish to use this alternative syntax:
uri = URI.parse(base_url)
uri.query = URI.encode_www_form(params)
conn = Net::HTTP.new(uri.host, uri.port)
conn.use_ssl = true
res = conn.get uri.request_uri

how to set header['content-type']='application/json' in ruby

require 'net/http'
require 'rubygems'
require 'json'
url = URI.parse('http://www.xyxx/abc/pqr')
resp = Net::HTTP.get_response(url) # get_response takes an URI object
data = resp.body
puts data
this is my code in ruby, resp.data is giving me data in xml form.
rest api return xml data by default , and json if header content-type is application/json.
but i want data in json form.for this i have to set header['content-type']='application/json'.
but i do not know , how to set header with get_response method.to get json data.
def post_test
require 'net/http'
require 'json'
#host = '23.23.xxx.xx'
#port = '8080'
#path = "/restxxx/abc/xyz"
request = Net::HTTP::Get.new(#path, initheader = {'Content-Type' =>'application/json'})
response = Net::HTTP.new(#host, #port).start {|http| http.request(request) }
puts "Response #{response.code} #{response.message}: #{response.body}"
end
Use instance method Net::HTTP#get to modify the header of a GET request.
require 'net/http'
url = URI.parse('http://www.xyxx/abc/pqr')
http = Net::HTTP.new url.host
resp = http.get("#{url.path}?#{url.query.to_s}", {'Content-Type' => 'application/json'})
data = resp.body
puts data
You can simply do this:
uri = URI.parse('http://www.xyxx/abc/pqr')
req = Net::HTTP::Get.new(uri.path, 'Content-Type' => 'application/json')
res = Net::HTTP.new(uri.host, uri.port).request(req)

How to post json data with Rest API

require 'net/http'
require 'uri'
postData = Net::HTTP.post_form(URI.parse('http://localhost/restapi/index.php/api/posts'),
{'id'=>9,'firstname'=>"test","lastname"=>"test"})
puts postData.body
How can I send data in JSON form?
#toSend = {"id" =>5,"firstname" => "anurag","lastname" => "arya"}
I also tried this but it did not work:
#toSend.to_json
Example:
require 'rubygems'
require 'net/http'
require 'uri'
require 'json'
url = "http://localhost/restapi/index.php/api/posts"
uri = URI.parse(url)
data = {"id"=>11,
"firstname"=>"PWD","lastname"=>"last"}
headers = {'Content-Type' =>'application/json',
'Accept-Encoding'=> "gzip,deflate",
'Accept' => "application/json"}
http = Net::HTTP.new(uri.host,uri.port) # Creates a http object
#http.use_ssl = true # When using https
#http.verify_mode = OpenSSL::SSL::VERIFY_NONE
response = http.post(uri.path,data.to_json,headers)
puts response.code
puts response.body
postData=Net::HTTP.post_form(URI.parse('http://localhost/oecprashant/yiiIndex.php/api/rubyREST'),
{'data'=>jsonData})

ruby net/http difficulties

I have some perl code that I'm trying to port to ruby. The perl code does what I want to, but I'm having some difficulty getting similar results out of the ruby code which is all the more frustrating because what I'm doing isn't terribly complicated.
first, the perl code:
use LWP::UserAgent;
use HTTP::Cookies;
my $cookie_jar = HTTP::Cookies->new(file => "/home/blah/lwpcookies.txt", autosave => 0);
my $ua = LWP::UserAgent->new('cookie_jar' => $cookie_jar);
my $p = {
'param1' => 'p1val',
'param2' => 'p2val',
'param3' => 'p3val',
'param4' => 'p4val',
'param5' => 'p5val',
'param6' => 'p6val',
};
my $res = $ua->post('https://sitename.somesite.com/login_page.php', $p); #login
my $url = "https://sitename.sometime.com/report.php?startdate=2012-1-1&enddate=2012-1-2";
$res = $ua->get($url);
I can then access $res->content and get what I want out of it.
I've tried the same in ruby using net/http, but I'm not able to get the same results. I'm also having some trouble figuring out what parts are even not working.
Here's the ruby code:
require 'net/http'
params = Hash.new
params['param1'] = 'p1val'
params['param2'] = 'p2val'
params['param3'] = 'p3val'
params['param4'] = 'p4val'
params['param5'] = 'p5val'
params['param6'] = 'p6val'
uri = URI.parse('https://sitename.somesite.com/login_page.php')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Post.new(uri.request_uri)
request.set_form_data(params)
res = http.request(request)
cookies = res.response['set-cookie']
# for what it's worth, I'm pretty sure the problem has already occurred by this point
uri = URI.parse("https://sitename.somesite.com/report.php?startdate=2012-1-1&enddate=2012-1-2")
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)
request['Cookie'] = cookies
res = http.request(request)
Thoughts? Suggestions? Tell me why I'm an idiot? Thanks.
Try Mechanize, it does cookies and redirects for you:
require 'mechanize'
agent = Mechanize.new
agent.post url1, params
cookie is set now
response = agent.get url2

Resources