Utilizzo di Net :: HTTP.get per un URL https


85

Sto cercando di utilizzare Net::HTTP.get()per un URL https:

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

Tuttavia, ottengo il seguente risultato quando provo a stampare i risultati:

non è possibile convertire URI :: HTTPS in String

Qual è l'accordo? Sto usando Ruby 1.8.7 (OS X)


Solo per tua informazione, ci stavamo connettendo temporaneamente a un server di terze parti che presentava problemi di certificato, quindi abbiamo dovuto utilizzare IO.copy_stream( open( url, { ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE } ), download_path )solo per disabilitare la verifica SSL. Nel nostro caso, la sicurezza non era un problema, il server era fuori dal nostro controllo ed era una soluzione temporanea.
Joshua Pinter

Risposte:


156

Risposta originale:

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)

Come sottolineato nei commenti, questo è più elegante:

require "open-uri"
@data = URI.parse("https://example.com/some/path").read

7
Lo darò come risposta perché è la risposta a ciò che ho chiesto, ma la vera risposta è far notare che mi sto avvicinando a questo nel modo sbagliato. Usa URI.parse(uri_string).readinvece, funziona così, così magnificamente.
Tony Stark

2
Cosa VERIFY_NONEimplica? Cosa si dovrebbe fare invece?
Jonathan Allard

1
questo è un flag che significa che la veridicità del certificato viene ignorata, ma è stato un po 'di tempo fa, quindi non sono sicuro del motivo per cui è necessario impostarlo.
stef

2
@frabcus, devi farlo require 'open-uri'perché il .read funzioni.
Josh D

1
Non c'è nulla nella domanda dell'OP che implichi che la verifica SSL non sia desiderata, quindi perché stai suggerendo VERIFY_NONE?
Alex

35

EDIT: Le mie opere approccio, ma di @ jason-Yeo approccio è molto più facile.

A partire da 2.1.2 il metodo preferito è il seguente (citando direttamente la documentazione ):

HTTPS è abilitato per una connessione HTTP da # 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 

Nelle versioni precedenti di Ruby avresti bisogno di 'net / https' per usare HTTPS. Questo non è più vero.


7
Questo non è vero. A partire da Ruby 2.0.0, Net::HTTP.getè sufficiente eseguire una richiesta di acquisizione HTTPS se all'oggetto URI viene passato un httpsURL. Vedi la mia risposta: stackoverflow.com/a/36543895/382740 .
Jason Yeo

19

In Ruby 2.0.0 e versioni successive, il semplice passaggio di un oggetto uri con un httpsURL è sufficiente per eseguire una richiesta di get HTTPS.

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

Puoi verificarlo eseguendo una richiesta get su un dominio con un certificato scaduto.

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

È stato introdotto da questo commit in Ruby 2.0.0.

Il get_responsemetodo, che viene chiamato dal Net::HTTP.getmetodo, viene impostato :use_ssl su true quando iluri.scheme è "https".

Disclaimer: Capisco che la domanda sia per Ruby 1.8.7, ma poiché questo è uno dei primi risultati di ricerca quando si cerca "https ruby", ho deciso di rispondere comunque.


5
Come punto dati, ho scoperto che questo non è vero in ruby ​​2.2.10. Ha aperto la connessione sulla porta 443, ma non ha utilizzato SSL. Ovviamente, il server straniero non avrebbe avuto nulla a che fare con esso e ha chiuso la connessione senza una risposta, causando molti digrignamenti da parte mia. Ho dovuto chiamare http.use_ssl = trueper costringerlo a utilizzare effettivamente ssl, e poi le cose sono andate a gonfie vele.
David Hempy

4

questo dovrebbe apparire come:

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

ha funzionato, ma ora l'API esterna si lamenta del fatto che ho inviato una semplice richiesta HTTP a una porta HTTPS ...
Tony Stark

haha, giusto;) vedi sotto la soluzione fornita da Stef, dovrebbe funzionare
Vlad Khomich

non è così, ricevo un errore che dice "metodo non definito` use_ssl = '"
Tony Stark

2
prova a richiedere anche 'net / https'
Vlad Khomich
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.