87 votes

Utilisation de Net::HTTP.get pour une url https

J'essaie d'utiliser Net::HTTP.get() pour une URL https :

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

Cependant, j'obtiens le résultat suivant lorsque j'essaie d'imprimer les résultats :

ne peut pas convertir URI::HTTPS en String

C'est quoi le problème ? J'utilise Ruby 1.8.7 (OS X).

0 votes

Pour information, nous nous sommes connectés temporairement à un serveur tiers qui avait des problèmes de certificat et nous avons donc dû utiliser IO.copy_stream( open( url, { ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE } ), download_path ) pour désactiver la vérification SSL. Dans notre cas, la sécurité n'était pas un problème, le serveur était hors de notre contrôle et il s'agissait d'une solution temporaire.

158voto

stef Points 6478

Réponse 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)

Comme indiqué dans les commentaires, c'est plus élégant :

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

7 votes

Je vais donner cette réponse parce que c'est la réponse à ce que j'ai demandé, mais la vraie réponse est de souligner que je n'aborde pas la question de la bonne façon. Utiliser URI.parse(uri_string).read au lieu de cela, fonctionne très, très bien.

0 votes

Hatorade, je n'arrive pas du tout à faire fonctionner cette option avec ".read". Pourriez-vous publier une réponse complète à votre propre question en expliquant comment vous procédez ?

2 votes

Qu'est-ce que VERIFY_NONE impliquer ? Que faudrait-il faire à la place ?

36voto

eebbesen Points 1596

EDIT : Mon approche fonctionne, mais celle de @jason-yeo approche est beaucoup plus facile.

Il apparaît à partir de la 2.1.2 le préféré une méthode documentée est la suivante (citant directement la documentation ) :

HTTPS est activé pour une connexion HTTP par #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 

Dans les versions précédentes de Ruby, vous deviez exiger 'net/https' pour utiliser le protocole HTTPS. Ce n'est plus le cas.

7 votes

Ce n'est pas le cas. Depuis Ruby 2.0.0, Net::HTTP.get est suffisant pour effectuer une requête HTTPS si l'objet URI est accompagné d'un paramètre https url. Voir ma réponse : stackoverflow.com/a/36543895/382740 .

22voto

Jason Yeo Points 954

Dans Ruby 2.0.0 et plus, il suffit de passer un objet uri avec une balise https url est suffisant pour effectuer une demande d'accès HTTPS.

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

Vous pouvez le vérifier en effectuant une requête get sur un fichier de type domaine avec un certificat expiré.

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

Il a été introduit par ce commettre dans Ruby 2.0.0.

Le site get_response qui est appelée par la méthode Net::HTTP.get méthode, fixe :use_ssl à true lorsque le uri.scheme est "https".

Avertissement : je comprends que la question concerne Ruby 1.8.7, mais comme il s'agit de l'un des premiers résultats de recherche lorsqu'on cherche "https ruby", j'ai décidé de répondre quand même.

6 votes

À titre d'information, j'ai constaté que ce n'était pas le cas avec ruby 2.2.10. Il a bien ouvert la connexion sur le port 443, mais n'a pas utilisé SSL. Bien entendu, le serveur étranger n'a rien voulu savoir et a fermé la connexion sans réponse, ce qui m'a valu de nombreux grincements de dents. J'ai dû appeler http.use_ssl = true pour le forcer à utiliser ssl, et tout s'est bien passé.

4voto

Vlad Khomich Points 3296

Cela devrait ressembler à :

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

0 votes

Cela a fonctionné, mais maintenant l'API externe se plaint que j'ai envoyé une requête HTTP simple à un port HTTPS...

0 votes

Haha, c'est vrai ;) voir la solution ci-dessous fournie par Stef, cela devrait fonctionner

0 votes

Ce n'est pas le cas, j'obtiens une erreur disant "undefined method `use_ssl='"

3voto

Justin Tanner Points 5437

Identique à la réponse de stef, mais avec les @data contenant le corps de l'URI demandé :

http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Get.new(uri.request_uri)
response = http.request(request)
@data = response.body

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X