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

我使用的是 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 中的一个 bug。

122811 次浏览

在 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']

如果 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: 使用 Net: : HTTP 发送表单时到达问题文件的末尾

我在对非 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。开始,因为我想在多个请求上维护 HTTP 会话。除此之外,您可能希望尝试最相关的部分,即 get 调用中的 Encode (url)

我也有同样的问题,Ruby-1.8.7-p357,我尝试了很多东西,但都是徒劳的..。

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

因此,现在我在每次调用时都重新实例化我的客户端,它就是这样工作的: |

在做了一些研究之后,Ruby 的 XMLRPC::Client库发生了这种情况——它使用 NET::HTTP。客户端使用 NET::HTTP中的 start()方法,它保持连接对未来请求是开放的。

这恰好发生在最后一次请求之后的30秒——因此我在这里假设它所访问的服务器在这段时间之后正在关闭请求。我不确定 NET::HTTP保持请求打开的默认设置是什么——但我将在60秒内进行测试,看看这是否解决了问题。

我发现我会周期性地遇到 Net: : HTTP 和 Net: : FTP 问题,当我遇到这样的问题时,在调用周围使用 timeout ()会使所有这些问题消失。因此,这将偶尔挂起3分钟左右,然后出现一个 EOFError:

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

这总能帮我解决问题:

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

我最近碰到了这个问题,最终发现这是由于我们正在攻击的端点的网络超时造成的。幸运的是,我们能够增加超时时间。

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