在我们的Rails应用程序中,我们有一个控制器操作,可以打开一个外部URL,并将其作为
JSON返回给我们的前端使用.
今天,我收到以下错误:
Errno :: EAFNOSUPPORT:协议不支持的地址族 – socket(2)
我们的devops建议如果地址返回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
docs for open-uri对IP版本一无所知.是否有一个参数可以传递给强制它读取IPv4的open方法,或者另一种处理方法?
编辑
当我尝试从控制台打开谷歌时,我得到了这个:
[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\"><p>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. </p>

<p>If you have a bone marrow disease,there are problems with the stem cells or how they develop. <a href=\"http://www.nlm.nih.gov/medlineplus/leukemia.html\">Leukemia</a> is a cancer in which the bone marrow produces abnormal white blood cells. With <a href=\"http://www.nlm.nih.gov/medlineplus/aplasticanemia.html\">aplastic anemia</a>,the bone marrow doesn't make red blood cells. Other diseases,such as <a href=\"http://www.nlm.nih.gov/medlineplus/lymphoma.html\">lymphoma</a>,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.</p> 

<p>Symptoms of bone marrow diseases vary. Treatments depend on the disorder and how severe it is. They might involve medicines,blood transfusions or a <a href=\"http://www.nlm.nih.gov/medlineplus/bonemarrowtransplantation.html\">bone marrow transplant</a>. </p>
 <p class=\"NLMrelatedLinks\"><ul><li><a href=\"http://www.nlm.nih.gov/medlineplus/ency/article/003658.htm\">Bone marrow aspiration</a></li><li><a href=\"http://www.nlm.nih.gov/medlineplus/ency/article/003934.htm\">Bone marrow biopsy</a></li><li><a href=\"http://www.nlm.nih.gov/medlineplus/ency/article/003682.htm\">Bone marrow culture</a></li><li><a href=\"http://www.nlm.nih.gov/medlineplus/ency/article/003009.htm\">Bone marrow transplant</a></li><li><a href=\"http://www.nlm.nih.gov/medlineplus/ency/patientinstructions/000010.htm\">Bone marrow transplant - discharge</a></li><li><a href=\"http://www.nlm.nih.gov/medlineplus/ency/article/000589.htm\">Polycythemia vera</a></li><li><a href=\"http://www.nlm.nih.gov/medlineplus/ency/article/000531.htm\">Primary myelofibrosis</a></li></ul></p></summary></entry></Feed> \n\n"
也就是说,它将HTML作为字符串返回,就像您期望的那样.
解决方法
看来你需要更新的ruby,见
ruby bug report
你可以“强制”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