Використання Net :: HTTP.get для URL-адреси https


84

Я намагаюся використовувати Net::HTTP.get()для URL-адреси https:

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

Однак при спробі роздрукувати результати я отримую такий результат:

не вдається перетворити URI :: HTTPS у String

У чому справа? Я використовую Ruby 1.8.7 (OS X)


Просто як довідник, ми тимчасово підключалися до стороннього сервера, який мав проблеми із сертифікатом, тому нам довелося IO.copy_stream( open( url, { ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE } ), download_path )просто вимкнути перевірку SSL. У нашому випадку безпека не була проблемою, сервер був поза нашим контролем, і це було тимчасовим рішенням.
Джошуа Пінтер,

Відповіді:


156

Оригінальна відповідь:

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)

Як зазначалося в коментарях, це більш елегантно:

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

7
Я дам це як відповідь, тому що це відповідь на те, що я запитував, але справжня відповідь полягає в тому, щоб вказати, що я підходжу до цього неправильно. Використовуйте URI.parse(uri_string).readзамість цього, працює так, дуже красиво.
Тоні Старк,

2
Що VERIFY_NONEозначає? Що, можливо, слід робити замість цього?
Джонатан Аллард,

1
це прапорець, який означає, що правдивість сертифіката ігнорується, але це було деякий час тому, тому я не впевнений, чому вам потрібно це встановити.
stef 02

2
@frabcus, вам потрібно, щоб require 'open-uri'.read запрацював.
Джош Д

1
У питанні OP нічого не вказує на те, що перевірка SSL не бажана, то чому ви пропонуєте VERIFY_NONE?
Alex

35

EDIT: Мій підхід працює, але @ JASON-Ео в підході набагато простіше.

Станом на 2.1.2, кращим документованим методом є такий (безпосереднє цитування документації ):

HTTPS увімкнено для з'єднання HTTP за допомогою # 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 

У попередніх версіях Ruby вам потрібно було вимагати 'net / https' для використання HTTPS. Це вже неправда.


6
Це не правда. Станом на Ruby 2.0.0, Net::HTTP.getдостатньо зробити запит на отримання HTTPS, якщо об’єкту URI передається httpsURL-адреса. Дивіться мою відповідь: stackoverflow.com/a/36543895/382740 .
Джейсон Йо

19

У Ruby 2.0.0 і вище, простого передавання об'єкта uri за допомогою httpsurl достатньо, щоб зробити запит на отримання HTTPS.

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

Ви можете підтвердити це, виконавши запит на отримання для домену із простроченим сертифікатом.

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

Він був введений цим комітом у Ruby 2.0.0.

get_responseМетод, який викликається Net::HTTP.getметод, встановлює :use_ssl , щоб вірно , коли uri.schemeце «HTTPS».

Застереження: Я розумію, що питання стосується Ruby 1.8.7, але оскільки це один з кількох найпопулярніших результатів пошуку, коли хтось шукає "https ruby", я вирішив відповісти все-таки.


4
Як точка даних, я виявив, що це не відповідає дійсності в ruby ​​2.2.10. Він справді відкрив з'єднання на порту 443, але не використовував SSL. Звичайно, іноземний сервер не мав би до цього ніякого відношення, і перервав зв’язок без відповіді, що призвело до сильного скрипу зубами на моєму кінці. Мені довелося зателефонувати, http.use_ssl = trueщоб змусити його насправді використовувати ssl, а потім все пішло плавно.
Девід Хемпі,

4

це має виглядати так:

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

це спрацювало, але зараз зовнішній API скаржиться, що я надіслав звичайний запит HTTP до порту HTTPS ...
Тоні Старк

ха-ха, правильно;) див. нижче рішення Stef, це має спрацювати
Влад Хоміч

це не так, я отримую повідомлення про помилку із записом "undefined method` use_ssl = '"
Тоні Старк,

2
спробуйте також вимагати 'net / https'
Влад Хоміч
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.