How to solve net http internal server error - ruby

I am passing xml data from an xml for post_xml to a web service which reads this data but am getting an error # my passing method is as below. What am I missing out or how shoul i go about it. Thank you
require 'net/http'
require 'open-uri'
pegPayStatusCode = ""
conn = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Post.new(uri.request_uri)
if uri.scheme == 'https'
require 'net/https'
conn.use_ssl = true
conn.verify_mode = OpenSSL::SSL::VERIFY_NONE # needed for windows environment
end
#request.body=post_xml
request.set_form_data({"q" => "#{post_xml}", "per_page" => "50"})
response = conn.request(request)
pegPayStatusCode = response

Related

Trouble passing params into GET request - Ruby script

I have a Ruby script that issues a GET request to a restful API, but it ignores the params that I'm trying to pass in. I want to just get the activated users but it returns all of the users.
Am I not passing in my params correctly? This is my script:
require 'net/http'
require 'net/https'
require 'time'
require 'api-auth'
require 'json'
URL = 'https://<instance name>.mingle-api.thoughtworks.com/api/v2/users.xml'
OPTIONS = {:access_key_id => '<sign in name>', :access_secret_key => '<secret key>'}
PARAMS = {:user => { :activated => true } }
def http_get(url, options={}, params)
uri = URI.parse(url)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
body = params.to_json
request = Net::HTTP::Get.new(uri.request_uri)
request.body = body
request['Content-Type'] = 'application/json'
request['Content-Length'] = body.bytesize
ApiAuth.sign!(request, options[:access_key_id], options[:access_secret_key])
response = http.request(request)
users = response.body
if response.code.to_i > 300
raise StandardError, <<-ERROR
Request URL: #{url}
Response: #{response.code}
Response Message: #{response.message}
Response Headers: #{response.to_hash.inspect}
Response Body: #{response.body}
ERROR
end
puts users
end
http_get(URL, OPTIONS, PARAMS)
The response is XML of users, formatted like this:
<user>
<id type="integer">2228</id>
<name>NAME</name>
<login>example#example.com</login>
<email>example#example.com</email>
<light type="boolean">false</light>
<icon_path nil="true"></icon_path>
<activated type="boolean">true</activated>
<admin type="boolean">false</admin>
</user>
I'm still a beginner when it comes to coding, so any help is greatly appreciated! Thank you!
You are putting the parameters for the get request in the body, when you should be placing them in the URL, so that the end of the URL looks something like this:
?param1=value1&param2=value2
Use a function like this (source):
require 'uri'
def hash_to_query(hash)
return URI.encode(hash.map{|k,v| "#{k}=#{v}"}.join("&"))
end
When you create the URI:
uri = URI.parse("#{url}?#{hash_to_query(params)}")
Passing the params via the URL did not work for me.
I ended up pulling the data from the XML that was returned instead of narrowing the search. This returns the correct data:
require 'net/http'
require 'net/https'
require 'time'
require 'api-auth'
require 'json'
require 'nokogiri'
URL = 'https://<instance name>.mingle-api.thoughtworks.com/api/v2/users.xml'
OPTIONS = {:access_key_id => '<sign in name>', :access_secret_key => '<secret key>'}
def http_get(url, options={})
uri = URI.parse(url)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri.request_uri)
ApiAuth.sign!(request, options[:access_key_id], options[:access_secret_key])
response = http.request(request)
users = response.body
if response.code.to_i > 300
raise StandardError, <<-ERROR
Request URL: #{url}
Response: #{response.code}
Response Message: #{response.message}
Response Headers: #{response.to_hash.inspect}
Response Body: #{response.body}
ERROR
end
return users
end
def extract_active_users
all_users = Nokogiri::XML(http_get(URL, OPTIONS))
all_users.search('//user').each do |user|
active_user = user.xpath('activated')
if active_user.text == 'true'
puts user
end
end
end
extract_active_users

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)

Sending http post request in Ruby by Net::HTTP

I'm sending a request with custom headers to a web service.
require 'uri'
require 'net/http'
uri = URI("https://api.site.com/api.dll")
https = Net::HTTP.new(uri.host, uri.port)
https.use_ssl = true
headers =
{
'HEADER1' => "VALUE1",
'HEADER2' => "HEADER2"
}
response = https.post(uri.path, headers)
puts response
It's not working, I'm receiving an error of:
/usr/lib/ruby/1.9.1/net/http.rb:1932:in `send_request_with_body': undefined method `bytesize' for #<Hash:0x00000001b93a10> (NoMethodError)
How do I solve this?
P.S. Ruby 1.9.3
Try this:
For detailed documentation, take a look at:
http://www.rubyinside.com/nethttp-cheat-sheet-2940.html
require 'uri'
require 'net/http'
uri = URI('https://api.site.com/api.dll')
https = Net::HTTP.new(uri.host, uri.port)
https.use_ssl = true
request = Net::HTTP::Post.new(uri.path)
request['HEADER1'] = 'VALUE1'
request['HEADER2'] = 'VALUE2'
response = https.request(request)
puts response
The second argument of Net::HTTP#post needs to be a String containing the data to post (often form data), the headers would be in the optional third argument.
As qqx mentioned, the second argument of Net::HTTP#post needs to be a String
Luckily there's a neat function that converts a hash into the required string:
response = https.post(uri.path, URI.encode_www_form(headers))

Ruby https POST with headers

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}"

Resources