ruby net/http difficulties - ruby

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

Related

Why mechanize failed to login website ruby

I'm trying to make an account to website "vpnstaticip.com" using mechanize
but I've always got unknown error that
ERROR: Email is too long
after submiting.
The error never happend in the browser
I've tried to submit without any input and same thing happend
require "mechanize"
$url = "https://vpnstaticip.com/create-account.php?trial=1"
$m = Mechanize.new
$page1 = $m.get($url)
$form1 = $page1.form_with(:id => "pro_form1")
$form1.field_with(:name => "name").value = "name"
$form1.field_with(:name => "email").value = "me#mail.com"
$form1.field_with(:name => "country").options[217].click #United States
$form1.field_with(:name => "username").value = "Username"
$form1.checkbox_with(:name => "terms").check
$page2 = $m.submit($form1)
$file1 = open("vpnstaticip.html","w")
$file1.write($page2.parser)
$file1.close()
Looks like this form submitted by js, but the mechanize is not working with js actually
onclick="document.getElementById('pro_form1').submit();"
perhaps the changed of driver will help (selenium or poltergeist) with the creation of Capybara browser session.
or, as an option, just try to ignore SSL errors:
$m.verify_mode = OpenSSL::SSL::VERIFY_NONE
or i think, match better to use here the net-post request without mechanize, for me it's work fine:
url = URI("https://vpnstaticip.com/create-account.php?trial=1")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/x-www-form-urlencoded'
request.body = "name=name&email=me%2540mail.com&country=217&username=Username&terms=1&nospam=nospam&submitted=1"
response = http.request(request)
puts response.read_body
=> ERROR: Username already exists. Try different one
besides, i can't reproduce the "Email is too long" error, so please, let me know if the problem is still persist, thanks

How to solve net http internal server error

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

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

Ruby: Syntax to POST batch request with Net::HTTP to Facebook API

Using curl the following command is correct, and the Facebook API replies with the expected response:
curl -F 'access_token=TOKEN' -F 'batch=[{"method":"GET",
"relative_url":"facebook"},{"method":"GET",
"relative_url":"youtube"}]' https://graph.facebook.com
I would like to convert this to Ruby but have been struggling to find the right syntax. I have tried variations on the below, but without luck:
uri = URI.parse('https://graph.facebook.com')
res = Net::HTTP.post_form(uri, 'access_token' => 'TOKEN', 'batch' =>
"[{'method':'GET', 'relative_url':'facebook'}]")
Can you help?
Thanks to this question and this blog post here's what I got working:
uri = URI("https://graph.facebook.com/")
req = Net::HTTP::Post.new(uri.path)
attach = {}
attach = {'batch' => [{"method" => "GET", "relative_url"=>"facebook"}].to_json}
req.set_form_data(attach.merge('access_token' => "TOKEN"))
res = Net::HTTP.new(uri.host, uri.port)
res.verify_mode = OpenSSL::SSL::VERIFY_NONE
res.use_ssl = true
response = nil
res.start do |http|
response = http.request(req)
end

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