Ruby post not working - ruby

I'm trying to replicate the curl request on this page using Ruby. When I run the curl request from my system it works fine, but Ruby gives me an error. I've tried a few different ways of doing Ruby posts but none of them work. Here's my code:
hr_args = { 'type' => 'todo',
'text' => 'tyy'
}
hr_hd = {"Content-Type"=>"application/json",
'x-api-user'=> habit_user,
'x-api-key' => habit_token
}
url = URI.parse('https://habitrpg.com:443/api/v2/user/tasks')
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Post.new(url.request_uri, hr_hd)
request.body = hr_args.to_json
response = http.request(request)
This is the error I get:
/usr/local/rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/net/protocol.rb:153:in `read_nonblock': end of file reached (EOFError)
from /usr/local/rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/net/protocol.rb:153:in `rbuf_fill'
from /usr/local/rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/net/protocol.rb:134:in `readuntil'
from /usr/local/rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/net/protocol.rb:144:in `readline'
from /usr/local/rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/net/http/response.rb:39:in `read_status_line'
from /usr/local/rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/net/http/response.rb:28:in `read_new'
from /usr/local/rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/net/http.rb:1408:in `block in transport_request'
from /usr/local/rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/net/http.rb:1405:in `catch'
from /usr/local/rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/net/http.rb:1405:in `transport_request'
from /usr/local/rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/net/http.rb:1378:in `request'
from /usr/local/rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/net/http.rb:1371:in `block in request'
from /usr/local/rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/net/http.rb:853:in `start'
from /usr/local/rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/net/http.rb:1369:in `request'
from todo.rb:38:in `<main>'
What am I doing wrong?

The problem was that I needed to set http.use_ssl = true.

try this
...
require 'openssl'
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
...
...

Related

Does the shoes gem support HTTPS requests?

I've been looking around on how to make HTTPS requests using the Shoes GUI builder and I'm getting the SSL_connnect connect error and I'm unsure of what to do about it.
I made a test app in this Gist
Here's the Error:
SSL_connect returned=1 errno=0 state=error: certificate verify failed
/Applications/Shoes.app/Contents/MacOS/lib/ruby/2.2.0/net/http.rb:923:in `connect'
/Applications/Shoes.app/Contents/MacOS/lib/ruby/2.2.0/net/http.rb:923:in `block in connect'
/Applications/Shoes.app/Contents/MacOS/lib/ruby/2.2.0/timeout.rb:73:in `timeout'
/Applications/Shoes.app/Contents/MacOS/lib/ruby/2.2.0/net/http.rb:923:in `connect'
/Applications/Shoes.app/Contents/MacOS/lib/ruby/2.2.0/net/http.rb:863:in `do_start'
/Applications/Shoes.app/Contents/MacOS/lib/ruby/2.2.0/net/http.rb:852:in `start'
/Applications/Shoes.app/Contents/MacOS/lib/ruby/2.2.0/net/http.rb:1375:in `request'
shoes.rb:17:in `request'
shoes.rb:54:in `block (3 levels) in <main>'
-e:1:in `call'
I figured it out. Updating the request to strip the token and setting the verify_mode to OpenSSL::SSL::VERIFY_NONE fixed the problem.
token = Base64.encode64("#{user}:#{pass}").strip
uri = URI("https://example.com/")
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["authorization"] = "Bearer #{token}"
request["Content-Type"] = "application/json"
response = http.request(request)
info(response.body)
response

fetching tweets with Ruby returns `open_http': 400 Bad Request (OpenURI::HTTPError)

I am new to Ruby. I have starting reading first chapter in Bastards Book Ruby i.e. Tweet fetching but the tutorial uses Twitter API v1. The response I got told me to use v1.1. So, I followed tutorials and wrote a program:
require 'oauth'
def prepare_access_token(oauth_token, oauth_token_secret)
consumer = OAuth::Consumer.new("apiKey", "APISecret", { :site => "https://api.twitter.com", :scheme => :header })
token_hash = { :oauth_token => oauth_token, :oauth_token_secret => oauth_token_secret }
access_token = OAuth::AccessToken.from_hash(consumer, token_hash )
return access_token
end
access_token = prepare_access_token("AccessToken", "AccessTokenSecret")
response = access_token.request(:get, "https://api.twitter.com/1.1/statuses/home_timeline.json")
puts response
Output: #<Net::HTTPOK:0x007fb7eb0885b8>
If I run program until here. It runs just fine. But, then if I add below content to fetch tweets and write to file. I get errors
twitter_user = "iAbhimanyuAryan"
remote_base_url = "https://api.twitter.com/1.1/statuses/user_timeline.json?count=100&screen_name="
remote_full_url = remote_base_url + twitter_user
tweets = open(remote_full_url).read
my_local_filename = twitter_user + "-tweets.json"
my_local_file = open(my_local_filename, "w")
my_local_file.write(tweets)
my_local_file.close
Errors:
❯ ruby twitter.rb
#<Net::HTTPOK:0x007fbbfc9d75c8>
/Users/abhimanyuaryan/.rbenv/versions/2.2.3/lib/ruby/2.2.0/open-uri.rb:358:in `open_http': 400 Bad Request (OpenURI::HTTPError)
from /Users/abhimanyuaryan/.rbenv/versions/2.2.3/lib/ruby/2.2.0/open-uri.rb:736:in `buffer_open'
from /Users/abhimanyuaryan/.rbenv/versions/2.2.3/lib/ruby/2.2.0/open-uri.rb:211:in `block in open_loop'
from /Users/abhimanyuaryan/.rbenv/versions/2.2.3/lib/ruby/2.2.0/open-uri.rb:209:in `catch'
from /Users/abhimanyuaryan/.rbenv/versions/2.2.3/lib/ruby/2.2.0/open-uri.rb:209:in `open_loop'
from /Users/abhimanyuaryan/.rbenv/versions/2.2.3/lib/ruby/2.2.0/open-uri.rb:150:in `open_uri'
from /Users/abhimanyuaryan/.rbenv/versions/2.2.3/lib/ruby/2.2.0/open-uri.rb:716:in `open'
from /Users/abhimanyuaryan/.rbenv/versions/2.2.3/lib/ruby/2.2.0/open-uri.rb:34:in `open'
from twitter.rb:27:in `<main>'
Looking at the man pages for the Twitter API, this request requires authentication.
You will need to use your AccessToken object to make the request. Something like this:
# response is a [Net::HTTPResponse][3]
response = access_token.get(remote_full_url)
# Get the entire body of the response
tweets = response.body
Note, this is a very basic way of doing it. If you were putting such code into production, you would add proper checking and error handling.

