Ciągle otrzymuję ten błąd:

Errno::ECONNRESET in SearchController#create

Connection reset by peer

I

EOFError in SearchController#create

end of file reached

Próbuję uzyskać odpowiedź z interfejsu API Google, a następnie przeanalizować JSON za pomocą ruby. Oto mój kod:

require 'rubygems'
require 'json'
require 'net/https'

def create
  @search = params[:search][:search]
  base_url = "https://ajax.googleapis.com/ajax/services/search/web?v=1.0"
  url = "#{base_url}&q=#{@search}&rsz=8&start=0"
  resp = Net::HTTP.get_response(URI.parse(url))
  data = resp.body

  result = JSON.parse(data)

  if result.has_key? 'Error'
     raise "web service error"
  end
  return result
end

A resp = Net::HTTP.get_response(URI.parse(url)) wydaje się być linią, w której pojawia się błąd. Jak mogę to naprawić?

Oto pierwsza część pełnego śladu:

/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/net/protocol.rb:135:in `sysread'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/net/protocol.rb:135:in `rbuf_fill'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/timeout.rb:62:in `timeout'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/timeout.rb:93:in `timeout'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/net/protocol.rb:134:in `rbuf_fill'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/net/protocol.rb:116:in `readuntil'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/net/protocol.rb:126:in `readline'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/net/http.rb:2020:in `read_status_line'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/net/http.rb:2009:in `read_new'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/net/http.rb:1050:in `request'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/net/http.rb:948:in `request_get'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/net/http.rb:380:in `get_response'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/net/http.rb:543:in `start'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/net/http.rb:379:in `get_response'
app/controllers/search_controller.rb:10:in `create'
1
Justin Meltzer 21 czerwiec 2011, 08:29
Czy działa lepiej, jeśli użyjesz adresu URL http://... zamiast https://...?
 – 
Tobias Cohen
21 czerwiec 2011, 09:35
Tak.......... działa, jeśli używam http
 – 
Justin Meltzer
21 czerwiec 2011, 09:36

2 odpowiedzi

Najlepsza odpowiedź

Osobiście polecam używanie Open::URI, chyba że potrzebujesz niższego szczegółowość lub kontrola procedury na poziomie:

require 'open-uri'
require 'json'

def create
  search = params[:search][:search]
  base_url = "https://ajax.googleapis.com/ajax/services/search/web?v=1.0"

  stream = open("#{base_url}&q=#{search}&rsz=8&start=0")
  raise 'web service error' if (stream.status.first != '200')

  JSON.parse(stream.read)
end

Open::URI automatycznie obsługuje przekierowania i, jeszcze lepiej w tym celu, zajmuje się konfiguracją połączenia HTTPs.

Jeśli chcesz używać Net::HTTP, to zadziała:

require 'rubygems'
require 'json'
require 'net/http'

def create(search)
  base_url = "https://ajax.googleapis.com/ajax/services/search/web?v=1.0"
  url = "#{base_url}&q=#{search}&rsz=8&start=0"
  uri = URI.parse(url)
  connection = Net::HTTP.new(uri.host, 443)
  connection.use_ssl = true

  resp = connection.request_get(uri.path + '?' + uri.query)

  if resp.code != '200'
     raise "web service error"
  end

  JSON.parse(resp.body) 
end

puts create('ruby')

Różnica polega na tym, że mówię Net::HTTP, aby otworzył połączenie SSL przy użyciu portu 443, w którym, jak sądzę, twój kod zawodzi. Ponadto szukam kodu statusu sukcesu „200”, który możesz chcieć sprawdzić, a następnie zareagować, jeśli otrzymasz przekierowanie.

2
the Tin Man 21 czerwiec 2011, 10:54
Należy zmienić wymaganie 'net/http' na https .. http nie posiada metody use_ssl=. ma tylko use_ssl? metoda.
 – 
brayne
2 wrzesień 2012, 12:43

Może to być problem z samym Net::HTTP. Spróbuj użyć httparty: http://github.com/jnunemaker/httparty

-1
Jack Hoge 21 czerwiec 2011, 09:35
Problem nie dotyczy Net::HTTP. Chodzi o to, że nie ustawił poprawnie połączenia.
 – 
the Tin Man
21 czerwiec 2011, 10:56