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
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
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.
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.
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)
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