Ruby net/http can't connect to a TLS proxy - ruby

Rubys net/http allows you to specify a proxy to route all requests through like this:
Net::HTTP.new("host", "443", "proxyHost", 8080, "proxyUsername", "password")
This works fine when used with HTTP proxy however fails when a TLS proxy used instead of HTTP:
def tls_proxy(data)
uri = URI("https://example.com/post")
client = Net::HTTP.new("host", "443", "proxyHost", 8443, "proxyUsername", "password")
client.ssl_version = :TLSv1_2
client.use_ssl = true
request = Net::HTTP::Post.new(uri.path)
request['Content-type'] = 'application/json'
request.body = data
client.request(request)
end
Uncaught exception: end of file reached
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/net/protocol.rb:225:in `rbuf_fill'
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/net/protocol.rb:191:in `readuntil'
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/net/protocol.rb:201:in `readline'
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/net/http/response.rb:40:in `read_status_line'
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/net/http/response.rb:29:in `read_new'
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/net/http.rb:969:in `connect'
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/net/http.rb:930:in `do_start'
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/net/http.rb:919:in `start'
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/net/http.rb:1470:in `request'
/Users/laptop/Projects/tls-proxy-ruby/example-https.rb:47:in `tls_proxy'
/Users/laptop/Projects/tls-proxy-ruby/example-https.rb:60:in `<top (required)>'
Is there a way to make it work with TLS proxy or perhaps there is an alternative to this library that supports TLS proxy?

You could try httparty gem instead.
require 'httparty'
options = {
http_proxyaddr: '127.0.0.1',
http_proxyport: '8443',
http_proxyuser: 'johndoe',
http_proxypass: '123456'
}
response = HTTParty.get('https://example.com', options)

Related

opensearch-ruby error on verifying ssl certificate: certificate verify failed (Hostname mismatch) (Faraday::SSLError)

I have a simple script and I am trying to perform using the opensearch-ruby client a simple search on my index. If I try to perform the query with ssl verification, my request succeeds. However, I am not able to perform the query if I enforce ssl verification. My request is failing saying that the certificate verify failed (Hostname mismatch). Below you can have a look on my script and the stacktrace after trying to execute my script.
Note that when I generate my certificate I use as CN=my.host.com
Do I miss something in my configuration when I am creating my client?
client = OpenSearch::Client.new(host: 'my.host.com',
port: 9200,
user: 'admin',
password: 'mypassword',
scheme: 'https',
transport_options: { ssl: {
verify: true,
ca_file: '/certs/root-ca.pem' } })
index_name = "my-index"
term = "Joe D"
query = {
'multi_match': {
'query': term,
'fields': ['name']
}
}
response = client.search(
body: query,
index: index_name
)
puts JSON.pretty_generate(response)
C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/net-protocol-0.1.2/lib/net/protocol.rb:46:in `connect_nonblock': SSL_connect returned=1 errno=0 state=error: certificate verify failed (Hostname mismatch) (Faraday::SSLError)
from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/net-protocol-0.1.2/lib/net/protocol.rb:46:in `ssl_socket_connect'
from C:/Ruby30-x64/lib/ruby/3.0.0/net/http.rb:1038:in `connect'
from C:/Ruby30-x64/lib/ruby/3.0.0/net/http.rb:970:in `do_start'
from C:/Ruby30-x64/lib/ruby/3.0.0/net/http.rb:965:in `start'
from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/net-http-persistent-4.0.1/lib/net/http/persistent.rb:655:in `start'
from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/net-http-persistent-4.0.1/lib/net/http/persistent.rb:595:in `connection_for'
from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/net-http-persistent-4.0.1/lib/net/http/persistent.rb:885:in `request'
from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/faraday-net_http_persistent-1.2.0/lib/faraday/adapter/net_http_persistent.rb:71:in `perform_request'
from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/faraday-net_http-1.0.1/lib/faraday/adapter/net_http.rb:66:in `block in call'
from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/faraday-1.10.0/lib/faraday/adapter.rb:50:in `connection'
from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/faraday-net_http-1.0.1/lib/faraday/adapter/net_http.rb:64:in `call'
from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/faraday-1.10.0/lib/faraday/rack_builder.rb:154:in `build_response'
from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/faraday-1.10.0/lib/faraday/connection.rb:516:in `run_request'
from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/opensearch-transport-2.0.0/lib/opensearch/transport/transport/http/faraday.rb:56:in `block in perform_request'
from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/opensearch-transport-2.0.0/lib/opensearch/transport/transport/base.rb:297:in `perform_request'
from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/opensearch-transport-2.0.0/lib/opensearch/transport/transport/http/faraday.rb:45:in `perform_request'
from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/opensearch-transport-2.0.0/lib/opensearch/transport/client.rb:193:in `perform_request'
from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/opensearch-ruby-2.0.2/lib/opensearch.rb:92:in `open_search_validation_request'
from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/opensearch-ruby-2.0.2/lib/opensearch.rb:58:in `verify_open_search'
from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/opensearch-ruby-2.0.2/lib/opensearch.rb:47:in `method_missing'
from C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/opensearch-api-2.0.2/lib/opensearch/api/actions/search.rb:106:in `search'
from C:/Users/vasgat/RubymineProjects/OpenSearchTest/myclient.rb:68:in `<main>'

