Ruby 2.3/Rails - 更新到 Ubuntu 16.04 后网络 uri 不再工作

Ruby 2.3/Rails - net uri not working anymore after update to Ubuntu 16.04

我以前在我的管理面板中有一个工作代码,检查输入的 url 是否存在,并在不存在的情况下向管理员发送友好消息..

def get_url_response(url)
    uri = URI(url)
    request = Net::HTTP.get_response(uri)
    return request
end

url_response = get_url_response("http://www.example.com").code
    if  url_response === "200" || url_response === "304"
       link_to http://www.example.com, http://www.example.com, target: :blank
    else                                                          
        status_tag("We have a problem ! Response code: "+url_response, :class => 'red')  
    end

地址 ("http://www.example.com" in the example above) exists, that it to say sends back a 200 code, but as soon as I have a non existing address such as http://www.examplenotexistingotallyfake.com 时效果很好,它应该发送 404 代码并显示 ""We have a problem ! Response code:" 但失败并显示错误消息:

SocketError: Failed to open TCP connection to examplenotexistingotallyfake.com:443 (getaddrinfo: Name or service not known)
from /home/mreisner/.rvm/rubies/ruby-2.3.1/lib/ruby/2.3.0/net/http.rb:882:in `rescue in block in connect'

我通过打开 Rails 控制台 (Rails c) 验证了这一点,如果我输入:

 Net::HTTP.get(URI('https://www.examplenotexistingotallyfake.com')).code

我收到同样的错误信息:

 SocketError: Failed to open TCP connection to examplenotexistingotallyfake.com:443 (getaddrinfo: Name or service not known)
from /home/mreisner/.rvm/rubies/ruby-2.3.1/lib/ruby/2.3.0/net/http.rb:882:in `rescue in block in connect'

它如何对正确的 url 起作用而不对不存在的地址起作用?它应该可以正常工作,但会给我发回 404 代码,不是吗?

我只能看到我几天前升级到 Ubutun 16.04,这可能篡改了一些关键的 dns/localhost 设置作为这个问题的根源,但不是 100% 完全确定。

编辑

经过一些建议,我现在尝试通过拯救这个来避免应用程序崩溃

def get_url_response(url)       
    begin
        uri = URI(url)
          request = Net::HTTP.get_response(uri)
          return request

        rescue SocketError => e
        puts "Got socket error: #{e}"
        end

  end

但应用程序仍然崩溃并显示套接字错误消息

这是正确的行为。

问题是 DNS 条目中不存在 examplenotexistingotallyfake.com

如果你看看404的描述是什么:https://en.wikipedia.org/wiki/HTTP_404

to indicate that the client was able to communicate with a given server, but the server could not find what was requested.

因此,为了获得 404 代码,您首先需要能够与相关服务器通信。

您可以使用 chrome 甚至 curl 仔细检查此行为,访问以下网址:examplenotexistingotallyfake.com 或 google.com/missing

每个都会给出不同的结果。

卷曲:

$ curl -I examplenotexistingotallyfake.com
curl: (6) Could not resolve host: examplenotexistingotallyfake.com

# google
curl -I google.com/missing
HTTP/1.1 404 Not Found
Content-Type: text/html; charset=UTF-8
Referrer-Policy: no-referrer
Content-Length: 1568
Date: Fri, 12 Jan 2018 09:25:27 GMT

如果您希望您的代码以相同的方式运行(即使我建议向用户提供不同的消息,您也可以执行以下操作):

require 'uri'
require 'net/http'
require 'ostruct'

def get_url_response(url)
  uri = URI(url)
  request = Net::HTTP.get_response(uri)
  return request
rescue Errno::ECONNREFUSED => e
  OpenStruct.new(code: 404)
end

这不是问题,您要查找的站点不存在且无法访问。

所以它会给出 DNS address is not found issue when you try hit it directly.Thats why the error: 直接给socketError : getaddrinfo: Name or service not known你需要处理这个

但是如果您想要 404 status code,您将在网站(地址)存在而该网站内的页面不存在时获得它。

要获取 404,您的地址应该有效,如果 The requested URL /examples was not found on this server.

,则会出现错误