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.