7

在我们的 Rails 应用程序中,我们有一个控制器操作,它打开一个外部 URL,并将其作为 JSON 返回以供我们的前端使用。

今天,我收到以下错误:

Errno::EAFNOSUPPORT: Address family not supported by protocol - socket(2)

我们的开发人员建议,如果地址返回 IPv6 响应和 IPv4 响应,这将是错误。我们不支持 IPv6,所以这可以解释。

这是触发请求的方法:

def medline_response
  open("http://apps.nlm.nih.gov/medlineplus/services/mpconnect_service.cfm?mainSearchCriteria.v.cs=#{codesys}&mainSearchCriteria.v.c=#{code}")
end

事实上,来自该服务器主机的响应:

$ host apps.nlm.nih.gov
apps.nlm.nih.gov is an alias for apps.wip.nlm.nih.gov.
apps.wip.nlm.nih.gov has address 130.14.16.117
apps.wip.nlm.nih.gov has IPv6 address 2607:f220:41e:1016::117

open-uri的文档没有说明 IP 版本。是否有一个参数可以传递给open强制它读取 IPv4 的方法,或者其他处理这个问题的方法?

编辑

当我尝试从控制台打开谷歌时,我得到了这个:

[18] pry(main)> require 'open-uri'
=> false
[19] pry(main)> open 'http://google.com'   
=> #<File:/var/folders/hq/7_rgkt4565q728y91dtqzs2r2wxb1y/T/open-uri20130913-50258-1af4zhv>

所以看起来 IPv6 地址不是问题。

编辑 2

$ ruby -v
ruby 1.9.3p385 (2013-02-06 revision 39114) [x86_64-darwin11.4.2]

OS X 10.7.5

编辑 3

这是每个人最喜欢的一种错误:间歇性错误。这是我在open-uri对象上调用 read 时发生的情况。我在本地和我们的所有 3 个应用程序服务器上都得到了相同的输出。

[22] pry(main)> open("http://apps.nlm.nih.gov/medlineplus/services/mpconnect_service.cfm?mainSearchCriteria.v.cs=2.16.840.1.113883.6.103&mainSearchCriteria.v.c=238.4").read
=> "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<feed xml:base=\"http://apps.nlm.nih.gov/medlineplus/services/\" xml:lang=\"en\" xmlns=\"http://www.w3.org/2005/Atom\" xmlns:v3=\"urn:hl7-org:v3\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><title type=\"text\">MedlinePlus Connect</title><subtitle type=\"text\">MedlinePlus Connect results for ICD-9-CM 238.4</subtitle><author><name>U.S. National Library of Medicine</name><uri>http://www.nlm.nih.gov</uri></author><updated type=\"text\">2013-09-13T12:09:48Z</updated><category scheme=\"REDS_MT010001UV\" term=\"MATCHED\"><v3:mainSearchCriteria classCode=\"OBS\" moodCode=\"DEF\" xmlns:v3=\"urn:hl7-org:v3\"><v3:code code=\"KSUBJ\" codeSystem=\"2.16.840.1.113883.5.4\" xmlns:v3=\"urn:hl7-org:v3\"/><v3:value code=\"238.4\" codeSystem=\"2.16.840.1.113883.6.103\" displayName=\"\" xmlns:v3=\"urn:hl7-org:v3\"/></v3:mainSearchCriteria><v3:informationRecipient typeCode=\"IRCP\" xmlns:v3=\"urn:hl7-org:v3\"><v3:patient classCode=\"PAT\" xmlns:v3=\"urn:hl7-org:v3\"/></v3:informationRecipient></category><id></id><entry><title>Bone Marrow Diseases</title><link href=\"http://www.nlm.nih.gov/medlineplus/bonemarrowdiseases.html\" rel=\"alternate\"/><id>tag: nlm.nih.gov, 2013-13-09:/medlineplus/bonemarrowdiseases.html</id><updated>2013-09-13T12:09:48Z</updated><summary type=\"html\">&lt;p&gt;Bone marrow is the spongy tissue inside some of your bones, such as your hip and thigh bones. It contains immature cells, called stem cells. The stem cells can develop into the red blood cells that carry oxygen through your body, the white blood cells that fight infections, and the platelets that help with blood clotting. &lt;/p&gt;&#xd;&#xd;&lt;p&gt;If you have a bone marrow disease, there are problems with the stem cells or how they develop. &lt;a href=\"http://www.nlm.nih.gov/medlineplus/leukemia.html\"&gt;Leukemia&lt;/a&gt; is a cancer in which the bone marrow produces abnormal white blood cells. With &lt;a href=\"http://www.nlm.nih.gov/medlineplus/aplasticanemia.html\"&gt;aplastic anemia&lt;/a&gt;, the bone marrow doesn't make red blood cells. Other diseases, such as &lt;a href=\"http://www.nlm.nih.gov/medlineplus/lymphoma.html\"&gt;lymphoma&lt;/a&gt;, can spread into the bone marrow and affect the production of blood cells.  Other causes of bone marrow disorders include your genetic makeup and environmental factors.&lt;/p&gt; &#xd;&#xd;&lt;p&gt;Symptoms of bone marrow diseases vary. Treatments depend on the disorder and how severe it is. They might involve medicines, blood transfusions or a &lt;a href=\"http://www.nlm.nih.gov/medlineplus/bonemarrowtransplantation.html\"&gt;bone marrow transplant&lt;/a&gt;. &lt;/p&gt;&#xd; &lt;p class=\"NLMrelatedLinks\"&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=\"http://www.nlm.nih.gov/medlineplus/ency/article/003658.htm\"&gt;Bone marrow aspiration&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=\"http://www.nlm.nih.gov/medlineplus/ency/article/003934.htm\"&gt;Bone marrow biopsy&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=\"http://www.nlm.nih.gov/medlineplus/ency/article/003682.htm\"&gt;Bone marrow culture&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=\"http://www.nlm.nih.gov/medlineplus/ency/article/003009.htm\"&gt;Bone marrow transplant&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=\"http://www.nlm.nih.gov/medlineplus/ency/patientinstructions/000010.htm\"&gt;Bone marrow transplant - discharge&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=\"http://www.nlm.nih.gov/medlineplus/ency/article/000589.htm\"&gt;Polycythemia vera&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=\"http://www.nlm.nih.gov/medlineplus/ency/article/000531.htm\"&gt;Primary myelofibrosis&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;</summary></entry></feed>  \n\n"

也就是说,它HTML以字符串的形式返回,就像您期望的那样。

4

1 回答 1

0

看来您需要更新的 ruby​​,请参阅ruby​​ 错误报告

您可以“强制”open-uri 使用 ip,例如:

require 'open-uri'
require 'socket'

url = "google.com"
ip = IPSocket::getaddress(url)

open("http://#{url}") do |f|
  puts "i'm using url #{url} #{f.base_uri}"
end
open("http://#{ip}") do |f|
  puts "i'm using ip #{ip} #{f.base_uri}"
end
于 2014-06-16T15:17:30.590 回答