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
Кажется, это происходит только в случае API Facebook. Кроме того, я заметил, что в некоторых постах это может быть ошибкой в Net :: HTTP.
Ответы
Ответ 1
Если 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'=>'[email protected]'})
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = (url.scheme == "https")
response = http.request(req)
Еще в моем блоге: EOFError: проблема с окончанием файла при отправке формы с помощью Net:: HTTP.
Ответ 2
У меня была аналогичная проблема с запросом к службе, отличной от SSL.
Этот блог предложил смутно попробовать кодировать URI URL-адрес, который передается "get": 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
Ответ 3
У меня была такая же проблема, ruby-1.8.7-p357, и я много чего перепробовал...
Я наконец понял, что это происходит только при нескольких вызовах, использующих один и тот же экземпляр XMLRPC :: Client!
Так что теперь я заново создаю экземпляр моего клиента при каждом вызове, и он просто работает: |
Ответ 4
Я нахожу, что периодически сталкиваюсь с проблемами Net:: HTTP и Net:: FTP, и когда я это делаю, окружающий вызов с таймаутом() заставляет все эти проблемы исчезать. Итак, где это будет время от времени висеть в течение 3 минут или около того, а затем поднять EOFError:
res = Net::HTTP.post_form(uri, args)
Это всегда исправляет это для меня:
res = timeout(120) { Net::HTTP.post_form(uri, args) }
Ответ 5
После некоторых исследований это произошло в библиотеке Ruby XMLRPC::Client
которая использует NET::HTTP
. Клиент использует метод start()
в NET::HTTP
который сохраняет соединение открытым для будущих запросов.
Это произошло ровно через 30 секунд после последних запросов - поэтому я предполагаю, что сервер, к которому он обращается, закрывает запросы по истечении этого времени. Я не уверен, что по умолчанию для NET::HTTP
держать запрос открытым - но я собираюсь протестировать с 60 секундами, чтобы увидеть, решит ли это проблему.
Ответ 6
В 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']
Ответ 7
Я столкнулся с этим недавно и в конце концов обнаружил, что это было вызвано сетевым тайм-аутом с конечной точки, на которую мы попали. К счастью для нас, мы смогли увеличить продолжительность тайм-аута.
Чтобы убедиться, что это наша проблема (а на самом деле не проблема с net http), я сделал тот же запрос с помощью curl и подтвердил, что запрос был прерван.