EOFError: akhir file mencapai masalah dengan Net :: HTTP

158

Saya menggunakan ruby-1.8.7-p302 / Rails 2.3.11. Saya mencoba menggunakan FQL (Facebook API) untuk mendapatkan statistik tautan. Ini kode saya:

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

Dan inilah kesalahannya:

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

Ini sepertinya hanya terjadi pada API Facebook. Juga, saya melihatnya disarankan dalam beberapa posting ini bisa menjadi bug di Net :: HTTP.

Rahul Singh
sumber
3
Apakah Anda menemukan solusi untuk ini? Saya menghadapi masalah serupa di API SFDC.
Nilesh

Jawaban:

281

Jika URL menggunakan https alih-alih http, Anda perlu menambahkan baris berikut:

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

Perhatikan tambahannya http.use_ssl = true.

Dan kode yang lebih tepat yang akan menangani http dan https akan mirip dengan yang berikut.

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)

Lihat lebih banyak di blog saya: EOFError: masalah akhir file saat mengirim formulir dengan Net :: HTTP .

Sur Max
sumber
Terima kasih, ini membantu saya memahami perbedaan antara httpdan req.
guptron
6
Tautan posting blog rusak, tetapi coba ini: web.archive.org/web/20150429191916/http
Henrik N
Bagaimana jika itu bukan https?
Jwan622
5

Saya memiliki masalah serupa dengan permintaan ke layanan non-SSL.

Blog ini menyarankan untuk mencoba URI menyandikan URL yang dilewatkan ke 'get': http://www.loudthinking.org/2010/02/ruby-eoferror-end-of-file-reached.html

Saya mengambil kesempatan itu, berdasarkan pada keputusasaan, dan dalam pengujian saya yang terbatas ini sepertinya telah memperbaikinya untuk saya. Kode baru saya adalah:

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

Perhatikan bahwa saya menggunakan @ http.start karena saya ingin mempertahankan sesi HTTP melalui beberapa permintaan. Selain itu, Anda mungkin ingin mencoba bagian yang paling relevan yaitu: URI.encode (url) di dalam panggilan masuk

Phil
sumber
2
Saya hanya ingin memberikan umpan balik tambahan tentang ini, karena tampaknya masih berguna. Saya telah menjalankan menggunakan URI yang disandikan ini pada server produksi selama 4 bulan dan saya dapat mengonfirmasi bahwa masalah tersebut telah diperbaiki.
Phil
3

Saya menemukan bahwa saya mengalami Net :: HTTP dan Net :: FTP masalah seperti ini secara berkala, dan ketika saya melakukannya, seputar panggilan dengan batas waktu () membuat semua masalah tersebut hilang. Jadi di mana ini kadang-kadang akan menggantung selama 3 menit atau lebih dan kemudian meningkatkan EOFError:

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

Ini selalu memperbaikinya untuk saya:

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

Saya memiliki masalah yang sama, ruby-1.8.7-p357, dan mencoba banyak hal dengan sia-sia ...

Saya akhirnya menyadari bahwa itu hanya terjadi pada beberapa panggilan menggunakan XMLRPC :: Klien contoh yang sama!

Jadi sekarang saya kembali instantiating klien saya di setiap panggilan dan hanya berfungsi: |

jobwat
sumber
1

Setelah melakukan beberapa penelitian, ini terjadi di XMLRPC::Clientperpustakaan Ruby - yang menggunakan NET::HTTP. Klien menggunakan start()metode NET::HTTPyang membuat koneksi tetap terbuka untuk permintaan di masa mendatang.

Ini terjadi tepat pada 30 detik setelah permintaan terakhir - jadi asumsi saya di sini adalah bahwa server yang dipukulnya sedang menutup permintaan setelah waktu itu. Saya tidak yakin untuk apa defaultnya NET::HTTPagar permintaan tetap terbuka - tapi saya akan menguji dengan 60 detik untuk melihat apakah itu menyelesaikan masalah.

TJ Biddle
sumber
1
Apakah hasilnya?
Peter Mortensen
1

Saya mengalami ini baru-baru ini dan akhirnya menemukan bahwa ini disebabkan oleh batas waktu jaringan dari titik akhir yang kami tekan. Untungnya bagi kami, kami dapat meningkatkan durasi waktu tunggu.

Untuk memverifikasi ini adalah masalah kami (dan sebenarnya bukan masalah dengan http net), saya membuat permintaan yang sama dengan curl dan mengkonfirmasi bahwa permintaan tersebut sedang dihentikan.

Tyler
sumber
-1

Di Ruby on Rails saya menggunakan kode ini, dan berfungsi dengan baik:

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