Użycie Net :: HTTP.get dla adresu URL https

84

Próbuję użyć Net::HTTP.get()adresu URL https:

@data = Net::HTTP.get(uri, Net::HTTP.https_default_port())

Jednak podczas próby wydrukowania wyników otrzymuję następujący wynik:

nie można przekonwertować URI :: HTTPS na ciąg

O co chodzi? Używam Ruby 1.8.7 (OS X)

Tony Stark
źródło
Tylko do Twojej wiadomości, tymczasowo łączyliśmy się z serwerem innej firmy, który miał problemy z certyfikatem, więc musieliśmy użyć IO.copy_stream( open( url, { ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE } ), download_path )tylko do wyłączenia weryfikacji SSL. W naszym przypadku bezpieczeństwo nie było problemem, serwer był poza naszą kontrolą i było to rozwiązanie tymczasowe.
Joshua Pinter

Odpowiedzi:

156

Oryginalna odpowiedź:

uri = URI.parse("https://example.com/some/path")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
@data = http.get(uri.request_uri)

Jak wskazano w komentarzach, jest to bardziej eleganckie:

require "open-uri"
@data = URI.parse("https://example.com/some/path").read
stef
źródło
7
Podam to jako odpowiedź, ponieważ jest to odpowiedź na to, o co prosiłem, ale prawdziwa odpowiedź jest taka, że ​​podchodzę do tego w niewłaściwy sposób. Użyj URI.parse(uri_string).readzamiast tego, działa tak, tak pięknie.
Tony Stark
2
Co to znaczy VERIFY_NONE? Co ewentualnie należałoby zrobić zamiast tego?
Jonathan Allard
1
to jest flaga, która oznacza, że ​​prawdziwość certyfikatu jest ignorowana, ale to było jakiś czas temu, więc nie jestem pewien, dlaczego musisz to ustawić.
stef
2
@frabcus, musisz, aby require 'open-uri'plik .read działał.
Josh D
1
W pytaniu OP nic nie sugeruje, że weryfikacja SSL nie jest pożądana, więc dlaczego sugerujesz VERIFY_NONE?
Alex
35

EDIT: Moje prace podejście, ale @ Jason-Yeo za podejście jest o wiele łatwiejsze.

Wydaje się, że od 2.1.2 preferowana udokumentowana metoda jest następująca (bezpośrednio cytując dokumentację ):

HTTPS jest włączony dla połączenia HTTP przez # use_ssl =.

uri = URI('https://secure.example.com/some_path?query=string')

Net::HTTP.start(uri.host, uri.port,   
  :use_ssl => uri.scheme == 'https') do |http|
  request = Net::HTTP::Get.new uri

  response = http.request request # Net::HTTPResponse object 
end 

W poprzednich wersjach Rubiego do korzystania z protokołu HTTPS potrzebna byłaby opcja „net / https”. To już nie jest prawdą.

eebbesen
źródło
6
To nie jest prawda. Począwszy od Ruby 2.0.0, Net::HTTP.getwystarczy wykonać żądanie get HTTPS, jeśli do obiektu URI zostanie przekazany httpsadres URL. Zobacz moją odpowiedź: stackoverflow.com/a/36543895/382740 .
Jason Yeo,
19

W Ruby 2.0.0 i nowszych wersjach, zwykłe przekazanie obiektu uri z httpsadresem URL jest wystarczające, aby wykonać żądanie pobierania HTTPS.

uri = URI('https://encrypted.google.com')
Net::HTTP.get(uri)

Możesz to zweryfikować, wykonując żądanie pobierania w domenie z wygasłym certyfikatem.

uri = URI('https://expired.badssl.com/')
Net::HTTP.get(uri)
# OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=error: certificate verify failed

Zostało wprowadzone przez to zatwierdzenie w Rubim 2.0.0.

get_responseMetoda, która jest wywoływana przez Net::HTTP.getmetodę, ustawia :use_ssl się prawdziwe, gdy uri.schemejest „https”.

Zastrzeżenie: Rozumiem, że pytanie dotyczy Rubiego 1.8.7, ale ponieważ jest to jeden z niewielu najlepszych wyników wyszukiwania przy wyszukiwaniu hasła „https ruby”, i tak zdecydowałem się odpowiedzieć.

Jason Yeo
źródło
4
Jeśli chodzi o dane, stwierdziłem, że nie jest to prawdą w Ruby 2.2.10. Otworzył połączenie na porcie 443, ale nie używał SSL. Oczywiście zagraniczny serwer nie miałby z tym nic wspólnego i zamknął połączenie bez odpowiedzi, co doprowadziło do zgrzytania zębami po mojej stronie. Musiałem zadzwonić, http.use_ssl = trueaby zmusić go do korzystania z SSL, a potem wszystko poszło gładko.
David Hempy
4

powinno to wyglądać następująco:

uri.port = Net::HTTP.https_default_port()
@data = Net::HTTP.get(uri)
Vlad Khomich
źródło
zadziałało, ale teraz zewnętrzny interfejs API skarży się, że wysłałem zwykłe żądanie HTTP do portu HTTPS ...
Tony Stark
haha, racja;) zobacz poniżej rozwiązanie dostarczone przez Stefa, powinno działać
Vlad Khomich
tak się nie dzieje, pojawia się błąd z informacją „undefined method` use_ssl = '”
Tony Stark
2
spróbuj także wymagać „net / https”
Vlad Khomich