Ruby Net::HTTP Get request Error when using https

I have a web server that i need to get some data from. I want to reuse the connection, that's why i chose HTTP.new
require "net/http"
require "openssl"
uri = URI.parse("https://example.com")
path = "/index.html"
http = Net::HTTP.new(uri.host, uri.port,
:use_ssl => uri.scheme == 'https')
request = Net::HTTP::Get.new "/index.html"
response = http.request(request)
When issuing the request (response = http.request(request)) ruby throws a TypeError:
TypeError: no implicit conversion of Hash into String
from /usr/local/Cellar/ruby/2.2.2/lib/ruby/2.2.0/net/http.rb:879:in `initialize'
from /usr/local/Cellar/ruby/2.2.2/lib/ruby/2.2.0/net/http.rb:879:in `open'
from /usr/local/Cellar/ruby/2.2.2/lib/ruby/2.2.0/net/http.rb:879:in `block in connect'
from /usr/local/Cellar/ruby/2.2.2/lib/ruby/2.2.0/timeout.rb:74:in `timeout'
from /usr/local/Cellar/ruby/2.2.2/lib/ruby/2.2.0/net/http.rb:878:in `connect'
from /usr/local/Cellar/ruby/2.2.2/lib/ruby/2.2.0/net/http.rb:863:in `do_start'
from /usr/local/Cellar/ruby/2.2.2/lib/ruby/2.2.0/net/http.rb:852:in `start'
from /usr/local/Cellar/ruby/2.2.2/lib/ruby/2.2.0/net/http.rb:1375:in `request'
from (irb):14
from /usr/local/bin/irb:11:in `<main>'
The same request works when i use http
I'm not sure you aren't overcomplicating the invocation. Why not just use:
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
I'm basing this on the assumption that you already know whether or not your target server requires HTTPS or not.

can't get a response using Ruby's Net::HTTP with headers

Here's my code:
#!/usr/bin/env ruby
require 'net/http'
uri = URI.parse('https://api.lendingclub.com/api/investor/v1/loans/listing')
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Get.new(uri.request_uri)
request.initialize_http_header({'Authorization' => 'exampleQd0ddDKREKgdpeDOKsdfs3434aA='})
request.initialize_http_header({'Accept' => 'application/json'})
request.initialize_http_header({'Content-Type' => 'application/json'})
response = http.request(request)
Here's where I end up:
/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/net/protocol.rb:153:in `read_nonblock': end of file reached (EOFError)
from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/net/protocol.rb:153:in `rbuf_fill'
from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/net/protocol.rb:134:in `readuntil'
from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/net/protocol.rb:144:in `readline'
from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/net/http/response.rb:39:in `read_status_line'
from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/net/http/response.rb:28:in `read_new'
from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/net/http.rb:1406:in `block in transport_request'
from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/net/http.rb:1403:in `catch'
from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/net/http.rb:1403:in `transport_request'
from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/net/http.rb:1376:in `request'
from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/net/http.rb:1369:in `block in request'
from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/net/http.rb:852:in `start'
from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/net/http.rb:1367:in `request'
from /Users/jeff/Documents/My Synched Cloud Files/Documents/My Scripts/Python/Development/Lending Club/ruby/LC_get_notes_new.rb:12:in `<main>'
Not sure why all the errors are from Frameworks/Ruby. I am just trying to run this from a file (it's a script), not as any part of a website. Bonus points if you can then tell me how to save the response to a file once I get this part of the code working. By the way, I have all this working fine in Python but I am trying to port this to Ruby (which is new for me). Thanks!
Here an example how to do that with a POST
require 'net/http'
http = Net::HTTP.new('nl3.forgeofempires.com')
path = '/game/json?h=c29e13c18d3'
data = [
%{5a6029226f[{"clientIdentification":{"requiredBackendVersion":"1.17","appType":null,"deviceId":null,"registrationId":null,"platform":"bro","androidDeviceId":null,"platformVersion":"web","clientVersionNumber":"1.17","__class__":"ClientIdentification"}, etc...}]}
]
headers = {
'Cookie' => cookie,
"Content-Length" => l,
'Connection' => 'keep-alive',
"Origin" => "http://cdn.nl.forgeofempires.com",
'Referer' => "http://cdn.nl.forgeofempires.com/swf/Preloader.swf?1389689898",
'Content-Type' => 'application/x-www-form-urlencoded'
}
resp = http.post(path, data, headers)
File.write('response.json', resp.body)
Try with this:
#!/usr/bin/env ruby
require 'net/http'
uri = URI.parse('https://api.lendingclub.com/api/investor/v1/loans/listing')
request = Net::HTTP::Get.new uri.request_uri
res = Net::HTTP.start(uri.host, uri.port,
:use_ssl => uri.scheme == 'https') {|http| http.request request}
request.initialize_http_header({'Authorization' => 'exampleQd0ddDKREKgdpeDOKsdfs3434aA='})
request.initialize_http_header({'Accept' => 'application/json'})
request.initialize_http_header({'Content-Type' => 'application/json'})
response = res.request(request)
If you want to write the response into a file
File.write('filename', response)

Ruby undefined method `bytesize' for #<Hash:0x2954fe8>

