EOFError: đã kết thúc sự cố với Net :: HTTP


158

Tôi đang sử dụng ruby-1.8.7-p302 / Rails 2.3.11. Tôi đang cố gắng sử dụng FQL (API Facebook) để lấy số liệu thống kê cho một liên kết. Đây là mã của tôi:

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

Và đây là lỗi:

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

Điều này dường như chỉ xảy ra trong trường hợp API Facebook. Ngoài ra, tôi thấy nó được đề xuất trong một số bài đăng này có thể là một lỗi trong Net :: HTTP.


3
Bạn đã tìm thấy giải pháp cho điều này? Tôi đang đối mặt với vấn đề tương tự trong API SFDC.
Nilesh

Câu trả lời:


280

Nếu URL đang sử dụng https thay vì http, bạn cần thêm dòng sau:

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

Lưu ý bổ sung http.use_ssl = true.

Và mã thích hợp hơn sẽ xử lý cả http và https sẽ tương tự như mã sau.

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)

Xem thêm trong blog của tôi: EOFError: cuối tập tin đã gặp sự cố khi đăng một biểu mẫu với Net :: HTTP .


Cảm ơn, điều này đã giúp tôi hiểu sự khác biệt giữa httpreq.
guptron

6
Liên kết bài đăng trên blog bị hỏng, nhưng hãy thử điều này: web.archive.org/web/20150429191916/http://expressica.com/2012/ Kẻ
Henrik N

Nếu nó không phải là https thì sao?
Jwan622

5

Tôi gặp vấn đề tương tự với yêu cầu dịch vụ không phải SSL.

Blog này gợi ý một cách mơ hồ để thử mã hóa URI URL được chuyển đến 'get': http://www.loudthinking.org/2010/02/ruby-eoferror-end-of-file-reached.html

Tôi đã bắn nó, dựa trên sự tuyệt vọng, và trong thử nghiệm giới hạn của tôi, điều này dường như đã sửa nó cho tôi. Mã mới của tôi là:

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

Lưu ý rằng tôi sử dụng @ http.start vì tôi muốn duy trì phiên HTTP qua nhiều yêu cầu. Ngoài ra, bạn có thể muốn thử phần có liên quan nhất đó là: URI.encode (url) bên trong cuộc gọi nhận


2
Tôi chỉ muốn cung cấp một số phản hồi bổ sung về điều này, vì nó dường như vẫn hữu ích. Tôi đã chạy bằng cách sử dụng URI được mã hóa này trên một máy chủ sản xuất trong 4 tháng và tôi có thể xác nhận rằng nó đã khắc phục vấn đề.
Phil

3

Tôi thấy rằng tôi gặp phải các sự cố Net :: HTTP và Net :: FTP như thế này theo định kỳ và khi tôi thực hiện, xung quanh cuộc gọi có thời gian chờ () làm cho tất cả các vấn đề đó biến mất. Vì vậy, nơi này đôi khi sẽ treo trong 3 phút hoặc lâu hơn và sau đó nâng EOFError:

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

Điều này luôn luôn sửa nó cho tôi:

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

3

Tôi gặp vấn đề tương tự, ruby-1.8.7-p357 và đã thử vô số thứ ...

Cuối cùng tôi đã nhận ra rằng nó chỉ xảy ra trên nhiều cuộc gọi bằng cùng một XMLRPC :: Client dụ!

Vì vậy, bây giờ tôi đang khởi tạo lại ứng dụng khách của mình tại mỗi cuộc gọi và nó chỉ hoạt động: |


1

Sau khi thực hiện một số nghiên cứu, điều này đã xảy ra trong XMLRPC::Clientthư viện của Ruby - nơi sử dụng NET::HTTP. Máy khách sử dụng start()phương thức NET::HTTPgiữ kết nối mở cho các yêu cầu trong tương lai.

Điều này xảy ra chính xác vào 30 giây sau các yêu cầu cuối cùng - vì vậy, giả định của tôi ở đây là máy chủ đang tấn công đang đóng các yêu cầu sau thời gian đó. Tôi không chắc chắn mặc định là gì NET::HTTPđể giữ yêu cầu mở - nhưng tôi sẽ thử nghiệm trong 60 giây để xem liệu điều đó có giải quyết được vấn đề không.


1
Thế kết quả là gì?
Peter Mortensen

1

Tôi đã gặp phải điều này gần đây và cuối cùng thấy rằng điều này là do thời gian chờ mạng từ điểm cuối mà chúng tôi đang gặp phải. May mắn thay cho chúng tôi, chúng tôi đã có thể tăng thời gian chờ.

Để xác minh đây là vấn đề của chúng tôi (và thực tế không phải là vấn đề với net http), tôi đã đưa ra yêu cầu tương tự với curl và xác nhận rằng yêu cầu đã bị chấm dứt.


-1

Trong Ruby on Rails tôi đã sử dụng mã này và nó hoạt động hoàn hảo:

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']
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.