web-dev-qa-db-fra.com

EOFError: problème de fin de fichier atteint avec Net :: HTTP

J'utilise Ruby-1.8.7-p302/Rails 2.3.11. J'essaie d'utiliser FQL (API Facebook) pour obtenir des statistiques pour un lien. Voici mon code:

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

Et voici l'erreur:

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

Cela semble se produire uniquement dans le cas de l'API Facebook. De plus, je l'ai vu suggéré dans un post, cela pourrait être un bug dans Net :: HTTP.

143
Rahul Singh

Si l'URL utilise https au lieu de http, vous devez ajouter la ligne suivante:

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

Notez le supplément http.use_ssl = true _ .

Et le code le plus approprié, capable de gérer http et https, sera similaire au suivant.

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)

Voir plus dans mon blog: EOFError: problème de fin de fichier atteint lors de la publication d'un formulaire avec Net :: HTTP .

257
Sur Max

J'ai eu un problème similaire avec une demande à un service non-SSL.

Ce blog proposait vaguement d'essayer de coder en URI l'URL transmise à 'get': http://www.loudthinking.org/2010/02/Ruby-eoferror-end-of-file-reached.html

Je me suis lancée dans une tentative, basée sur le désespoir, et dans mes essais restrictifs, cela semble avoir réglé le problème pour moi. Mon nouveau code est:

@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) 

Notez que j'utilise @ http.start car je souhaite conserver la session HTTP sur plusieurs requêtes. Sinon, vous voudrez peut-être essayer la partie la plus pertinente, à savoir: URI.encode (url) dans l'appel à recevoir

5
Phil

Je constate que je rencontre régulièrement des problèmes Net :: HTTP et Net :: FTP comme celui-ci, et lorsque je le fais, entourer l'appel d'un délai d'attente () fait disparaître tous ces problèmes. Donc, cela risque de rester suspendu pendant 3 minutes environ, puis de déclencher un EOFError:

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

Cela le répare toujours pour moi:

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

J'ai eu le même problème, Ruby-1.8.7-p357, et j'ai essayé plein de choses en vain ...

J'ai finalement réalisé que cela ne se produit que lors d'appels multiples utilisant la même instance XMLRPC :: Client!

Alors maintenant, je ré-instancie mon client à chaque appel et cela fonctionne:

3
jobwat

Après quelques recherches, cela se passait dans la bibliothèque XMLRPC::Client De Ruby - qui utilise NET::HTTP. Le client utilise la méthode start() dans NET::HTTP, Qui maintient la connexion ouverte pour les futures demandes.

C’est ce qui s’est passé précisément 30 secondes après les dernières demandes. Je suppose donc que le serveur sur lequel il s’appuie ferme les demandes après ce moment. Je ne suis pas sûr de la valeur par défaut de NET::HTTP Pour maintenir la demande ouverte - mais je suis sur le point de tester avec 60 secondes pour voir si cela résout le problème.

1
TJ Biddle

Je me suis heurté récemment à cette situation et j'ai finalement découvert que cela était dû à un délai d'attente réseau sur le terminal que nous utilisions. Heureusement pour nous, nous avons pu augmenter la durée de temporisation.

Pour vérifier si c’était notre problème (et en réalité pas un problème avec net http), j’ai fait la même demande avec curl et confirmé que la demande était en cours de résiliation.

0
Tyler

Dans Ruby on Rails J'ai utilisé ce code et cela fonctionne parfaitement:

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é