i have the following Ruby Code, for a tracking website in sandbox mode:
require "net/http"
require "net/https"
require "uri"
xml = <<XML
<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?><data appname="dhl_entwicklerportal" language-code="de" password="Dhl_123!" request="get-status-for-public-user"><data piece-code="00340433836536550280"></data></data>
XML
uri = URI('https://cig.dhl.de/services/sandbox/rest/sendungsverfolgung')
nhttp = Net::HTTP.new(uri.host, uri.port)
nhttp.use_ssl=true
nhttp.verify_mode=OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Get.new(uri)
request.basic_auth 'xpackageWP', 'hidden'
response = nhttp.start {|http|
http.request(request, xml:xml)
}
puts response.body
I always get the error :
d:/Ruby200/lib/ruby/2.0.0/net/http/generic_request.rb:179:in `send_request_with_body' undefined method `bytesize' for #<Hash:0x2954fe8> (NoMethodError)
from d:/Ruby200/lib/ruby/2.0.0/net/http/generic_request.rb:130:in `exec'
from d:/Ruby200/lib/ruby/2.0.0/net/http.rb:1404:in `block in transport_request'
from d:/Ruby200/lib/ruby/2.0.0/net/http.rb:1403:in `catch'
from d:/Ruby200/lib/ruby/2.0.0/net/http.rb:1403:in `transport_request'
from d:/Ruby200/lib/ruby/2.0.0/net/http.rb:1376:in `request'
from D:/Dropbox_5BHIF/Dropbox/TempDHL/Main.rb:17:in `block in <main>'
from d:/Ruby200/lib/ruby/2.0.0/net/http.rb:852:in `start'
from D:/Dropbox_5BHIF/Dropbox/TempDHL/Main.rb:16:in `<main>'
I tried really hard to solve this, but i cannot think of any problem.
When i test it in the Browser with the Link and then a ?xml= it works perfectly, so it seems to be a problem with my Ruby Code.
You're sending post data as a hash. You should encode it as string.
For example Using URI::encode_www_form:
request = Net::HTTP::Post.new(uri)
...
response = nhttp.start do |http|
post_data = URI.encode_www_form({xml: xml})
http.request(request, post_data)
end
UPDATE If you want GET request, append the query string to the url.
post_data = URI.encode_www_form({xml: xml})
uri = URI('https://cig.dhl.de/services/sandbox/rest/sendungsverfolgung?' +
post_data)
...
response = nhttp.start do |http|
http.request(request)
end
request expects a string for its second argument, on which it invokes bytesize. You're giving it a hash, which doesn't respond to bytesize.
Use POST and not GET request
xml = <<XML
<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?><data
appname="dhl_entwicklerportal" language-code="de" password="Dhl_123!" request="get-status-for-public-user"><data piece-code="00340433836536550280"></data></data>
XML
uri = URI('https://cig.dhl.de/services/sandbox/rest/sendungsverfolgung')
nhttp = Net::HTTP.new(uri.host, uri.port)
nhttp.use_ssl=true
nhttp.verify_mode=OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Post.new(uri)
request.body = xml
request.basic_auth 'xpackageWP', 'hidden'
response = nhttp.start {|http|
http.request(request)
}
I solved by using .to_s, it returns a 200.
#client.job.create_or_update(job_name, job_xml.get_xml.to_s)
This is Jenkins API client what I'm currently using:
https://github.com/arangamani/jenkins_api_client

Resources