Error after trying to access xml (Zlib::BufError) (Ruby)

I keep getting and error whenever I try and access an XML file in Ruby. This is my code:
require 'rubygems'
require 'net/http'
require 'uri'
require 'json'
require 'open-uri'
url = 'http://access.alchemyapi.com/calls'
service = '/text/TextGetRankedTaxonomy'
apikey = '?apikey=4317fce9281094613deee9ebcc5aaf5238cd0748'
thething = '&text='
text = 'men%27s%20white%20crew%20neck%20shirt'
fullurl = url + service + apikey + thething + text
opener = open(fullurl) {|f| f.read }
Here is the error:
C:/Ruby21/lib/ruby/2.1.0/net/http/response.rb:357:in `finish': buffer error (Zlib::BufError)
from C:/Ruby21/lib/ruby/2.1.0/net/http/response.rb:357:in `finish'
from C:/Ruby21/lib/ruby/2.1.0/net/http/response.rb:262:in `ensure in inflater'
from C:/Ruby21/lib/ruby/2.1.0/net/http/response.rb:262:in `inflater'
from C:/Ruby21/lib/ruby/2.1.0/net/http/response.rb:274:in `read_body_0'
from C:/Ruby21/lib/ruby/2.1.0/net/http/response.rb:201:in `read_body'
from C:/Ruby21/lib/ruby/2.1.0/net/http/response.rb:226:in `body'
from C:/Ruby21/lib/ruby/2.1.0/net/http/response.rb:163:in `reading_body'
from C:/Ruby21/lib/ruby/2.1.0/net/http.rb:1420:in `block in transport_request'
from C:/Ruby21/lib/ruby/2.1.0/net/http.rb:1411:in `catch'
from C:/Ruby21/lib/ruby/2.1.0/net/http.rb:1411:in `transport_request'
from C:/Ruby21/lib/ruby/2.1.0/net/http.rb:1384:in `request'
from C:/Ruby21/lib/ruby/2.1.0/net/http.rb:509:in `block in post_form'
from C:/Ruby21/lib/ruby/2.1.0/net/http.rb:853:in `start'
from C:/Ruby21/lib/ruby/2.1.0/net/http.rb:583:in `start'
from C:/Ruby21/lib/ruby/2.1.0/net/http.rb:507:in `post_form'
from C:/Users/KVadher/Desktop/test151:11:in `<main>'
Is there anything I can do to either solve the error or run past it?
There is something wrong with the way this API server is encoding the data. To bypass this, you can simple say in the HTTP header that you don't accept any kind of encoding:
opener = open(fullurl, 'Accept-Encoding' => '') {|f| f.read }

Error while using Net::HTTP GET request

I am new to ruby . I have the following Code snippet which performs a GET operation and retrieves the names of my facebook groups
def get_groups
query=("SELECT gid,name FROM group where gid in(SELECT gid from group_member where uid=me)")
uri=URI("https://graph.facebook.com/fql")
params={'q'=>query,'access_token'=>TOKEN}
uri.query=URI.encode_www_form(params)
response=Net::HTTP.get_response(uri)
result=json.loads(response.text)
return result['data']
end
But when I execute the above code I get the following errors:
/usr/lib/ruby/1.9.1/net/protocol.rb:141:in `read_nonblock': Connection reset by peer (Errno::ECONNRESET)
from /usr/lib/ruby/1.9.1/net/protocol.rb:141:in `rbuf_fill'
from /usr/lib/ruby/1.9.1/net/protocol.rb:122:in `readuntil'
from /usr/lib/ruby/1.9.1/net/protocol.rb:132:in `readline'
from /usr/lib/ruby/1.9.1/net/http.rb:2562:in `read_status_line'
from /usr/lib/ruby/1.9.1/net/http.rb:2551:in `read_new'
from /usr/lib/ruby/1.9.1/net/http.rb:1319:in `block in transport_request'
from /usr/lib/ruby/1.9.1/net/http.rb:1316:in `catch'
from /usr/lib/ruby/1.9.1/net/http.rb:1316:in `transport_request'
from /usr/lib/ruby/1.9.1/net/http.rb:1293:in `request'
from /usr/lib/ruby/1.9.1/net/http.rb:1195:in `request_get'
from /usr/lib/ruby/1.9.1/net/http.rb:455:in `block in get_response'
from /usr/lib/ruby/1.9.1/net/http.rb:745:in `start'
from /usr/lib/ruby/1.9.1/net/http.rb:454:in `get_response'
from fb.rb:12:in `get_groups'
from fb.rb:32:in `<main>'
What is the mistake that I am making here?
I believe the issue here is you're using an HTTP library to access an HTTPS service. These are fundamentally different things. Here's an HTTPS example:
require 'net/http'
require 'net/https'
http = Net::HTTP.new('www.example.com', 443)
http.use_ssl = true
http.ssl_version = :TLSv1
http.ciphers = "ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:-LOW"
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
req = Net::HTTP::Get.new('/', {'Content-Type' =>'application/json'})
http.start {|http| http.request(req) }
It seems like you have SSL certificate validation issue. Try to turn off SSL validation.
Net::HTTP.verify_mode = OpenSSL::SSL::VERIFY_NONE
If above helps you, possible root of the issue is current OpenSSL installation. Try to update it to the latest version.

How to use Ruby's XMLRPC::Client::new3

I'm trying to sort out how to use the new3 method of the XMLRPC::Client class. This is what I have:
#!/usr/bin/ruby
require "xmlrpc/client"
params = {
host: "https://192.168.1.2",
path: "rpc/api",
port: "443",
proxy_host: "",
proxy_port: "",
user: "username",
password: "password",
use_ssl: "true",
timeout: 300,
}
session = XMLRPC::Client.new3(params)
session.instance_variable_get(:#http).instance_variable_set(:#verify_mode, OpenSSL::SSL::VERIFY_NONE)
sys_ver = session.call('api.systemVersion')
users = session.call("user.listUsers", session)
If I use the new2 method the script will connect and return a 404 error. However, if I use the new3 it returns
/usr/lib/ruby/1.9.1/net/http.rb:762:in `initialize': Connection refused - connect(2) (Errno::ECONNREFUSED)
from /usr/lib/ruby/1.9.1/net/http.rb:762:in `open'
from /usr/lib/ruby/1.9.1/net/http.rb:762:in `block in connect'
from /usr/lib/ruby/1.9.1/timeout.rb:68:in `timeout'
from /usr/lib/ruby/1.9.1/timeout.rb:99:in `timeout'
from /usr/lib/ruby/1.9.1/net/http.rb:762:in `connect'
from /usr/lib/ruby/1.9.1/net/http.rb:755:in `do_start'
from /usr/lib/ruby/1.9.1/net/http.rb:750:in `start'
from /usr/lib/ruby/1.9.1/xmlrpc/client.rb:535:in `do_rpc'
from /usr/lib/ruby/1.9.1/xmlrpc/client.rb:420:in `call2'
from /usr/lib/ruby/1.9.1/xmlrpc/client.rb:410:in `call'
from sat_test.rb:24:in `<main>'
Am I using the new3 method properly?
Also, if I use the new method instead, do I need to set parameter=value for each parameter (proxy_host=, proxy_port=, etc)?
The problem seemed to be more with my script being coded wrong. This is what I have now:
#!/usr/bin/ruby
require "xmlrpc/client"
params = {
host: "REDACTED",
path: "/rpc/api",
use_ssl: "true",
user: "REDACTED",
pass: "REDACTED"
}
client = XMLRPC::Client.new3(params)
client.instance_variable_get(:#http).instance_variable_set(:#verify_mode, OpenSSL::SSL::VERIFY_NONE)
session = client.call('auth.login', params[:user], params[:pass])
sys_ver = session.call('api.systemVersion', session)
users = session.call("user.listUsers", session)
users.each { |uname| puts uname }
I've removed unnecessary arguments in the params hash and made sure everything is properly quoted.
It works and is only leaving me with a 404 error which is a problem with the script. But, at least it connects now and gives me something.

Send email via Ruby code on Heroku

I'm having problems sending email via my Ruby code. You can see my full code on GitHub.
UPDATE: the below code has been amended to reflect suggestions from #Gaurish
UPDATE2: looks like gmail refused the login attempt - I received an email from them to warn me some unknown application tried to access my account but they disabled it
The specific class is here:
require 'net/smtp'
=begin
http://apidock.com/ruby/v1_9_3_125/Net/SMTP/start/class
https://devcenter.heroku.com/articles/config-vars
I added the following config vars to Heroku
heroku config:add GM_USR=xxxx
heroku config:add GM_PSW=xxxx
=end
class Email
def initialize (to, from, subject, body)
#to = to
#from = from
#subject = subject
#body = body
#message = <<MESSAGE_CONTENT
From: User <#{#from}>
To: Integralist <#{#to}>
MIME-Version: 1.0
Content-type: text/html
Subject: #{#subject}
#{#body}
MESSAGE_CONTENT
#smtp = Net::SMTP.new('smtp.gmail.com', 587)
end
def send_email
#smtp.enable_starttls
#smtp.start('furious-wind-9309.herokuapp.com', ENV['GM_USR'], ENV['GM_PSW'], :login) do |smtp|
#smtp.send_message(#message, #from, #to)
end
end
end
I'm calling it like so:
email = Email.new('myemail#gmail.com', params[:email], 'test subject', params[:message]);
email.send_mail
But when I execute the code I get the error displayed on screen: 535-5.7.1 Please log in with your web browser and then try again. Learn more at
I checked the logs and I get...
2012-06-13T08:01:08+00:00 heroku[router]: POST furious-wind-9309.herokuapp.com/contact dyno=web.1 queue=0 wait=0ms service=628ms status=500 bytes=2060
2012-06-13T08:01:08+00:00 app[web.1]: /app/vendor/bundle/ruby/1.9.1/gems/rack-protection-1.2.0/lib/rack/protection/xss_header.rb:22:in `call'
2012-06-13T08:01:08+00:00 app[web.1]: /app/vendor/bundle/ruby/1.9.1/gems/rack-1.4.1/lib/rack/session/abstract/id.rb:200:in `call'
2012-06-13T08:01:08+00:00 app[web.1]: /app/vendor/bundle/ruby/1.9.1/gems/rack-1.4.1/lib/rack/session/abstract/id.rb:205:in `context'
2012-06-13T08:01:08+00:00 app[web.1]: /app/vendor/bundle/ruby/1.9.1/gems/rack-1.4.1/lib/rack/logger.rb:15:in `call'
2012-06-13T08:01:08+00:00 app[web.1]: /app/vendor/bundle/ruby/1.9.1/gems/rack-1.4.1/lib/rack/commonlogger.rb:20:in `call'
2012-06-13T08:01:08+00:00 app[web.1]: /app/vendor/bundle/ruby/1.9.1/gems/rack-1.4.1/lib/rack/head.rb:9:in `call'
2012-06-13T08:01:08+00:00 app[web.1]: /app/vendor/bundle/ruby/1.9.1/gems/rack-1.4.1/lib/rack/methodoverride.rb:21:in `call'
2012-06-13T08:01:08+00:00 app[web.1]: /app/vendor/bundle/ruby/1.9.1/gems/sinatra-1.3.2/lib/sinatra/base.rb:1334:in `block in call'
2012-06-13T08:01:08+00:00 app[web.1]: /app/vendor/bundle/ruby/1.9.1/gems/sinatra-1.3.2/lib/sinatra/base.rb:1416:in `synchronize'
2012-06-13T08:01:08+00:00 app[web.1]: /app/vendor/bundle/ruby/1.9.1/gems/sinatra-1.3.2/lib/sinatra/base.rb:1334:in `call'
2012-06-13T08:01:08+00:00 app[web.1]: /app/vendor/bundle/ruby/1.9.1/gems/thin-1.3.1/lib/thin/connection.rb:80:in `block in pre_process'
2012-06-13T08:01:08+00:00 app[web.1]: /app/vendor/bundle/ruby/1.9.1/gems/thin-1.3.1/lib/thin/connection.rb:78:in `catch'
2012-06-13T08:01:08+00:00 app[web.1]: /app/vendor/bundle/ruby/1.9.1/gems/thin-1.3.1/lib/thin/connection.rb:78:in `pre_process'
2012-06-13T08:01:08+00:00 app[web.1]: /app/vendor/bundle/ruby/1.9.1/gems/eventmachine-0.12.10/lib/eventmachine.rb:1060:in `call'
2012-06-13T08:01:08+00:00 app[web.1]: /app/vendor/bundle/ruby/1.9.1/gems/eventmachine-0.12.10/lib/eventmachine.rb:1060:in `block in spawn_threadpool'
2012-06-13T08:01:08+00:00 app[web.1]: 82.69.39.185 - - [13/Jun/2012 08:01:08] "POST /contact HTTP/1.1" 500 2060 0.6254
I know people will likely suggest ActionMailer or Pony, but I'd rather not use those or have those suggested to me please. I'd instead like a solution that helps fix the above code instead.
[Update 1]
If gmail doesn't work for you, you can use SendGrid Addon which gives you upto 200emails per day at no charge.
Here is a sample(taken from docs) on how to use their STMP API with mail gem
require 'mail'
Mail.defaults do
delivery_method :smtp, { :address => "smtp.sendgrid.net",
:port => 587,
:domain => "yourdomain.com",
:user_name => "yourusername#domain.com",
:password => "yourPassword",
:authentication => 'plain',
:enable_starttls_auto => true }
end
mail = Mail.deliver do
to 'yourRecipient#domain.com'
from 'Your Name <name#domain.com>'
subject 'This is the subject of your email'
text_part do
body 'Hello world in text'
end
html_part do
content_type 'text/html; charset=UTF-8'
body '<b>Hello world in HTML</b>'
end
end
Using Sendgrid is much better solution because you also get access Advanced reporting & analyticss which are not available with gmail. Also, there is no restriction on "from" addresses in sendgrid.
With Heroko, you can't send emails directly from localhost because Heroku does not provide an outgoing mail service.
so you will have to consider an external smtp server for sending your emails. popular ones are Gmail & Sendgrid
this is just one trade-off of using a cloud computing platform like heroku.
With Gmail, try doing something like this:
require 'net/smtp'
msg = "your message goes here"
smtp = Net::SMTP.new 'smtp.gmail.com', 587
smtp.enable_starttls
smtp.start(YourDomain, YourAccountName, YourPassword, :login) do
smtp.send_message(msg, FromAddress, ToAddress)
end
If you try:
#email = Email.new('mark.mcdx#gmail.com', params[:email], 'test subject', params[:message])
#email.send_email
Just load up SendGrid as an add-on and it works right out of the box. Plus you get a whole suite of analytics for troubleshooting bounces, deliveries, etc...

Resources