EOFError: 文件末尾到达 Net::HTTP 问题

Posted

技术标签:

【中文标题】EOFError: 文件末尾到达 Net::HTTP 问题【英文标题】:EOFError: end of file reached issue with Net::HTTP 【发布时间】:2011-07-11 19:42:12 【问题描述】:

我正在使用 ruby​​-1.8.7-p302/Rails 2.3.11。我正在尝试使用 FQL(Facebook API)来获取链接的统计信息。这是我的代码:

def stats(fb_post_url)
  url = BASE_URI + "?query=#URI.encode("select like_count from link_stat where url=\"#fb_post_url\"")"
  parsed_url = URI.parse(url)
  http = Net::HTTP.new(parsed_url.host, parsed_url.port)
  request = Net::HTTP::Get.new(parsed_url.request_uri)

  response = http.request(request)
  response.inspect
end

这是错误:

EOFError: end of file reached
from /home/rahul/.rvm/rubies/ruby-1.8.7-p302/lib/ruby/1.8/net/protocol.rb:135:in `sysread'
from /home/rahul/.rvm/rubies/ruby-1.8.7-p302/lib/ruby/1.8/net/protocol.rb:135:in `rbuf_fill'
from /home/rahul/.rvm/rubies/ruby-1.8.7-p302/lib/ruby/1.8/timeout.rb:67:in `timeout'
from /home/rahul/.rvm/rubies/ruby-1.8.7-p302/lib/ruby/1.8/timeout.rb:101:in `timeout'
from /home/rahul/.rvm/rubies/ruby-1.8.7-p302/lib/ruby/1.8/net/protocol.rb:134:in `rbuf_fill'
from /home/rahul/.rvm/rubies/ruby-1.8.7-p302/lib/ruby/1.8/net/protocol.rb:116:in `readuntil'
from /home/rahul/.rvm/rubies/ruby-1.8.7-p302/lib/ruby/1.8/net/protocol.rb:126:in `readline'
from /home/rahul/.rvm/rubies/ruby-1.8.7-p302/lib/ruby/1.8/net/http.rb:2028:in `read_status_line'
from /home/rahul/.rvm/rubies/ruby-1.8.7-p302/lib/ruby/1.8/net/http.rb:2017:in `read_new'
from /home/rahul/.rvm/rubies/ruby-1.8.7-p302/lib/ruby/1.8/net/http.rb:1051:in `request'
from /home/rahul/.rvm/rubies/ruby-1.8.7-p302/lib/ruby/1.8/net/http.rb:1037:in `request'
from /home/rahul/.rvm/rubies/ruby-1.8.7-p302/lib/ruby/1.8/net/http.rb:543:in `start'
from /home/rahul/.rvm/rubies/ruby-1.8.7-p302/lib/ruby/1.8/net/http.rb:1035:in `request'
from /home/rahul/Work/Radr/lib/fb_stats.rb:13:in `stats'
from (irb):10

这似乎只发生在 Facebook API 的情况下。另外,我在一些帖子中看到它建议这可能是 Net::HTTP 中的一个错误。

【问题讨论】:

您找到解决方案了吗?我在 SFDC API 中遇到了类似的问题。 【参考方案1】:

我最近遇到了这个问题,最终发现这是由我们所访问的端点的网络超时引起的。对我们来说幸运的是,我们能够增加超时时间。

为了验证这是我们的问题(实际上不是 net http 的问题),我使用 curl 发出了相同的请求,并确认该请求已被终止。

【讨论】:

【参考方案2】:

在做了一些研究之后,这发生在 Ruby 的 XMLRPC::Client 库中——它使用了 NET::HTTP。客户端使用NET::HTTP 中的start() 方法保持连接打开以供将来的请求。

这恰好发生在最后一个请求之后的 30 秒 - 所以我在这里的假设是它所访问的服务器在那之后关闭请求。我不确定NET::HTTP 保持请求打开的默认值是什么 - 但我将在 60 秒内进行测试,看看是否能解决问题。

【讨论】:

结果如何?【参考方案3】:

我遇到了同样的问题,ruby-1.8.7-p357,但尝试了很多东西都徒劳...

我终于意识到,它只发生在使用同一个 XMLRPC::Client 实例的多个调用中!

所以现在我在每次通话时都重新实例化我的客户,它就可以正常工作:|

【讨论】:

【参考方案4】:

在 Ruby on Rails 中,我使用了这段代码,它运行良好:

req_profilepic = ActiveSupport::JSON.decode(open(URI.encode("https://graph.facebook.com/me/?fields=picture&type=large&access_token=#fb_access_token")))

profilepic_url = req_profilepic['picture']

【讨论】:

【参考方案5】:

如果 URL 使用 https 而不是 http,则需要添加以下行:

parsed_url = URI.parse(url)
http = Net::HTTP.new(parsed_url.host, parsed_url.port)
http.use_ssl = true

注意额外的http.use_ssl = true

处理 http 和 https 的更合适的代码将类似于以下代码。

url = URI.parse(domain)
req = Net::HTTP::Post.new(url.request_uri)
req.set_form_data('name'=>'Sur Max', 'email'=>'some@email.com')
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = (url.scheme == "https")
response = http.request(req)

在我的博客中查看更多信息:EOFError: end of file reached issue when post a form with Net::HTTP。

【讨论】:

谢谢,这帮助我理解了httpreq 之间的区别。 博文链接失效了,试试这个:web.archive.org/web/20150429191916/http://expressica.com/2012/… 如果不是https怎么办?【参考方案6】:

我发现我会定期遇到这样的 Net::HTTP 和 Net::FTP 问题,当我这样做时,用 timeout() 包围调用会使所有这些问题都消失。因此,这偶尔会挂起 3 分钟左右,然后引发 EOFError:

res = Net::HTTP.post_form(uri, args)

这总是为我解决问题:

res = timeout(120)  Net::HTTP.post_form(uri, args) 

【讨论】:

【参考方案7】:

我在请求非 SSL 服务时遇到了类似的问题。

此博客含糊地建议尝试对传递给“get”的 URL 进行 URI 编码:http://www.loudthinking.org/2010/02/ruby-eoferror-end-of-file-reached.html

出于绝望,我尝试了它,在我的极限测试中,这似乎已经为我解决了问题。我的新代码是:

@http = Net::HTTP.new('domain.com')  
@http = @http.start    
url = 'http://domain.com/requested_url?blah=blah&etc=1'
req = Net::HTTP::Get.new(URI.encode(url))
req.basic_auth USERNAME, API_KEY
res = @http.request(req) 

请注意,我使用@http.start 是因为我想通过多个请求维护 HTTP 会话。除此之外,您可能想尝试最相关的部分:URI.encode(url) 在 get 调用中

【讨论】:

我只是想就此提供一些额外的反馈,因为它似乎仍然有用。我已经在生产服务器上使用这个编码的 URI 运行了 4 个月,我可以确认它已经解决了问题。

以上是关于EOFError: 文件末尾到达 Net::HTTP 问题的主要内容,如果未能解决你的问题,请参考以下文章

Rails 4:EOFError:仅在开发中的任何电子邮件后到达文件结尾

Ruby 邮件程序出现 EOFError

Python:显式退出和简单地让执行到达文件末尾有啥区别?

ifstream.eof() - 在真正结束之前到达文件末尾

如何在 Access 中快速滚动并到达组合框的末尾

SQL 命令在到达大型 csv 文件末尾之前终止