web-dev-qa-db-ja.com

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のバグである可能性を示唆しているのを見ました。

143
Rahul Singh

URLがhttpではなくhttpsを使用している場合、次の行を追加する必要があります。

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'=>'[email protected]'})
http = Net::HTTP.new(url.Host, url.port)
http.use_ssl = (url.scheme == "https")
response = http.request(req)

私のブログで詳細を参照してください: EOFError:Net :: HTTPでフォームを投稿するとファイルの終わりに達した問題

257
Sur Max

非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.startを使用していることに注意してください。それ以外に、get呼び出し内で最も関連性の高い部分URI.encode(url)を試してみてください。

5
Phil

定期的にこのようなNet :: HTTPおよびNet :: FTPの問題が発生することがわかりました。その場合、呼び出しをtimeout()で囲むと、これらの問題がすべてなくなります。したがって、これが時々3分間ほどハングし、EOFErrorが発生する場合:

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

これは常に私のためにそれを修正します:

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

私は同じ問題、Ruby-1.8.7-p357を持っていて、無駄にたくさんのものを試しました...

最終的に、同じXMLRPC :: Clientインスタンスを使用する複数の呼び出しでのみ発生することに気付きました!

だから今、私は各呼び出しでクライアントを再インスタンス化していますが、それはちょうど動作します:|

3
jobwat

いくつかの研究を行った後、これはXMLRPC::Clientを使用するRubyのNET::HTTPライブラリで発生していました。クライアントは、NET::HTTPstart()メソッドを使用して、将来の要求のために接続を開いたままにします。

これは、最後のリクエストの30秒後に発生しました。したがって、ここでの私の推測は、ヒットしているサーバーがその時間の後にリクエストを閉じているということです。 NET::HTTPがリクエストを開いたままにするためのデフォルトがわからないが、60秒でテストして、問題が解決するかどうかを確認しようとしている。

1
TJ Biddle

最近、これに遭遇しましたが、最終的には、ヒットしているエンドポイントからのネットワークタイムアウトが原因であることがわかりました。幸いなことに、タイムアウト時間を長くすることができました。

これが私たちの問題(実際にはnet httpの問題ではない)であることを確認するために、curlで同じリクエストを行い、リクエストが終了していることを確認しました。

0
Tyler

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']
0
Nicolas Grenié