Trying to make curl requests in ruby - ruby-on-rails

is there a ruby curl library that will allow me to duplicate this request:
curl -d '<hello xmlns="http://checkout.google.com/schema/2"/>' https://S_MERCHANT_ID:S_MERCHANT_KEY#sandbox.google.com/checkout/api/checkout/v2/request/Merchant/S_MERCHANT_ID
i have tried curb, but their PostField.content class is not cooperating with google's checkout api. here is the code from my curb request:
c = Curl::Easy.new("https://MY_ID:MY_KEY#sandbox.google.com/checkout/api/checkout/v2/request/Merchant/MY_ID_AGAIN")
c.http_auth_types = :basic
c.username = 'MY_ID'
c.password = 'MY_KEY'
# c.headers["data"] = '<?xml version="1.0" encoding="UTF-8"?><hello xmlns="http://checkout.google.com/schema/2"/>'
c.http_post(Curl::PostField.content('', '<?xml version="1.0" encoding="UTF-8"?><hello xmlns="http://checkout.google.com/schema/2"/>'))
c.perform
i HAVE managed to get it working using ruby's system command, but im not sure how to handle the response from it.
req = system("curl -d '<hello xmlns=\"http://checkout.google.com/schema/2\"/>' https://MY_ID:MY_KEY#sandbox.google.com/checkout/api/checkout/v2/request/Merchant/MY_ID")
I have been at it for 2 hours now. any help would be greatly appreciated, thanks!

You can use IO.popen to read from the child process:
IO.popen(['curl', '-o', '-', '-d', ..., err: [:child, :out]]) do |io|
response = io.read
end
This example combines standard out and standard error into one stream in the child process, and it forces curl to redirect output to standard out via -o. You would specify your other options in place of the ....

I always use Rest Client gem for such use cases, it is very simple in use and have all REST requests out-of-box with whole batch of tuning parameters.
Your code will look like something similar to this:
url = "sandbox.google.com/checkout/api/checkout/v2/request/Merchant/#{S_MERCHANT_ID}"
credentials = "#{S_MERCHANT_ID}:#{S_MERCHANT_KEY}"
RestClient.post "https://credentials##{url}", '<hello xmlns="http://checkout.google.com/schema/2"/>'

