Ruby POST request with cookies? - ruby

I have a Ruby script that sends a POST request with a cookie using:
curl.exe -H "Cookie: SomeCookie=#{cookie}" -d "SomaData=#{data}" http://somesite.com/post
I tried to rewrite this into native Ruby using Net::HTTP, but this code doesn't work:
Net::HTTP.post_form(URI('http://somesite.com/post'),
{'SomeData' => '#{data}',
'Cookie' => 'SomeCookie=#{cookie}'} )
How do I solve this problem?
I'am using MRI Ruby 1.9.3 on Windows 7.

Why not look into using Curb? It's a Ruby interface to libcurl, and has an interface that's closer to cURL than Net::HTTP.
This is from the documentation:
http = Curl.get("http://www.google.com/")
puts http.body_str
http = Curl.post("http://www.google.com/", {:foo => "bar"})
puts http.body_str
http = Curl.get("http://www.google.com/") do|http|
http.headers['Cookie'] = 'foo=1;bar=2'
end
puts http.body_str

Related

error!': 301 "Moved Permanently" (Net::HTTPRetriableError)

I am trying to use a code that I used to use with another Mac.
now when I run it with a new Mac (2018) I get the following error
This is the code
require 'net/http'
base = 'www.uniprot.org'
tool = 'uploadlists'
params = {
'from' => 'ACC', 'to' => 'P_REFSEQ_AC', 'format' => 'tab',
'query' => 'P13368 P20806 Q9UM73 P97793 Q17192'
}
http = Net::HTTP.new base
$stderr.puts "Submitting...\n";
response = http.request_post '/' + tool + '/',
params.keys.map {|key| key + '=' + params[key]}.join('&')
loc = nil
while response.code == '302'
loc = response['Location']
response = http.request_get loc
end
while loc
wait = response['Retry-After'] or break
$stderr.puts "Waiting (#{wait})...\n";
sleep wait.to_i
response = http.request_get loc
end
response.value # raises http error if not 2xx
puts response.body
and this is the error I get
/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/2.3.0/net/http/response.rb:120:in `error!': 301 "Moved Permanently" (Net::HTTPRetriableError)
from /System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/2.3.0/net/http/response.rb:129:in `value'
from conver.rb:28:in `<main>'
You're receiving an HTTP 301 Moved Permanently response code. When you look closer you can see it's pointing you to https://www.uniprot.org:443/uploadlists/ for the new location; this is what typically happens when a resource that was previously reachable via HTTP is now only reachable via HTTPS. It doesn't have anything to do with using a new computer; it's just coincidental that it happened around the same time.
If you change the URL to HTTPS it should work as you expect. That said, I never encourage the use of Net::HTTP directly because it's clunky. Take a look at how awkward it is just to make a connection using HTTPS! It's not worth the headache.
I prefer to use HTTParty because it's straightforward and easy to use, as well as being very popular in the Ruby community. Here's an example of how to accomplish your task with HTTParty in fewer lines of code:
require 'httparty'
params = {
'from' => 'ACC', 'to' => 'P_REFSEQ_AC', 'format' => 'tab',
'query' => 'P13368 P20806 Q9UM73 P97793 Q17192'
}
response = HTTParty.post(
'https://www.uniprot.org:443/uploadlists/',
{
body: params.keys.map { |key| key + '=' + params[key] }.join('&'),
headers: { 'Content-Type' => 'application/x-www-form-urlencoded' }
}
)
Then you can inspect the response body:
puts response.body
From To
P13368 NP_511114.2
Q9UM73 NP_004295.2
P97793 NP_031465.2
Q17192 XP_004934106.1
Additionally, I can tell from the stack trace that you posted that you're using the system version of Ruby that came with macOS. My advice is: Don't use system Ruby.
Instead, you should install a Ruby manager like RVM:
Install RVM with \curl -sSL https://get.rvm.io | bash -s stable
Reload your shell
Install Ruby with rvm install 2.5.3
Reinstall your gems (gem install httparty)
Then you can re-run your application.

Sending file with POST to server in pure ruby (or library that doesn't need build tools)

Writing extensions for Sketchup I need to get around their usage of their own ruby (2.0.0) interpreter. Most importantly, I can't install gems that require build tools.
How can I send a file per POST request to my local server which does some calculations and answers with a JSON object?
I'm aware how I can use rest-client to send the file, but due the mentioned restrictions I can't use it (it required build tools). Is there another comparable way or library that can help me?
require 'uri'
url = 'http://foourl.com'
uri = URI.parse(url)
data = File.read('fil_path')
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Post.new(uri.request_uri)
request.body = data
request.content_type = 'audio/amr'
response = http.request(request)
(Taken from here)
Don't forget to configure your content type
You can use Ruby's native Net::HTTP library.
Examples:
require 'net/http'
require 'uri'
uri = URI('http://www.example.com/search.cgi')
res = Net::HTTP.post_form(uri, 'q' => 'ruby', 'max' => '50')
puts res.body
or
response = http.post('/cgi-bin/search.rb', 'query=foo')

Converting a cURL request to a Ruby post request

I am trying to convert a quick cURL hack I did a while back to a Ruby equivavalent. Coming up short.
I am downloading data from an open JSON API from
http://api.turfgame.com/v4/users
with the following cURL command
curl -s -X POST -H "Content-Type: application/json" -d '[{"name": "tbone"}]' api.turfgame.com/v4/users
My feeble attempts has come up short. What I have so far that's not working is
require 'net/http'
require 'rubygems'
require 'json'
require 'uri'
url = "http://api.turfgame.com/v4/users"
uri = URI.parse(url)
data = {"name" => "tbone"}
headers = {"Content-Type" => "application/json"}
http = Net::HTTP.new(uri.host,uri.port)
response = http.post(uri.path,data.to_json,headers)
puts response.code
puts response.body
The error message I'm getting is
400
{"errorMessage":"Invalid JSON string","errorCode":195887105}
I'm guessing I'm not sending the request properly, but how?
Any pointers most welcome! Thanks
Your curl request has this content [{"name": "tbone"}] (an array with a hash inside), but in your Ruby version you just send the hash {"name" => "tbone"} without the wrapping array.
Change your data to:
data = [{"name" => "tbone"}]

Using cURL command with Ruby?

Want to scrape a bunch of tweets via the Twitter API, as an output I get cURL command, something like that
curl --get 'https://api.twitter.com/1.1/search/tweets.json' --data 'q=football' --header 'Authorization: OAuth oauth_consumer_key="**hidden**", oauth_nonce="**hidden**", oauth_signature="**hidden**", oauth_signature_method="HMAC-SHA1", oauth_timestamp="**hidden**", oauth_token="**hidden**", oauth_version="1.0"' --verbose
My question, is there a way to use this command into a Ruby script to scrape the tweets ?
Using the Twitter gem available here http://rdoc.info/gems/twitter with the following code you can get all the tweets from a ruby script.
require 'twitter'
client = Twitter::REST::Client.new do |config|
config.consumer_key ="hidden"
config.consumer_secret ="hidden"
config.access_token ="hidden"
config.access_token_secret ="hidden"
end
client.search("football").collect do |tweet|
puts tweet.text
end
you can wrap it in backticks and get the output like from any unix(like) command
script.rb
cmd=`echo 'hello world'`
puts cmd
ouptput: hello world
It is better to use existing API as #Hunter McMillen had suggested, but if you want to perform http-requests yourself, you can use net/http lib. Example below:
require 'net/http'
uri = URI('http://example.com/index.html')
params = { :limit => 10, :page => 3 }
uri.query = URI.encode_www_form(params)
res = Net::HTTP.get_response(uri)
puts res.body if res.is_a?(Net::HTTPSuccess)
Here is the info on how to set headers.

Simplest way to do a XMLHttpRequest in Ruby?

I want to do a XMLHttpRequest POST in Ruby. I don't want to use a framework like Watir. Something like Mechanize or Scrubyt would be fine. How can I do this?
Mechanize:
require 'mechanize'
agent = Mechanize.new
agent.post 'http://www.example.com/', :foo => 'bar'
Example with 'net/http', (ruby 1.9.3):
You only have to put an additional header for the XMLHttpRequest to your POST-request (see below).
require 'net/http'
require 'uri' # convenient for using parts of an URI
uri = URI.parse('http://server.com/path/to/resource')
# create a Net::HTTP object (the client with details of the server):
http_client = Net::HTTP.new(uri.host, uri.port)
# create a POST-object for the request:
your_post = Net::HTTP::Post.new(uri.path)
# the content (body) of your post-request:
your_post.body = 'your content'
# the headers for your post-request (you have to analyze before,
# which headers are mandatory for your request); for example:
your_post['Content-Type'] = 'put here the content-type'
your_post['Content-Length'] = your_post.body.size.to_s
# ...
# for an XMLHttpRequest you need (for example?) such header:
your_post['X-Requested-With'] = 'XMLHttpRequest'
# send the request to the server:
response = http_client.request(your_post)
# the body of the response:
puts response.body
XMLHTTPRequest is a browser concept, but since you're asking about Ruby, I assume all you want to do is simulate such a request from a ruby script? To that end, there's a gem called HTTParty which is very easy to use.
Here's a simple example (assuming you have the gem - install it with gem install httparty):
require 'httparty'
response = HTTParty.get('http://twitter.com/statuses/public_timeline.json')
puts response.body, response.code, response.message, response.headers.inspect

Resources