How to post XML data via a proxy in Ruby? - ruby-on-rails

I would like to run the following command in ruby on rails via a proxy:
curl --request POST http://200.206.38.24:8580/my_server_path/
--data-binary #test01.xml
--header "Content-type: Application/vnd.vizrt.payload+xml;type=element"
And so far I have:
PROXY_URL = 'proxy.mydomain.com'
PROXY_PORT = 3128
PROXY_USER = 'user'
PROXY_PASSWORD = 'pass'
MSE_HOST = '200.206.38.24'
MSE_PORT = 8580
MSE_PATH = '/my_server_path/'
xml_file = '<?xml version="1.0" encoding="utf-8"?><etc... />'
Net::HTTP::Proxy(PROXY_URL, PROXY_PORT, PROXY_USER, PROXY_PASSWORD).start(MSE_HOST, MSE_PORT) do |http|
response = http.post(MSE_PATH, xml_file, {"Content-type" => "Application/vnd.vizrt.payload+xml;type=element"})
end
Thanks in advance for any help.

According to tests, it works fine.
The response from http.post can be accessed via the body method. Eg: response.body

Related

How do I format this GET in curb?

I'm trying to use someone's API to retrieve data. Here's a plain curl GET that works fine:
$ curl -H 'Authorization: Bearer eyJhbGciOiJSUz...' 'https://app.theirsite.com/api/web/call/call-log?q=\{"pageSize":25,"pageIndex":1,"sortBy":"timeConnected","sortDirection":2,"userAccountId":0,"requestorId":0,"companyAccountId":99,"consumerId":null,"ticksSince":636959988000000000,"ticksUntil":636966899990000000,"callStatusId":1\}'
Note the escaped brackets.
I can't get this to work in rails with curb. I've tried various attempts at formatting the parameters following the '?' in the url, but no luck. Here's my last attempt:
params = {"pageSize": 25,
"pageIndex": 1,
"sortBy": "timeConnected",
"sortDirection": 2,
"userAccountId": 0,
"requestorId": 0,
"companyAccountId": 99,
"consumerId": nil,
"ticksSince": 636959988000000000,
"ticksUntil": 636966899990000000,
"callStatusId": 1}
params_str = JSON[params].to_s
params_str.insert( -2, '\\')
response = Curl.get("https://app.theirsite.com/api/web/call/call-log?q=\\" + params_str ) {|curl|
curl.headers['Authorization'] = 'Bearer ' + #saved.token
curl.verbose = true}
The authorization is fine, but their server is responding with a 500 error {"global":["Index was outside the bounds of the array."]}. This is what I was getting with a direct curl command before I figured out I needed the escaped brackets. I haven't figured out how to get curb to provide an output of the complete url before sending. That would be helpful.
Any thoughts.
OK, not an answer, but I finally gave up on curb and switched to Ruby's net/http.
With the params above, it looks like:
uri = URI.parse("https://app.theirsite.com/api/web/call/call-log?q=" + JSON[params])
request = Net::HTTP::Get.new(uri)
request["Authorization"] = 'Bearer ' + #saved.token
req_options = {
use_ssl: uri.scheme == "https",
}
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
http.request(request)
end
A bit longer, but no escaped characters and now everything works.

Net::HTTP::Post.new request returns empty body in Ruby 2

In Ruby 2.0.0p195, Rails 4.0.0, Net::HTTP::Post.new request returns empty body of response.
#toSend = {
"zuppler_store_id" => 'X3r82l89',
"user_id" => '1'
}.to_json
uri = URI("http://smoothpay.com/zuppler/gen_token_post.php")
http = Net::HTTP.new(uri.host,uri.port)
req = Net::HTTP::Post.new uri
req.content_type = "application/json"
req.body = #toSend # or "[ #{#toSend} ]" ?
res = Net::HTTP.start(uri.host, uri.port) {|http| http.request(req)}
puts "Response #{res.code} - #{res.message}: #{res.body}"
This code returns "Response 200 - OK:"
But it should return like this: {"result":"success","token":"843e5be88fb8cee7d324244929177b4e"}
You can check it by typing this url:
http://smoothpay.com/zuppler/gen_token_test.php
Why is res.body empty?
Seems like that service doesn't like the POST request to be application/json.
This works:
uri = URI("http://smoothpay.com/zuppler/gen_token_post.php")
http = Net::HTTP.new(uri.host,uri.port)
req = Net::HTTP::Post.new uri
req.body = "zuppler_store_id=X3r82l89&user_id=1"
res = Net::HTTP.start(uri.host, uri.port) {|http| http.request(req)}
res.body # => "{\"result\":\"success\",\"token\":\"9502e49d454ab7b7dd2699a26f742cda\"}"
In other words, give the service application/x-www-form-urlencoded. Peculiarly, it will hand you back text/html which you'll have to JSON.parse. Weird service.

EOFError (end of file reached) in Ruby on Rails with http.request