Alternatively, you can use a HTTP request library such as Typheous (https://github.com/typhoeus/typhoeus). Is there anything that binds you with "curl"?

I would have curl put the result in a file, and then open the file using ruby and read it ( File.open)
Or us httparty

I figured it out (YAAAAY!)
if anyone else is having this problem, here is the solution.
executable commands work fine in the command line, but if you are trying to render the output of an executable command from a controller in rails, make sure you use render :json instead of render :text to print the results.
for some reason the render :text was only outputting bits and pieces of my command's output (and driving me insane in the process).
For those of you trying to integrate with google checkout in rails, here is how you make http requests to google:
First step: add rest-client to your Gemfile. here is how to do it from the command line:
$ cd /path/to/your/rails/app
$ sudo nano Gemfile
Next, add the gem to your gemfile by placing the following somewhere in your Gemfile
$ gem "rest-client"
next, run bundle install
$ bundle install
restart your server. if apache2:
$ sudo service apache2 reload
if webrick:
$ rails s
then, in your controller (assuming you have rails set up and are able to access a controller from the browser) write the following code:
$ url = "https://YOUR_GOOGLE_CHECKOUT_MERCHANT_ID:YOUR_GOOGLE_CHECKOUT_KEY#sandbox.google.com/checkout/api/checkout/v2/request/Merchant/YOUR_GOOGLE_CHECKOUT_MERCHANT_ID"
$ req = RestClient.post(url, '<hello xmlns="http://checkout.google.com/schema/2"/>')
render :json => req
Please don't forget to replace YOUR_GOOGLE_MERCHANT_ID with your actual merchant id and YOUR_GOOGLE_CHECKOUT_KEY with your actual google checkout key
<?xml version="1.0" encoding="UTF-8"?>
<bye xmlns="http://checkout.google.com/schema/2" serial-number="1dfc3b90-1fa6-47ea-a585-4d5482b6c785" />
(answer courtesy of nexo)

Related

Server not available on localhost with response code 403 & RuntimeError in Ruby on Rails

After changing proxy settings in open_uri.rb and server_manage.rb I finally managed to install neo4j behind a proxy server. The neo4j server is running on port 7000 ( It opens in the browser) but when i enter :
$rails generate scaffold post title body
Error:
/.rvm/gems/ruby-2.2.3/gems/neo4j-core-5.1.6/lib/neo4j-server/cypher_session.rb:51:in `open': Server not available on http://localhost:7000 (response code 403) (RuntimeError)
What should I do ?
Any help is appreciated!!
$ ruby --version
ruby 2.2.3p173 (2015-08-18 revision 51636) [x86_64-linux]
$ rails --version
Rails 4.2.2
My guess - proxy issues. Things may behave differently in your browser and code (because those are 2 different environment).
To check what exactly is going on with your database, you should try to make request to Neo4j manually, from command line.
Example with using curl:
# if auth enabled
curl -i --user username:password http://localhost:7000/db/data/
# if auth disabled
curl -i http://localhost:7000/db/data/
This will give you more details on what exactly is not working.
Also you can assemble basic ruby script that will make HTTP request, to check what you receive in response in this case.
A 403 might mean that your Neo4j authentication credentials are wrong. See http://neo4jrb.readthedocs.org/en/5.1.x/Setup.html#rails-configuration for details but basically, adding something like this to application.rb might do the trick:
config.neo4j.session_options = { basic_auth: { username: 'foo', password: 'bar'} }
Also, since you mentioned needing help with the proxy, you can add an initialize key to set that.
init = { proxy: { uri: 'http://myproxy', user: 'username', password: 'password' }}
auth = { username: 'neo4j', password: 'pwhere'}
config.neo4j.session_options = { basic_auth: auth, initialize: init }

rails api: send curl in controller test

I'm building a Rails API, and I'm writing a test that sending a curl request works. This seems to be a testing issue, because an actual curl request works:
$ curl -X POST -d temperature=68 localhost:3000/temperature_readings.json
# => {"status":200}
Here's the controller method:
def create
TemperatureReading.create(temperature: params[:temperature])
render json: { status: 200 }
end
Here's the test:
context 'works via a curl request' do
it 'works' do
system "curl -X POST -d 'temperature=68' #{temperature_readings_url(format: 'json')}"
expect(TemperatureReading.last.temperature).to eq(68)
end
end
I'm getting an error from curl that test.host does not resolve:
curl: (6) Could not resolve host: test.host
That makes sense, because when I call temperature_readings_url(format: 'json') from within pry in that method, I get http://test.host/temperatures.json.
Is there a better way to test that my controller can successfully handle a curl request and create the correct record with the correct attributes?
What I've Tried
I made sure that protect_from_forgery with: :null_session is set in ApplicationController so that it doesn't fail with an exception when it can't find the token
I tried adding -H 'Content-Type:application/json' to the curl request to make sure it's hitting the json format in the controller. But it really seems to boil down to the fact that the working URL in the testing environment is test.host.
So I explicitly set request.host to localhost:3000 in the test, which felt a little hacky. But then of course it just posted to my dev database and not my test database, so the test still failed.
Your app doesn't know its host outside the request context, so you have to provide it anyway. This is also hacky:
temperature_readings_url(format: 'json', host: 'localhost:3000').
But you can define it globally in config/enviroments/test.rb:
Rails.application.routes.default_url_options[:host] = 'localhost:3000'
so in test enviroment all url helpers will return localhost:3000 as host by default.

Ruby XMLRPC localhost Runtime Error : Wrong Size

I am trying to connect to the XMLRPC API of a dokuwiki website.
I am successfully doing that from my own laptop, with a SSL connection, however, when I try to do it from my production server (which hosts both the wiki and the rails app from which the ruby code is executed), I run into a
Runtime Error
Wrong size. Was 163, should be 113
Here's how I initialize the connection :
#wiki = ::XMLRPC::Client.new3(
host: "wiki.example.com",
path: "/lib/exe/xmlrpc.php",
use_ssl: true)
# Temp Hack because SSL Fails
#wiki.instance_variable_get(:#http).instance_variable_set(:#verify_mode, OpenSSL::SSL::VERIFY_NONE)
end
#authenticated = false
authenticate!
end
def authenticate!
# Fails at below line :
#authenticated = #wiki.call("dokuwiki.login", ENV['WIKI_USER'], ENV['WIKI_PASSWORD'])
Rails.logger.info (#authenticated ? "Authenticated on Wiki !" : "Authentication failed on wiki !")
end
I've read many posts saying that there is a bug in the XMLRPC lib of Ruby. I was running ruby 2.1.5pxx on my laptop and ruby 1.9.xx at my server so I did a rvm install 2.1.5, yet the problem is still here
(btw, I assumed it was enough to do a rvm use 2.1.5 and then touch restart to restart my rails server, but how can I check which version of ruby it's using ?)
What is wrong ?
EDIT
On my laptop, I am running ruby 2.1.5p273 (2014-11-13 revision 48405) [x64-mingw32]
On my production server, I am running ruby-2.1.5 [ i686 ]
I tried another library, libxml-xmlrpc, and I get the following error when running the same command:
Net::HTTPBadResponse: wrong status line: "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">"
But again, the same code is running fine with the default ruby xmlrpc client on my Windows + rubyx64 2.1.5, so I really don't get it!
Edit2 : I tried adding
#wiki.http_header_extra = { "accept-encoding" => "identity" }
But then I get a
Authorization failed. HTTP-Error: 401 Unauthorized
The first call #wiki.call("dokuwiki.login", "myUsr", "myPwd") worked, but apparently it failed to authenticate me (Of course I am still using the same login information that should work)
EDIT 3
After investigation, a successful login from any other computer than localhost will set a cookie like
#cookie="DokuWiki=[small string] ; [very big string]
Whereas if I do it on localhost :
I will write [...] for random strings
#cookie="[small string 2]=deleted; DokuWiki=[small string]; [very big string]"
So I have an extra variable info stored in my cookie, which is "[small string 2]=deleted;
I believe this is what makes my authentication fails. Anyone knows what this is ???
So this localhost connection was messing up with the cookie. Apparently, even the ruby library doesn't know why, and the "Wrong size" comes from this unexpected string [random string]=deleted added at the beginning of the cookie.
Unless someone can explain WHY such a string is added, I will accept my solution of simply adding
#wiki.http_header_extra = { "accept-encoding" => "identity" }
which removes the "Wrong size" error, then
if /deleted/.match(#wiki.cookie)
#wiki.cookie = #wiki.cookie.gsub(/.*deleted; /, '')
end
To remove the beginning of the cookie

Ruby net-ssh wirth proxy command causes freeze

I would like to connect to a remote computer via another using ruby.
This scheme is the following :
Local -> proxy -> remote
I have this code which is doing the work for a direct access :
require 'net/ssh'
Net::SSH.start(remote_host, remote_user) do |ssh|
puts ssh.exec!'hostname'
end
However, when I try with the proxy, the command 'hostname' is executed and correct, but then the code freezes, same if I call ssh.close.
Here is the code :
require 'net/ssh'
require 'net/ssh/proxy/command'
proxy_cmd = Net::SSH::Proxy::Command.new('ssh proxy_user#proxy_host nc %h %p')
Net::SSH.start(remote_host, remote_user, :proxy => proxy) do |ssh|
puts ssh.exec!'hostname'
end
The loggin is done without password thanks to a rsa key. And the proxycommand is working (I was using it in bash before)
Would someone knows what I am doing wrong ?
Thank you very much for your interest,
EDIT : here is the last line in the logs, it blocks there :
I, [2013-10-16T23:01:19.304778 #3785] INFO -- net.ssh.connection.session[4555128]: closing remaining channels (0 open)
I've just bumped in the same issue - command line ssh was working and net/ssh was hanging on me when using proxycommand.
Debuging net/ssh brought me as far as: https://github.com/net-ssh/net-ssh/blob/master/lib/net/ssh/transport/session.rb#L113 and the whole thing was hanging on the .close call of the socket.
I'm not sure what caused this, but adding timeout to nc command seems to have solved it:
ProxyCommand ssh proxy_server#proxy_server nc -q 1 %h %p

What is the easiest way to get an HTTP response from command-line Dart?

I am writing a command-line script in Dart. What's the easiest way to access (and GET) an HTTP resource?
Use the http package for easy command-line access to HTTP resources. While the core dart:io library has the primitives for HTTP clients (see HttpClient), the http package makes it much easier to GET, POST, etc.
First, add http to your pubspec's dependencies:
name: sample_app
description: My sample app.
dependencies:
http: any
Install the package. Run this on the command line or via Dart Editor:
pub install
Import the package:
// inside your app
import 'package:http/http.dart' as http;
Make a GET request. The get() function returns a Future.
http.get('http://example.com/hugs').then((response) => print(response.body));
It's best practice to return the Future from the function that uses get():
Future getAndParse(String uri) {
return http.get('http://example.com/hugs')
.then((response) => JSON.parse(response.body));
}
Unfortunately, I couldn't find any formal docs. So I had to look through the code (which does have good comments): https://code.google.com/p/dart/source/browse/trunk/dart/pkg/http/lib/http.dart
this is the shortest code i could find
curl -sL -w "%{http_code} %{url_effective}\\n" "URL" -o /dev/null
Here, -s silences curl's progress output, -L follows all redirects as before, -w prints the report using a custom format, and -o redirects curl's HTML output to /dev/null.
Here are the other special variables available in case you want to customize the output some more:
url_effective
http_code
http_connect
time_total
time_namelookup
time_connect
time_pretransfer
time_redirect
time_starttransfer
size_download
size_upload
size_header
size_request
speed_download
speed_upload
content_type
num_connects
num_redirects
ftp_entry_path

Resources