ruby rest-client ipv6 request failure with Apache 2.2.31 - ruby

I've been stuck with this for about two days...
I use ruby(version 2.3.3p222) gem rest-client(v2.0.0) to send a GET request with a ipv6 url to the server (Apache/2.2.31):
url = 'https://[fd36:4928:8040:dc10:0000:0000:0000:0160]:8080/resources/1'
resource = RestClient::Resource.new(url, :ssl_version => 'TLSv1', :verify_ssl => false, :headers => {'Authorization' => 'Basic cm9vdDAbCdEfwYXNzMSE='})
resource.get
I got a 400 bad response and the body says:"Your browser sent a request that this server could not understand. Additionally, a 400 Bad Request error was encountered while trying to use an ErrorDocument to handle the request"
However I can use curl command with the same parameters and get the right response, so I suspect maybe it's something wrong with the header of my rest-client request.
PS: I also tested with adding the 'host'
header: {'Authorization' => 'Basic cm9vdDAbCdEfwYXNzMSE=', 'host' => '[fd36:4928:8040:dc10:0000:0000:0000:0160]:8080' }
It still failed with the same bad response.
I just noticed the appache error for this request, it says:
"httpd[29124]: [error] Hostname fd36:4928:8040:dc10:0000:0000:0000:0160 provided via SNI and hostname fd36:4928:8040:dc10:0000:0000:0000 provided via HTTP are different
"

The curl command you supplied would translate --user admin:password into the following header:
Authorization: Basic YWRtaW46cGFzc3dvcmQ=
However, you're sending
Basic: cm9vdDAbCdEfwYXNzMSE=
which is not the same thing... so the server is probably complaining about not getting the correct auth...

After debugging and googling for another day, this problem seems to be clear:
From a similar bug report to chrome https://bugs.chromium.org/p/chromium/issues/detail?id=500981, "SNI is only hostnames, and should never contain IPs.". However ruby does use ip as hostname (in this case rest-client is nothing to blame since it just delegate everything down to ruby lib). You can find evidence in Net::HTTP#connect (around line 922):
# Server Name Indication (SNI) RFC 3546
s.hostname = #address if s.respond_to? :hostname=
Just comment out the last line it will work (to workaround this you have to do a monkey patch). Additionally, as pointed out by #alberge, host header does not contain brackets, the final request host header is like this: "FD36:4928:8040:DC10::162", no "[ ]" around.
Also on Apache side, it does something wrong since it just strips off everything from the last colon to get the host name without any extra check- this still exists in version 2.4.10, not sure if it is fixed or not.

This appears to be either a bug in rest-client or a regression in Ruby Net::HTTP.
https://github.com/rest-client/rest-client/issues/583
What version of Ruby are you using? Have you tried using Ruby 2.1 to see if it works there?
EDIT:
This is Ruby Bug #12642. The Host header for an IPv6 address is sent with no enclosing [ ].
Ruby in 2.1.6 - 2.1.10 doesn't have the bug, but versions >= 2.2.0 are affected.
And worse still, there's a bug with setting an explicit IPv6 Host header so you get an exception URI::InvalidComponentError: bad component(expected host component): [

Related

Failure/Error: $driver.navigate.to ENV['URL'] in ruby