I am trying to get json form url :
uri = URI.parse("http://84.38.185.251:9262/send")
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Get.new(uri.request_uri)
response = http.request(request)
response.code # => 301
response.body # => The body (HTML, XML, blob, whatever)
response["cache-control"] # => public, max-age=2592000
puts response.body
but i get an error :`EOFError (end of file reached):
app/controllers/sensors_controller.rb:35:in sensinfo'
sensors_controller.rb:35:
response = http.request(request)
What am i did wrong?
this error mostly get for using https
If it is https then
Please try this one
uri = URI.parse("https://84.38.185.251:9262/send")
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Get.new(uri.request_uri)
http.use_ssl = true
response = http.request(request)
Note aditional
http.use_ssl = true
If it is not https
http.use_ssl = false
or you can add the condition
http.use_ssl = true if domain =~ /^https/
you can get more on this https://web.archive.org/web/20140226183826/http://expressica.com/2012/02/10/eoferror-end-of-file-reached-issue-when-post-a-form-with-nethttp/
I think it is a some sort of bug; typhoeus seems to work:
require 'typhoeus'
response = Typhoeus.get("http://84.38.185.251:9262/send")
p response.body
#=> {"ids":"-1","data":{"temp":"nan","h":"-1"},"status":"255","voltage":"-1"}

Too many open files - socket(2) with net/http

I have a problem with http requests with net/http...
I writing a ruby script that interacts with the dailymotion api.
This script will upload a video "test.flv".
Basically it consists of four requests.
It works perfectly until step "#Create the video object".
The following error is raised on the last
"response = http.request(req)" command ->
Errno::EMFILE: Too many open files - socket(2)
Here is the code, thx for any advice...
require 'net/http'
require 'curb'
require 'json'
# Authenticate the user
url = URI.parse( 'https://api.dailymotion.com/oauth/token' )
req = Net::HTTP::Post.new(url.path)
req.set_form_data({ 'grant_type' => 'password',
'client_id' => 'my_client_id',
'client_secret' => 'my_client_secret',
'username' => 'myusername',
'password' => 'mypassword'
})
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
response = http.request(req)
access_token = JSON.parse( response.body )['access_token']
access_url = 'https://api.dailymotion.com/file/upload?access_token=' + access_token
# Get an upload URL
url = URI.parse( access_url )
req = Net::HTTP::Get.new( url.request_uri )
http = Net::HTTP.new( url.host, url.port )
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
response = http.request( req )
upload_url = JSON.parse( response.body )['upload_url']
progress_url = JSON.parse( response.body )['progress_url']
# Post the video
fields_hash = {}
post_data = fields_hash.map { |k, v| Curl::PostField.content(k, v.to_s) }
post_data << Curl::PostField.file('file', 'C:/test.flv')
c = Curl::Easy.new(upload_url)
c.multipart_form_post = true
c.http_post(post_data)
file_url = JSON.parse( c.body_str )['url']
# Create the video object
url = URI.parse( 'https://api.dailymotion.com/me/videos' )
req = Net::HTTP::Post.new(url.path)
req.set_form_data({ 'url' => file_url,
'access_token' => access_token
})
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
response = http.request(req)
puts response.body
Try calling finish
http.finish
after the response = http.request( req ).

get ebay time in rails

I've been looking around a bit for how to get the time off of ebay..
I don't want to use SAVON because... well it didn't work..
So I'm trying to use net/http, just to get the time. (for now)
Here's what I got so far.
def get_ebay_time
require "net/http"
require "uri"
devName = 000000000
appName = 000000000
certName = 000000000
authToken = 0000000000
url = URI.parse("https://api.ebay.com/ws/api.dll")
req = Net::HTTP::Post.new(url.path)
req.add_field("X-EBAY-API-COMPATIBILITY-LEVEL", "759")
req.add_field("X-EBAY-API-DEV-NAME", devName)
req.add_field("X-EBAY-API-APP-NAME", appName)
req.add_field("X-EBAY-API-CERT-NAME", certName)
req.add_field("X-EBAY-API-SITEID", "0")
req.add_field("X-EBAY-API-CALL-NAME", "GeteBayOfficialTime")
req.body = '<?xml version="1.0" encoding="utf-8"?>'+
'<GeteBayOfficialTimeRequest xmlns="urn:ebay:apis:eBLBaseComponents">'+
'<RequesterCredentials>'+
"<eBayAuthToken>#{authToken}</eBayAuthToken>"+
'</RequesterCredentials>'+
'</GeteBayOfficialTimeRequest>?'
http = Net::HTTP.new(url.host, url.port)
res = http.start do |http_runner|
http_runner.request(req)
end
return res.body
end
APIs wrappers are developed to help :)
Please use eBay4r and same on github: up_the_irons/ebay4r
require 'rubygems'
gem 'ebay'
# Put your credentials in this file
load('myCredentials.rb')
# Create new eBay caller object. Omit last argument to use live platform.
eBay = EBay::API.new($authToken, $devId, $appId, $certId, :sandbox => true)
resp = eBay.GeteBayOfficialTime
puts "Hello, World!"
puts "The eBay time is now: #{resp.timestamp}"
it didn't take me as long to find this as I thought.
in the bottom bit, I added SSL handling
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = 0
res = http.start do |http_runner|
http_runner.request(req)
end
return res.body

Resources