EOFError: la fine del file ha raggiunto il problema con Net :: HTTP


158

Sto usando ruby-1.8.7-p302 / Rails 2.3.11. Sto cercando di utilizzare FQL (API di Facebook) per ottenere statistiche per un collegamento. Ecco il mio codice:

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

Ed ecco l'errore:

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

Questo sembra accadere solo nel caso dell'API di Facebook. Inoltre, ho visto suggerire che in alcuni post questo potrebbe essere un bug in Net :: HTTP.


3
Hai trovato una soluzione per questo? Sto affrontando un problema simile nell'API SFDC.
Nilesh,

Risposte:


281

Se l'URL utilizza https anziché http, è necessario aggiungere la seguente riga:

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

Nota l'ulteriore http.use_ssl = true.

E il codice più appropriato che gestirà sia http che https sarà simile al seguente.

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)

Vedi di più sul mio blog: EOFError: la fine del file ha raggiunto il problema quando si pubblica un modulo con Net :: HTTP .


Grazie, questo mi ha aiutato a capire la differenza tra il httpe req.
guptron,

6
Il link al post del blog è interrotto, ma prova questo: web.archive.org/web/20150429191916/http://expressica.com/2012/…
Henrik N

E se non fosse https?
Jwan622,

5

Ho avuto un problema simile con una richiesta a un servizio non SSL.

Questo blog ha suggerito vagamente di provare l'URI che codifica l'URL che viene passato a 'get': http://www.loudthinking.org/2010/02/ruby-eoferror-end-of-file-reached.html

Ci ho provato, basato sulla disperazione, e nei miei test limitanti questo sembra averlo risolto per me. Il mio nuovo codice è:

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

Nota che uso @ http.start per mantenere la sessione HTTP su più richieste. Oltre a questo, potresti provare la parte più rilevante che è: URI.encode (url) all'interno della chiamata get


2
Volevo solo fornire un feedback aggiuntivo su questo, poiché sembra ancora essere utile. Uso questo URI codificato su un server di produzione da 4 mesi e posso confermare che il problema è stato risolto.
Phil

3

Trovo che incontro periodicamente problemi di Net :: HTTP e Net :: FTP come questo, e quando lo faccio, circondare la chiamata con un timeout () fa svanire tutti questi problemi. Quindi, dove questo si bloccherà occasionalmente per circa 3 minuti e quindi solleverà un EOFError:

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

Questo lo risolve sempre per me:

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

3

Ho avuto lo stesso problema, ruby-1.8.7-p357, e ho provato un sacco di cose invano ...

Ho finalmente capito che succede solo su più chiamate usando la stessa istanza XMLRPC :: Client!

Quindi ora sto ri-istanziando il mio client ad ogni chiamata e funziona: |


1

Dopo aver fatto qualche ricerca, questo stava accadendo nella XMLRPC::Clientbiblioteca di Ruby - che usa NET::HTTP. Il client utilizza il start()metodo in NET::HTTPcui mantiene aperta la connessione per richieste future.

Questo è successo esattamente a 30 secondi dopo le ultime richieste, quindi la mia ipotesi qui è che il server che sta colpendo sta chiudendo le richieste dopo quel tempo. Non sono sicuro di quale sia l'impostazione predefinita per NET::HTTPmantenere aperta la richiesta, ma sto per testare con 60 secondi per vedere se questo risolve il problema.


1
Qual'era il risultato?
Peter Mortensen,

1

Mi sono imbattuto di recente in questo e alla fine ho scoperto che questo era causato da un timeout di rete dall'endpoint che stavamo colpendo. Fortunatamente per noi siamo stati in grado di aumentare la durata del timeout.

Per verificare che questo fosse il nostro problema (e in realtà non un problema con net http), ho fatto la stessa richiesta con curl e ho confermato che la richiesta era stata terminata.


-1

In Ruby on Rails ho usato questo codice e funziona perfettamente:

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']
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.