EOFError:Net :: HTTPでファイルの終わりに達した問題


158

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


3
これに対する解決策を見つけましたか?SFDC APIで同様の問題に直面しています。
Nilesh

回答:


280

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'=>'some@email.com'})
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = (url.scheme == "https")
response = http.request(req)

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


おかげで、これは私が違いを理解する助けhttpとしますreq
guptron 2014

6
ブログ記事のリンクが壊れたが、これしようとされていますweb.archive.org/web/20150429191916/http://expressica.com/2012/...
ヘンリックN

httpsでない場合はどうなりますか?
Jwan622 2018年

5

非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)を試してみたい場合があります。


2
それはまだ有用であると思われるので、私はこれについていくつかの追加のフィードバックを提供したかっただけです。このエンコードされたURIを使用して実稼働サーバーで4か月間実行しており、問題が修正されたことを確認できます。
Phil

3

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

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

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

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

3

私は同じ問題を抱えていました、ruby-1.8.7-p357、そしてたくさんのことを無駄に試してみました...

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

だから今私はクライアントを毎回再インスタンス化していて、それはうまくいきます:|


1

いくつかの調査を行った後、これはRubyのXMLRPC::Clientライブラリで発生していました-を使用していますNET::HTTP。クライアントは、今後のリクエストのために接続を開いたままにするstart()方法を使用しNET::HTTPます。

これは、最後のリクエストから30秒後に正確に発生しました。つまり、ここで想定しているのは、ヒットしたサーバーがその時間後にリクエストを閉じているということです。NET::HTTPリクエストを開いたままにしておくためのデフォルトが何であるかはわかりませんが、60秒でテストして問題が解決するかどうかを確認します。


1
結果はどうでしたか?
Peter Mortensen、

1

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

これが私たちの問題であることを確認するために(実際にはnet httpの問題ではありません)、curlを使用して同じ要求を行い、要求が終了していることを確認しました。


-1

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']
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.