While running the test case in the terminal with headless = true. I am getting the below error message.
Error message
Please find the details below:
I am using chromedriver version 86 with chrome browswer version 86 and same has been updated in .env file.
Also, I am running the scripts with Ubuntu in windows.
The error, ERR_NAME_NOT_RESOLVED means that the URL could not be resolved into an IP address. Most likely, ENV['URL'] is not returning a valid URL, there is a typo in the hostname, or it is referencing a private host that the script's DNS cannot resolve. Consider temporarily adding some debugging information, such as
url = ENV['URL']
STDERR.puts "Navigating to [#{url}]"
$driver.navigate.to url
or using Pry to pause your code, and check to make sure things are as you expect:
require 'pry'; binding.pry
$driver.navigate.to ENV['URL']
From the Pry shell, you can see what ENV['URL'] evaluates to, and also manually drive the $driver to see if it works as you expect.
If the URL in fact seems correct, then the issue is likely related to a private host and DNS issue. Ensure you can navigate to the url by other means on that same server (if it's a server, consider trying to ping the hostname, or use curl or wget for a quick check).

Rest-Client gem RoR, Getting SSL wrong version error

I want to build a cli ruby app which sends requests to Rails API server. I wanted to use rest-client gem to do that. Every time i use
RestClient.post
I get the following error
SSL_connect returned=1 errno=0 state=error: wrong version number (OpenSSL::SSL::SSLError)
Is there anything i can do for it to run from the console? The code is pretty simple, I just wanted to test out the feature, so don't worry, that's not final.
I am running rails 6.0.3, ruby 2.6.3.
require "tty-prompt"
prompt = TTY::Prompt.new
require 'rest-client'
if prompt.yes? "Do you have an account ?"
email = prompt.ask('What is your email?') do |q|
q.validate(/\A\w+#\w+\.\w+\Z/, 'Invalid email address')
end
pass = prompt.mask('password:')
puts email
puts pass
RestClient.post "https://localhost:3000/auth/sign_in", "email: #{email},password:#{pass}"
puts response.code
else
RestClient.post "https://localhost:3000/auth", "email: #{email},password:#{pass}"
end
I would like for the cli app to send a request to API, That's it, rest-client doesn't want to cooperate with me. Thank You :D
Likely the port 3000 you access is only http:// and not https://. Accessing a plain http:// port with https:// will cause the client to interpret the servers HTTP error message (since the beginning of the TLS handshake sent by the client was not valid HTTP) wrongly as HTTPS which can result in strange errors like invalid packet length or also wrong version number.

Getting random "read_nonblock': end of file reached (EOFError)" with Net::HTTP.start

When I execute the following code...
http = Net::HTTP.start('jigsaw.w3.org')
http.request_post('/css-validator/validator', ' ', 'Content-type' => "multipart/form-data")
...then I very often get the following error:
EOFError: end of file reached
from /Users/josh/.rvm/rubies/ruby-2.0.0-p353/lib/ruby/2.0.0/net/protocol.rb:153:in `read_nonblock'
Is this only me? What could be the problem? Sometimes it seems to work, but most of the time it doesn't.
The problem seems to be on the side of the host:
Loading http://jigsaw.w3.org/css-validator/DOWNLOAD.html manually in a browser results most of the time in "no data received" at the moment.
I'm trying to set up the downloadable command line version of the validator on my local machine and use this. More info here: How can I validate CSS on internal web pages?

How can I get Sinatra to set the content-length based on a static file's size?

I'm working on a Sinatra app and just started adding cacheing. Some of my files are cached correctly, but I keep seeing this warning when serving an image in the public folder:
WARN: Could not determine content-length of response body. Set
content-length of the response or set Response#chunked = true.
I don't understand why I'm getting this warning. Sinatra is serving the file correctly out of the public folder, and it says it defaults this header to the file size.
I'm using the following example settings from the README:
set :static_cache_control => [:public, :max_age => 60]
before do
cache_control :public, :must_revalidate, :max_age => 60
end
How can I get Sinatra to correctly set the content-length header to the static file's size?
Another workaround that removes the offending line from webrick. It's just not that useful:
cd `which ruby`/../../lib/ruby/1.9.1/webrick/ && sed -i '.bak' -e'/logger.warn/d' httpresponse.rb
(you may need to sudo)
Evidently, this message is safe to ignore.
See What does "WARN Could not determine content-length of response body." mean and how to I get rid of it?, or if you prefer to get the reply from the source, see the question posed at https://twitter.com/#!/luislavena/status/108998968859566080 and the answer at https://twitter.com/#!/tenderlove/status/108999110136303617.
A workaround: use thin
If the messages bother you, you can work around it by using thin. Add gem 'thin' to your Gemfile, then start your server using thin:
% bundle install
% rails server thin

Issues with HTTParty.post and Ruby 1.9.2

I used to have the following call working just fine on a Rails app running Ruby 1.8.7:
HTTParty.post("my uri", :body => "some body", :headers => { "Content-type" => "text/xml"})
When I run the same line on Ruby 1.9.2 I'm getting a MultiXml::ParseError with this message:
"xmlns: URI xyz is not absolute"
The call to my uri works just fine when I use curl, and I get back the expected response, which looks something like this:
<client login="foo" numsessions="1" xmlns="xyz"/>
Any Insight?
After much struggle, I gave up on HTTParty for this. I tried Patron, which worked local, but didn't on Heroku, and I finally settled on RestClient, which worked great. https://github.com/archiloque/rest-client
That's because curl doesn't try to parse the xmlns. You could either try making sure you use the same version of httparty with 1.9.2 as you use with 1.8.7 or asking the people in charge of that uri to make the xmlns valid

Resources