Savon raises error inside Rails app, but not inside irb - ruby-on-rails

I'm using Savon library to get some SOAP requests work. And i'm using almost the same code within IRB and Rails application. When i'm running IRB everything works as it should, but Rails generate error "no method 'to_hash' for nil:NilClass" inside savon's do_request -> respond_with methods.
Here's my code (the same when running it within IRB or Rails):
# setup Savon client for SOAP requests
client = Savon::Client.new "http://www.webservicex.net/country.asmx?WSDL"
# test if "webservicex.net" server is up and running
actions = client.wsdl.soap_actions
raise "SOAP server is down" if actions.nil? or actions.length <= 0
# get country list
resp = client.request :get_countries
raise "No response for countries" if resp.nil?
resp = resp[:get_countries_response][:get_countries_result]
None of that exceptions is risen nor code far than 'pinging server' is executed.
What's wrong and how could i fix that?

It's problem with httpi gem - https://github.com/rubiii/savon/issues/163
Just use 0.9.1 version.

Related

In RoR, how do I get the status code when requesting a web page through a proxy?

I’m using Rails 4.2.7. How do I get the status code when making a request? I’m trying the below
uri = URI(url)
content = nil
status = nil
content_type = nil
res1 = Net::HTTP.SOCKSProxy('127.0.0.1', 50001).start(uri.host, uri.port) do |http|
puts "launching #{uri.path}"
resp = http.get(uri.path)
status = resp.status
content = resp.content
content_type = resp['content-type']
end
but its resulting in the below error. I can clearly see its a 403, but I would like to have that nice and neat within a variable, or at least have some kind of error I can catch
Error during processing: undefined method `status' for #<Net::HTTPForbidden 403 Forbidden readbody=true>
/Users/davea/Documents/workspace/myproject/app/helpers/webpage_helper.rb:77:in `block in get_content'
/Users/davea/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/net/http.rb:853:in `start'
/Users/davea/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/net/http.rb:584:in `start'
/Users/davea/Documents/workspace/myproject/app/helpers/webpage_helper.rb:74:in `get_content'
I think you want resp.code.
One way to find out is to use the pry gem. Once installed you can put binding.pry just after your http.get line and run your code. When it hits the pry line it will stop executing and open up a IRB prompt and then you can play around with resp directly trying different things. One really nifty feature is you can cd resp and are now "in" the object itself. Type ls and you can see all the methods available. Makes figuring this sort of thing out much easier.

Websocket Rails getting 404 during handshake

I installed the 'websocket-rails' gem and after doing the default configuration I just created a JS dispatcher and I get a 404 error on chrome console.
This is my JS:
var dispatcher = new WebSocketRails('localhost:3000/websocket');
This is the message I get:
WebSocket connection to 'ws://localhost:3000/websocket' failed: Error during WebSocket handshake: Unexpected response code: 404
Everything else is as suggested by the first-steps-guide
events.rb
subscribe :test, :to => ChatServerController, :with_method => :test
controller/chat_server_controller.rb
class ChatServerController < WebsocketRails::BaseController
def initialize_session
# perform application setup here
controller_store[:message_count] = 0
end
def test
puts 'Hello'
end
end
There's one potential solution involving a gem dependency posted on github. But, if you look at the repo (151 open issues, 27 pull requests), it doesn't look like this gem is being actively maintained. The closed issues in 2016 are being closed by the same people who opened them.
You can probably make your application work by forcing websockets to use http by including a second parameter, set to false.
var Dispatcher = new WebSocketRails('localhost:3000/websocket', false);
I have concerns about how scalable using http polling will be and about the future of the websocket-rails gem. For me, it seems like the best way forward is to upgrade to Rails 5 and use Action Cable.

Publish errors with the Faye-Rails gem

I'm using the faye-rails gem for asynchronous messaging between the javascript in my frontend and my rails server. I can send messages using curl and have the javascript print them, so I know the faye server is running. I can also listen to messages on the server like this:
# In application.rb
config.middleware.use FayeRails::Middleware, mount: '/bayeux', :timeout => 25 do
map '/async/**' => FayeController
map :default => :block
end
# In faye_controller.rb
class FayeController < FayeRails::Controller
channel '/async/test' do
subscribe do
puts "Received on channel #{channel}: #{message.inspect}"
end
end
end
Then I receive messages sent via curl -X POST localhost:3000/bayeux -H 'Content-Type: application/json' -d '{"channel": "/async/test", "data": "test123"}' and get the expected output. However, I can't seem to send messages from within the server. I expected somthing like this to work, in the subscribe block (so it would be sent as a response to any message):
FayeController.publish '/async/test', :response => 'something'
but that crashes the whole server with an error:
in '+': no implicit conversion of nil into Array (TypeError)
and then a stack trace. Is this my fault - am I failing to set something up correctly, or misreading the documentation? Or is it a bug in the gem, in which case does anyone have a workaround?
I've actually alread had to use one workaround already due to a bug in the underlying faye library, see here.
You can publish to faye server using an HTTP request (like curl) from your server
uri = URI.parse("http://localhost:3000/bayeux")
begin
Net::HTTP.post_form(uri, response: 'something')
rescue Errno::ECONNREFUSED
puts "Pushing to Faye Failed"
end
--------- Update --------------------------
The previous code needs to be run in another thread to prevent the deadlock (run it in a back ground job using resque for example)
You can use the following to publish in the same thread
client = Faye::Client.new('http://localhost:3000/bayeux')
client.publish('/async/test', {response: "something"})

Ruby SOAP Client using SAVON not working whereas PHP SOAP client works

Hello there I am testing few web services and I am trying to write a client using SAVON with my WSDL. I have one available operation named log_process and I am trying to access that but getting errors. I have a similar script written in PHP and it is working fine. I have tried
require 'net/http'
require "uri"
require 'savon'
client = Savon.client(wsdl: "http://somedomain.com/projects/shared/abc.wsdl")
#a=client.operations
puts #a
ary={0 =>"art", 1 =>"bac", 2 =>"arr"}
#result = client.call(:log_process, message:{0 =>"asdf", 1 =>"qwer", 2 =>"arr"})
puts #result
and getting following error
raise_soap_and_http_errors!': (SOAP-ENV:Client) Bad Request (Savon::SOAPFault)
My php working solution looks like this
$result = $client->log_process(array(0=>$user_name,1=>$user_pwd,2=>$display_type));
any idea what will be the ruby equivalent to this or am I calling the operation in correct manner?
I know this is late, but I was having the exact same issue trying to set up a soap request using savon to a soap server I have worked with extensively using PHP Soap server. I found another post related to this, and it seem that adding the message_tag option fixed it.
This is because in my case the WSDL was expecting functionNameRequest in the xml, but savon as only sending funcionName by setting message_tag to functionNameRequest the >soap server was able to correctly map the function that was being requested.
This was the thread that helped me out https://github.com/savonrb/savon/issues/520 Relevant code quoted below:
Hi,
I'm just sharing this in case it's useful.
I'm using savon 2.3.0 and I guess the gem had some problems identifying parameters >automatically from my wsdl. I have no idea about SOAP and this is the first time I'm >actually using it.
I'm dealing with TradeTracker's WSDL
With the following code I got it working:
client = Savon.client do
wsdl "http://ws.tradetracker.com/soap/affiliate?wsdl"
namespace_identifier :ns1
end
credentials = {
customerID: 123123,
passphrase: "123123123"
}
response = client.call(:authenticate, message_tag: :authenticate, message: credentials)
Try:
#result = client.call(:log_process, message:["asdf", "asg", "arr"])
In the PHP code, you are sending only 1 parameter, its an array

Logging RestClient in a Rails app

I'd like to debug the request my Rails app makes with RestClient. The RestClient docs say:
To enable logging you can
set RestClient.log with a ruby Logger
or set an environment variable to avoid modifying the code (in this case you can use a file name, “stdout” or “stderr”):
$ RESTCLIENT_LOG=stdout path/to/my/program
Either produces logs like this:
RestClient.get "http://some/resource"
=> 200 OK | text/html 250 bytes
RestClient.put "http://some/resource", "payload"
=> 401 Unauthorized | application/xml 340 bytes
Note that these logs are valid Ruby, so you can paste them into the restclient shell or a >script to replay your sequence of rest calls.
How do I do get these logs included in my Rails apps log folder?
from: https://gist.github.com/jeremy/1383337
require 'restclient'
# RestClient logs using << which isn't supported by the Rails logger,
# so wrap it up with a little proxy object.
RestClient.log =
Object.new.tap do |proxy|
def proxy.<<(message)
Rails.logger.info message
end
end
Create a file in config/initializers:
RestClient.log = 'log/a_log_file.log'
Or just put last in console
https://github.com/adelevie/rest-client/commit/5a7ed325eaa091809141d3ef6e31087569614e9d
This worked for me, running on RestClient 1.8 and Rails 4.2.1:
::RestClient.log = Rails.logger
You can use this gem:
https://github.com/uswitch/rest-client-logger
It works out of the box just by adding "gem 'rest-client-logger'" to your Gemfile.
may be so: RestClient.log = Rails.logger

Resources