Spec-Zone.ru › Ruby 3.3

класс Net::HTTP

Родитель:
Протокол

Класс Net::HTTP предоставляет богатую библиотеку, реализующую клиента в модели клиент-сервер, которая использует протокол HTTP запросов-ответов. Для получения информации о HTTP, см.:

  • Протокол передачи гипертекста.

  • Технический обзор.

Об примерах

Примеры здесь предполагают, что net/http было потребовано (что также требует uri):

require 'net/http'

Многие примеры кода здесь используют эти примерные веб-сайты:

  • jsonplaceholder.typicode.com.

  • example.com.

Некоторые примеры также предполагают эти переменные:

uri = URI('https://jsonplaceholder.typicode.com/')
uri.freeze # Examples may not modify.
hostname = uri.hostname # => "jsonplaceholder.typicode.com"
path = uri.path         # => "/"
port = uri.port         # => 443

Таким образом, примерные запросы могут быть записаны как:

Net::HTTP.get(uri)
Net::HTTP.get(hostname, '/index.html')
Net::HTTP.start(hostname) do |http|
  http.get('/todos/1')
  http.get('/todos/2')
end

Пример, которому требуется изменённый URI сначала дублирует uri, затем изменяет дубликат:

_uri = uri.dup
_uri.path = '/todos/1'

Стратегии

  • Если вы будете делать только несколько запросов GET, рассмотрите использование OpenURI.

  • Если вы будете делать только несколько запросов всех типов, рассмотрите использование различных методов удобства в этом классе. Каждый из следующих методов автоматически запускает и завершает сеанс, который отправляет один запрос:

    # Return string response body.
    Net::HTTP.get(hostname, path)
    Net::HTTP.get(uri)
    
    # Write string response body to $stdout.
    Net::HTTP.get_print(hostname, path)
    Net::HTTP.get_print(uri)
    
    # Return response as Net::HTTPResponse object.
    Net::HTTP.get_response(hostname, path)
    Net::HTTP.get_response(uri)
    data = '{"title": "foo", "body": "bar", "userId": 1}'
    Net::HTTP.post(uri, data)
    params = {title: 'foo', body: 'bar', userId: 1}
    Net::HTTP.post_form(uri, params)
    
  • Если производительность важна, рассмотрите использование сеансов, которые снижают нагрузку на запросы. Этот сеанс содержит несколько запросов для методов HTTP и методов WebDAV:

    Net::HTTP.start(hostname) do |http|
      # Session started automatically before block execution.
      http.get(path)
      http.head(path)
      body = 'Some text'
      http.post(path, body)  # Can also have a block.
      http.put(path, body)
      http.delete(path)
      http.options(path)
      http.trace(path)
      http.patch(path, body) # Can also have a block.
      http.copy(path)
      http.lock(path, body)
      http.mkcol(path, body)
      http.move(path)
      http.propfind(path, body)
      http.proppatch(path, body)
      http.unlock(path, body)
      # Session finished automatically at block exit.
    end
    

Приведенные выше методы являются удобными методами, которые, благодаря своим нескольким аргументам, позволяют минимально управлять запросами. Для более широкого контроля рассмотрите использование объектов запроса.

URI

В интернете URI (универсальный идентификатор ресурса) представляет собой строку, которая идентифицирует конкретный ресурс. Он состоит из некоторых или всех: схемы, имени хоста, пути, запроса и фрагмента; см. синтаксис URI.

Объект Ruby URI::Generic представляет собой интернет URI. Он предоставляет, среди прочего, методы scheme, hostname, path, query, и fragment.

Схемы

Интернет-URI имеет схему.

Две поддерживаемые в Net::HTTP схемы — 'https' и 'http':

uri.scheme                       # => "https"
URI('http://example.com').scheme # => "http"

Имена хостов

Имя хоста идентифицирует сервер (хост), которому могут быть отправлены запросы:

hostname = uri.hostname # => "jsonplaceholder.typicode.com"
Net::HTTP.start(hostname) do |http|
  # Some HTTP stuff.
end

Пути

Указанный для хоста путь идентифицирует ресурс на хосте:

_uri = uri.dup
_uri.path = '/todos/1'
hostname = _uri.hostname
path = _uri.path
Net::HTTP.get(hostname, path)

Запросы

Указанный для хоста запрос добавляет пары имя/значение в URI:

_uri = uri.dup
params = {userId: 1, completed: false}
_uri.query = URI.encode_www_form(params)
_uri # => #<URI::HTTPS https://jsonplaceholder.typicode.com?userId=1&completed=false>
Net::HTTP.get(_uri)

Фрагменты

Фрагмент URI не оказывает никакого эффекта в Net::HTTP; те же данные возвращаются независимо от того, включён фрагмент или нет.

Заголовки запроса

Заголовки запроса могут использоваться для передачи дополнительной информации хосту, аналогично аргументам, передаваемым в вызов метода; каждый заголовок — это пара имя/значение.

Каждый из методов Net::HTTP, отправляющих запрос на хост, имеет необязательный аргумент headers, где заголовки выражены как хеш пар имя-поля/значение:

headers = {Accept: 'application/json', Connection: 'Keep-Alive'}
Net::HTTP.get(uri, headers)

См. списки стандартных полей запроса и общих полей запроса на странице Поля запроса. Хост также может принимать и другие пользовательские поля.

Сессии HTTP

Сессия — это соединение между сервером (хостом) и клиентом, которое:

  • Начинается методом экземпляра Net::HTTP#start.

  • Может содержать любое количество запросов.

  • Завершается методом экземпляра Net::HTTP#finish.

См. примеры сессий на странице Стратегии.

Сессия, использующая Net::HTTP.start

Если вам нужно отправить много запросов на один хост (и порт), рассмотрите использование одноэлементного метода Net::HTTP.start с блоком; метод автоматически обрабатывает сеанс путём:

  • Вызова start перед выполнением блока.

  • Выполнения блока.

  • Вызова finish после выполнения блока.

В блоке вы можете использовать эти методы экземпляров, каждый из которых отправляет один запрос:

  • Методы HTTP:

    • get, request_get: GET.

    • head, request_head: HEAD.

    • post, request_post: POST.

    • delete: DELETE.

    • options: OPTIONS.

    • trace: TRACE.

    • patch: PATCH.

  • Методы WebDAV:

    • copy: COPY.

    • lock: LOCK.

    • mkcol: MKCOL.

    • move: MOVE.

    • propfind: PROPFIND.

    • proppatch: PROPPATCH.

    • unlock: UNLOCK.

Сессия, использующая Net::HTTP.start и Net::HTTP.finish

Вы можете вручную управлять сеансом, используя методы start и finish:

http = Net::HTTP.new(hostname)
http.start
http.get('/todos/1')
http.get('/todos/2')
http.delete('/posts/1')
http.finish # Needed to free resources.

Сессия одного запроса

Некоторые методы удобства автоматически обрабатывают сеанс, выполняя:

  • Создание объекта HTTP

  • Запуск сеанса.

  • Отправление одного запроса.

  • Завершение сеанса.

  • Уничтожение объекта.

Методы, отправляющие запросы GET:

  • ::get: Возвращает строку тела ответа.

  • ::get_print: Выводит строку тела ответа в $stdout.

  • ::get_response: Возвращает объект Net::HTTPResponse.

Методы, отправляющие запросы POST:

  • ::post: Отправляет данные на хост.

  • ::post_form: Отправляет данные формы на хост.

HTTP Запросы и Ответы

Многие из вышеперечисленных методов являются методами удобства, каждый из которых отправляет запрос и возвращает строку без прямого использования объектов Net::HTTPRequest и Net::HTTPResponse.

Однако вы можете напрямую создать объект запроса, отправить запрос и получить объект ответа; см.:

  • Net::HTTPRequest.

  • Net::HTTPResponse.

Следование перенаправлению

Каждый возвращённый ответ является экземпляром подкласса Net::HTTPResponse. См. иерархию классов ответов иерархия классов ответов.

В частности, класс Net::HTTPRedirection является родительским для всех классов перенаправления. Это позволяет вам создать оператор case для правильной обработки перенаправлений:

def fetch(uri, limit = 10)
  # You should choose a better exception.
  raise ArgumentError, 'Too many HTTP redirects' if limit == 0

  res = Net::HTTP.get_response(URI(uri))
  case res
  when Net::HTTPSuccess     # Any success class.
    res
  when Net::HTTPRedirection # Any redirection class.
    location = res['Location']
    warn "Redirected to #{location}"
    fetch(location, limit - 1)
  else                      # Any other class.
    res.value
  end
end

fetch(uri)

Базовая аутентификация

Базовая аутентификация выполняется в соответствии с RFC2617:

req = Net::HTTP::Get.new(uri)
req.basic_auth('user', 'pass')
res = Net::HTTP.start(hostname) do |http|
  http.request(req)
end

Потоковые тела ответов

По умолчанию Net::HTTP читает весь ответ в память. Если вы обрабатываете большие файлы или хотите реализовать индикатор выполнения, вы можете вместо этого напрямую передать тело в IO.

Net::HTTP.start(hostname) do |http|
  req = Net::HTTP::Get.new(uri)
  http.request(req) do |res|
    open('t.tmp', 'w') do |f|
      res.read_body do |chunk|
        f.write chunk
      end
    end
  end
end

HTTPS

HTTPS включен для подключения HTTP с помощью Net::HTTP#use_ssl=:

Net::HTTP.start(hostname, :use_ssl => true) do |http|
  req = Net::HTTP::Get.new(uri)
  res = http.request(req)
end

Или, если вы просто хотите отправить запрос GET, вы можете передать объект URI с URL HTTPS. Net::HTTP автоматически включает проверку TLS, если объект URI имеет схему «https» URI:

uri # => #<URI::HTTPS https://jsonplaceholder.typicode.com/>
Net::HTTP.get(uri)

Прокси-сервер

Объект HTTP может иметь прокси-сервер.

Вы можете создать объект HTTP с прокси-сервером, используя метод Net::HTTP.new или метод Net::HTTP.start.

Прокси можно определить либо аргументом p_addr или переменной окружения 'http_proxy'.

Прокси, использующий аргумент p_addr в качестве строки

Когда аргумент p_addr является строкой hostname, возвращаемый http имеет указанный хост в качестве прокси:

http = Net::HTTP.new(hostname, nil, 'proxy.example')
http.proxy?          # => true
http.proxy_from_env? # => false
http.proxy_address   # => "proxy.example"
# These use default values.
http.proxy_port      # => 80
http.proxy_user      # => nil
http.proxy_pass      # => nil

Порт, имя пользователя и пароль для прокси также могут быть указаны:

http = Net::HTTP.new(hostname, nil, 'proxy.example', 8000, 'pname', 'ppass')
# => #<Net::HTTP jsonplaceholder.typicode.com:80 open=false>
http.proxy?          # => true
http.proxy_from_env? # => false
http.proxy_address   # => "proxy.example"
http.proxy_port      # => 8000
http.proxy_user      # => "pname"
http.proxy_pass      # => "ppass"

Прокси с использованием ‘ENV['http_proxy']’

Когда переменная окружения 'http_proxy' установлена в строку URI, возвращаемый http будет иметь сервер по этому URI в качестве прокси; обратите внимание, что строка URI должна иметь протокол, такой как 'http' или 'https':

ENV['http_proxy'] = 'http://example.com'
http = Net::HTTP.new(hostname)
http.proxy?          # => true
http.proxy_from_env? # => true
http.proxy_address   # => "example.com"
# These use default values.
http.proxy_port      # => 80
http.proxy_user      # => nil
http.proxy_pass      # => nil

Строка URI может включать имя пользователя прокси, пароль и номер порта:

ENV['http_proxy'] = 'http://pname:ppass@example.com:8000'
http = Net::HTTP.new(hostname)
http.proxy?          # => true
http.proxy_from_env? # => true
http.proxy_address   # => "example.com"
http.proxy_port      # => 8000
http.proxy_user      # => "pname"
http.proxy_pass      # => "ppass"

Фильтрация прокси

С помощью метода Net::HTTP.new (но не Net::HTTP.start), вы можете использовать аргумент p_no_proxy для фильтрации прокси:

  • Отклонить определённый адрес:

    http = Net::HTTP.new('example.com', nil, 'proxy.example', 8000, 'pname', 'ppass', 'proxy.example')
    http.proxy_address # => nil
    
  • Отклонить определённые домены или поддомены:

    http = Net::HTTP.new('example.com', nil, 'my.proxy.example', 8000, 'pname', 'ppass', 'proxy.example')
    http.proxy_address # => nil
    
  • Отклонить определённые комбинации адресов и портов:

    http = Net::HTTP.new('example.com', nil, 'proxy.example', 8000, 'pname', 'ppass', 'proxy.example:1234')
    http.proxy_address # => "proxy.example"
    
    http = Net::HTTP.new('example.com', nil, 'proxy.example', 8000, 'pname', 'ppass', 'proxy.example:8000')
    http.proxy_address # => nil
    
  • Отклонить список вышеперечисленных типов, разделенных запятой:

    http = Net::HTTP.new('example.com', nil, 'proxy.example', 8000, 'pname', 'ppass', 'my.proxy,proxy.example:8000')
    http.proxy_address # => nil
    
    http = Net::HTTP.new('example.com', nil, 'my.proxy', 8000, 'pname', 'ppass', 'my.proxy,proxy.example:8000')
    http.proxy_address # => nil
    

Сжатие и разархивирование

Net::HTTP не сжимает тело запроса перед отправкой.

По умолчанию Net::HTTP добавляет заголовок 'Accept-Encoding' к новому объекту запроса:

Net::HTTP::Get.new(uri)['Accept-Encoding']
# => "gzip;q=1.0,deflate;q=0.6,identity;q=0.3"

Это запрашивает сервер сжать тело ответа, если оно есть; сервер не обязан это делать.

Net::HTTP не автоматически разархивирует тело ответа, если ответ имеет заголовок 'Content-Range'.

В противном случае разархивирование (или его отсутствие) зависит от значения заголовка Content-Encoding:

  • 'deflate', 'gzip', или 'x-gzip': разархивирует тело и удаляет заголовок.

  • 'none' или 'identity': не разархивирует тело, но удаляет заголовок.

  • Любое другое значение: оставляет тело и заголовок без изменений.

Что здесь

Это категоризированный обзор методов и атрибутов.

Объекты Net::HTTP

  • ::new: Создаёт новый экземпляр.

  • #inspect: Возвращает строковое представление self.

Сессии

  • ::start: Начинает новую сессию в новом объекте Net::HTTP.

  • #started? (алиас #active?): Возвращает, находится ли в сессии.

  • #finish: Завершает активную сессию.

  • #start: Начинает новую сессию в существующем объекте Net::HTTP (self).

Соединения

  • :continue_timeout: Возвращает таймаут продолжения.

  • #continue_timeout=: Устанавливает таймаут продолжения в секундах.

  • :keep_alive_timeout: Возвращает таймаут поддержания соединения.

  • :keep_alive_timeout=: Устанавливает таймаут поддержания соединения.

  • :max_retries: Возвращает максимальное количество попыток.

  • #max_retries=: Устанавливает максимальное количество попыток.

  • :open_timeout: Возвращает таймаут открытия.

  • :open_timeout=: Устанавливает таймаут открытия.

  • :read_timeout: Возвращает таймаут чтения.

  • :read_timeout=: Устанавливает таймаут чтения.

  • :ssl_timeout: Возвращает таймаут SSL.

  • :ssl_timeout=: Устанавливает таймаут SSL.

  • :write_timeout: Возвращает таймаут записи.

  • write_timeout=: Устанавливает таймаут записи.

Запросы

  • ::get: Отправляет запрос GET и возвращает строковое тело ответа.

  • ::get_print: Отправляет запрос GET и выводит строковое тело ответа в $stdout.

  • ::get_response: Отправляет запрос GET и возвращает объект ответа.

  • ::post_form: Отправляет запрос POST с данными формы и возвращает объект ответа.

  • ::post: Отправляет запрос POST с данными и возвращает объект ответа.

  • #copy: Отправляет запрос COPY и возвращает объект ответа.

  • #delete: Отправляет запрос DELETE и возвращает объект ответа.

  • #get: Отправляет запрос GET и возвращает объект ответа.

  • #head: Отправляет запрос HEAD и возвращает объект ответа.

  • #lock: Отправляет запрос LOCK и возвращает объект ответа.

  • #mkcol: Отправляет запрос MKCOL и возвращает объект ответа.

  • #move: Отправляет запрос MOVE и возвращает объект ответа.

  • #options: Отправляет запрос OPTIONS и возвращает объект ответа.

  • #patch: Отправляет запрос PATCH и возвращает объект ответа.

  • #post: Отправляет запрос POST и возвращает объект ответа.

  • #propfind: Отправляет запрос PROPFIND и возвращает объект ответа.

  • #proppatch: Отправляет запрос PROPPATCH и возвращает объект ответа.

  • #put: Отправляет запрос PUT и возвращает объект ответа.

  • #request: Отправляет запрос и возвращает объект ответа.

  • #request_get (алиас #get2): Отправляет запрос GET и формирует объект ответа; если задан блок, вызывает блок с объектом, в противном случае возвращает объект.

  • #request_head (алиас #head2): Отправляет запрос HEAD и формирует объект ответа; если задан блок, вызывает блок с объектом, в противном случае возвращает объект.

  • #request_post (алиас #post2): Отправляет запрос POST и формирует объект ответа; если задан блок, вызывает блок с объектом, в противном случае возвращает объект.

  • #send_request: Отправляет запрос и возвращает объект ответа.

  • #trace: Отправляет запрос TRACE и возвращает объект ответа.

  • #unlock: Отправляет запрос UNLOCK и возвращает объект ответа.

Ответы

  • :close_on_empty_response: Возвращает, нужно ли закрывать соединение при пустом ответе.

  • :close_on_empty_response=: Устанавливает, нужно ли закрывать соединение при пустом ответе.

  • :ignore_eof: Возвращает, нужно ли игнорировать конец файла при чтении тела ответа с заголовками Content-Length.

  • :ignore_eof=: Устанавливает, нужно ли игнорировать конец файла при чтении тела ответа с заголовками Content-Length.

  • :response_body_encoding: Возвращает кодировку, используемую для тела ответа.

  • #response_body_encoding=: Устанавливает кодировку тела ответа.

Прокси

  • :proxy_address: Возвращает адрес прокси.

  • :proxy_address=: Устанавливает адрес прокси.

  • ::proxy_class?: Возвращает, является ли self классом прокси.

  • #proxy?: Возвращает, имеет ли self прокси.

  • #proxy_address (алиас #proxyaddr): Возвращает адрес прокси.

  • #proxy_from_env?: Возвращает, взят ли прокси из переменной окружения.

  • :proxy_from_env=: Устанавливает, нужно ли брать прокси из переменной окружения.

  • :proxy_pass: Возвращает пароль прокси.

  • :proxy_pass=: Устанавливает пароль прокси.

  • :proxy_port: Возвращает порт прокси.

  • :proxy_port=: Устанавливает порт прокси.

  • #proxy_user: Возвращает имя пользователя прокси.

  • :proxy_user=: Устанавливает пользователя прокси.

Безопасность

END_OF_DOCUMENT_MARKER
  • :ca_file: Возвращает путь к файлу сертификата CA.

  • :ca_file=: Устанавливает путь к файлу сертификата CA.

  • :ca_path: Возвращает путь к каталогу CA, содержащему сертификаты.

  • :ca_path=: Устанавливает путь к каталогу CA, содержащему сертификаты.

  • :cert: Возвращает объект OpenSSL::X509::Certificate для использования при клиентской сертификации.

  • :cert=: Устанавливает объект OpenSSL::X509::Certificate для использования при клиентской сертификации.

  • :cert_store: Возвращает X509::Store для проверки сертификата удалённого узла.

  • :cert_store=: Устанавливает X509::Store для проверки сертификата удалённого узла.

  • :ciphers: Возвращает доступные шифры SSL.

  • :ciphers=: Устанавливает доступные шифры SSL.

  • :extra_chain_cert: Возвращает дополнительные сертификаты X509 для добавления в цепочку сертификатов.

  • :extra_chain_cert=: Устанавливает дополнительные сертификаты X509 для добавления в цепочку сертификатов.

  • :key: Возвращает объект OpenSSL::PKey::RSA или OpenSSL::PKey::DSA.

  • :key=: Устанавливает объект OpenSSL::PKey::RSA или OpenSSL::PKey::DSA.

  • :max_version: Возвращает максимальную версию SSL.

  • :max_version=: Устанавливает максимальную версию SSL.

  • :min_version: Возвращает минимальную версию SSL.

  • :min_version=: Устанавливает минимальную версию SSL.

  • #peer_cert: Возвращает цепочку сертификатов X509 для сокета удалённого узла.

  • :ssl_version: Возвращает версию SSL.

  • :ssl_version=: Устанавливает версию SSL.

  • #use_ssl=: Устанавливает, будет ли новый сеанс использовать Transport Layer Security.

  • #use_ssl?: Возвращает, использует ли self SSL.

  • :verify_callback: Возвращает обработчик для проверки серверного сертификата.

  • :verify_callback=: Устанавливает обработчик для проверки серверного сертификата.

  • :verify_depth: Возвращает максимальную глубину проверки цепочки сертификатов.

  • :verify_depth=: Устанавливает максимальную глубину проверки цепочки сертификатов.

  • :verify_hostname: Возвращает флаги для проверки серверного сертификата в начале сеанса SSL/TLS.

  • :verify_hostname=: Устанавливает флаги для проверки серверного сертификата в начале сеанса SSL/TLS.

  • :verify_mode: Возвращает флаги для проверки серверного сертификата в начале сеанса SSL/TLS.

  • :verify_mode=: Устанавливает флаги для проверки серверного сертификата в начале сеанса SSL/TLS.

Адреса и Порты

  • :address: Возвращает строку имени хоста или IP хоста.

  • ::default_port: Возвращает целое число 80, стандартный порт для запросов HTTP.

  • ::http_default_port: Возвращает целое число 80, стандартный порт для запросов HTTP.

  • ::https_default_port: Возвращает целое число 443, стандартный порт для запросов HTTPS.

  • #ipaddr: Возвращает IP-адрес для подключения.

  • #ipaddr=: Устанавливает IP-адрес для подключения.

  • :local_host: Возвращает строку локального хоста, используемого для установления соединения.

  • :local_host=: Устанавливает строку локального хоста, используемого для установления соединения.

  • :local_port: Возвращает целое число локального порта, используемого для установления соединения.

  • :local_port=: Устанавливает целое число локального порта, используемого для установления соединения.

  • :port: Возвращает целое число номера порта.

Версия HTTP

  • ::version_1_2? (алиасы ::is_version_1_2? и ::version_1_2): Возвращает true; сохранено для совместимости.

Отладка

  • #set_debug_output: Устанавливает поток вывода для отладки.

Атрибуты

proxy_address[R]

Возвращает адрес прокси-хоста или nil если его нет; см. Proxy Server at Net::HTTP.

proxy_pass[R]

Возвращает пароль для доступа к прокси или nil если его нет; см. Proxy Server at Net::HTTP.

proxy_port[R]

Возвращает номер порта прокси-хоста или nil если его нет; см. Proxy Server at Net::HTTP.

proxy_user[R]

Возвращает имя пользователя для доступа к прокси или nil если его нет; см. Proxy Server at Net::HTTP.

address[R]

Возвращает строку имени хоста или IP-адреса хоста, указанного в качестве аргумента address в ::new.

ca_file[RW]

Устанавливает или возвращает путь к файлу сертификата CA в формате PEM.

ca_path[RW]

Устанавливает или возвращает путь к каталогу CA, содержащему файлы сертификатов в формате PEM.

cert[RW]

Устанавливает или возвращает объект OpenSSL::X509::Certificate, который будет использоваться для клиентской сертификации.

cert_store[RW]

Устанавливает или возвращает X509::Store, который будет использоваться для проверки сертификата узла.

ciphers[RW]

Устанавливает или возвращает доступные шифры SSL. См. OpenSSL::SSL::SSLContext#ciphers=.

close_on_empty_response[RW]

Устанавливает или возвращает, следует ли закрывать соединение, когда ответ пуст; изначально false.

continue_timeout[R]

Возвращает значение тайм-аута продолжения; см. continue_timeout=.

extra_chain_cert[RW]

Устанавливает или возвращает дополнительные сертификаты X509, которые будут добавлены к цепочке сертификатов. См. OpenSSL::SSL::SSLContext#add_certificate.

ignore_eof[RW]

Устанавливает или возвращает, следует ли игнорировать конец файла при чтении тела ответа с заголовками Content-Length; изначально true.

keep_alive_timeout[RW]

Устанавливает или возвращает числовое (целое или вещественное) количество секунд для поддержания соединения открытым после отправки запроса; изначально 2. Если новый запрос сделан в течение заданного интервала, используется все еще открытое соединение; в противном случае соединение будет закрыто и будет установлено новое соединение.

key[RW]

Устанавливает или возвращает объект OpenSSL::PKey::RSA или OpenSSL::PKey::DSA.

local_host[RW]

Устанавливает или возвращает строку локального хоста, используемого для установления соединения; изначально nil.

local_port[RW]

Устанавливает или возвращает целое число локального порта, используемого для установления соединения; изначально nil.

max_retries[R]

Возвращает максимальное количество попыток повтора идемпотентного запроса; см. max_retries=.

max_version[RW]

Устанавливает или возвращает максимальную версию SSL. См. OpenSSL::SSL::SSLContext#max_version=.

min_version[RW]

Устанавливает или возвращает минимальную версию SSL. См. OpenSSL::SSL::SSLContext#min_version=.

open_timeout[RW]

Устанавливает или возвращает числовое (целое или вещественное) количество секунд ожидания открытия соединения; изначально 60. Если соединение не установлено в течение заданного интервала, возникает исключение.

port[R]

Возвращает целое число номера порта, указанного в качестве аргумента port в ::new.

proxy_address[W]

Устанавливает адрес прокси; см. Proxy Server.

proxy_from_env[W]

Устанавливает, следует ли определять прокси из переменной окружения ‘ENV['http_proxy']’; см. Proxy Using ENV[‘http_proxy’].

proxy_pass[W]

Устанавливает пароль прокси; см. Proxy Server.

proxy_port[W]

Устанавливает порт прокси; см. Proxy Server.

proxy_user[W]

Устанавливает пользователя прокси; см. Proxy Server.

read_timeout[R]

Возвращает числовое (целое или вещественное) количество секунд ожидания чтения одного блока (с помощью одного вызова read(2)); см. read_timeout=.

response_body_encoding[R]

Возвращает кодировку, используемую для тела ответа; см. response_body_encoding=.

ssl_timeout[RW]

Устанавливает или возвращает таймаут SSL в секундах.

ssl_version[RW]

Устанавливает или возвращает версию SSL. См. OpenSSL::SSL::SSLContext#ssl_version=.

verify_callback[RW]

Устанавливает или возвращает обратный вызов для проверки сертификата сервера.

verify_depth[RW]

Устанавливает или возвращает максимальную глубину проверки цепочки сертификатов.

verify_hostname[RW]

Устанавливает или возвращает, нужно ли проверять, соответствует ли сертификат сервера имени хоста. См. OpenSSL::SSL::SSLContext#verify_hostname=.

verify_mode[RW]

Устанавливает или возвращает флаги для проверки сертификации сервера в начале сессии SSL/TLS. Допустимы OpenSSL::SSL::VERIFY_NONE или OpenSSL::SSL::VERIFY_PEER.

write_timeout[R]

Возвращает числовое (целое или с плавающей запятой) значение, количество секунд ожидания записи одного блока (через один вызов write(2)); см. write_timeout=.

Методы Публичного Класса

default_port() Показать исходный код
# File lib/net/http.rb, line 900
def HTTP.default_port
  http_default_port()
end

Возвращает целое число 80, стандартный порт для HTTP-запросов:

Net::HTTP.default_port # => 80
Net::HTTP.get(hostname, path, port = 80) → body Показать исходный код
Net::HTTP:get(uri, headers = {}, port = uri.port) → body
# File lib/net/http.rb, line 802
def HTTP.get(uri_or_host, path_or_headers = nil, port = nil)
  get_response(uri_or_host, path_or_headers, port).body
end

Отправляет запрос GET и возвращает тело HTTP-ответа в виде строки.

С использованием строковых аргументов hostname и path:

hostname = 'jsonplaceholder.typicode.com'
path = '/todos/1'
puts Net::HTTP.get(hostname, path)

Вывод:

{
  "userId": 1,
  "id": 1,
  "title": "delectus aut autem",
  "completed": false
}

С объектом URI uri и необязательным аргументом в виде хэша headers:

uri = URI('https://jsonplaceholder.typicode.com/todos/1')
headers = {'Content-type' => 'application/json; charset=UTF-8'}
Net::HTTP.get(uri, headers)

Связанные:

  • Net::HTTP::Get: класс запроса для HTTP-метода GET.

  • Net::HTTP#get: удобный метод для HTTP-метода GET.

Net::HTTP.get_print(hostname, path, port = 80) → nil Показать исходный код
Net::HTTP:get_print(uri, headers = {}, port = uri.port) → nil
# File lib/net/http.rb, line 761
def HTTP.get_print(uri_or_host, path_or_headers = nil, port = nil)
  get_response(uri_or_host, path_or_headers, port) {|res|
    res.read_body do |chunk|
      $stdout.print chunk
    end
  }
  nil
end

Аналогично Net::HTTP.get, но записывает возвращаемое тело в $stdout; возвращает nil.

Net::HTTP.get_response(hostname, path, port = 80) → http_response Показать исходный код
Net::HTTP:get_response(uri, headers = {}, port = uri.port) → http_response
# File lib/net/http.rb, line 812
def HTTP.get_response(uri_or_host, path_or_headers = nil, port = nil, &block)
  if path_or_headers && !path_or_headers.is_a?(Hash)
    host = uri_or_host
    path = path_or_headers
    new(host, port || HTTP.default_port).start {|http|
      return http.request_get(path, &block)
    }
  else
    uri = uri_or_host
    headers = path_or_headers
    start(uri.hostname, uri.port,
          :use_ssl => uri.scheme == 'https') {|http|
      return http.request_get(uri, headers, &block)
    }
  end
end

Аналогично Net::HTTP.get, но возвращает объект Net::HTTPResponse вместо строки тела.

http_default_port() Показать исходный код
# File lib/net/http.rb, line 908
def HTTP.http_default_port
  80
end

Возвращает целое число 80, стандартный порт для HTTP-запросов:

Net::HTTP.http_default_port # => 80
https_default_port() Показать исходный код
# File lib/net/http.rb, line 916
def HTTP.https_default_port
  443
end

Возвращает целое число 443, стандартный порт для HTTPS-запросов:

Net::HTTP.https_default_port # => 443
is_version_1_2?()
Псевдоним для: version_1_2?
new(address, port = nil, p_addr = :ENV, p_port = nil, p_user = nil, p_pass = nil, p_no_proxy = nil) Показать исходный код
# File lib/net/http.rb, line 1065
def HTTP.new(address, port = nil, p_addr = :ENV, p_port = nil, p_user = nil, p_pass = nil, p_no_proxy = nil)
  http = super address, port

  if proxy_class? then # from Net::HTTP::Proxy()
    http.proxy_from_env = @proxy_from_env
    http.proxy_address  = @proxy_address
    http.proxy_port     = @proxy_port
    http.proxy_user     = @proxy_user
    http.proxy_pass     = @proxy_pass
  elsif p_addr == :ENV then
    http.proxy_from_env = true
  else
    if p_addr && p_no_proxy && !URI::Generic.use_proxy?(address, address, port, p_no_proxy)
      p_addr = nil
      p_port = nil
    end
    http.proxy_address = p_addr
    http.proxy_port    = p_port || default_port
    http.proxy_user    = p_user
    http.proxy_pass    = p_pass
  end

  http
end

Возвращает новый объект Net::HTTP http (но не открывает TCP-соединение или HTTP-сессию).

С единственным строковым аргументом address (и ENV['http_proxy'] не определено или nil), возвращаемый объект http:

  • Имеет указанный адрес.

  • Имеет стандартный порт, Net::HTTP.default_port (80).

  • Не использует прокси.

Пример:

http = Net::HTTP.new(hostname)
# => #<Net::HTTP jsonplaceholder.typicode.com:80 open=false>
http.address # => "jsonplaceholder.typicode.com"
http.port    # => 80
http.proxy?  # => false

С целым числом аргументом port также указанным, возвращаемый объект http имеет указанный порт:

http = Net::HTTP.new(hostname, 8000)
# => #<Net::HTTP jsonplaceholder.typicode.com:8000 open=false>
http.port # => 8000

Для аргументов настройки прокси p_addr до p_no_proxy, см. Proxy Server.

Вызывает метод родительского класса
Также известен как: newobj
newobj(address, port = nil, p_addr = :ENV, p_port = nil, p_user = nil, p_pass = nil, p_no_proxy = nil)
Псевдоним для: new
post(url, data, header = nil) Показать исходный код
# File lib/net/http.rb, line 855
def HTTP.post(url, data, header = nil)
  start(url.hostname, url.port,
        :use_ssl => url.scheme == 'https' ) {|http|
    http.post(url, data, header)
  }
end

Отправляет данные на хост; возвращает объект Net::HTTPResponse.

Аргумент url должен быть URL; аргумент data должен быть строкой:

_uri = uri.dup
_uri.path = '/posts'
data = '{"title": "foo", "body": "bar", "userId": 1}'
headers = {'content-type': 'application/json'}
res = Net::HTTP.post(_uri, data, headers) # => #<Net::HTTPCreated 201 Created readbody=true>
puts res.body

Вывод:

{
  "title": "foo",
  "body": "bar",
  "userId": 1,
  "id": 101
}

Связанные:

  • Net::HTTP::Post: класс запроса для HTTP-метода POST.

  • Net::HTTP#post: удобный метод для HTTP-метода POST.

post_form(url, params) Показать исходный код
# File lib/net/http.rb, line 882
def HTTP.post_form(url, params)
  req = Post.new(url)
  req.form_data = params
  req.basic_auth url.user, url.password if url.user
  start(url.hostname, url.port,
        :use_ssl => url.scheme == 'https' ) {|http|
    http.request(req)
  }
end

Отправляет данные на хост; возвращает объект Net::HTTPResponse.

Аргумент url должен быть URI; аргумент data должен быть хэшем:

_uri = uri.dup
_uri.path = '/posts'
data = {title: 'foo', body: 'bar', userId: 1}
res = Net::HTTP.post_form(_uri, data) # => #<Net::HTTPCreated 201 Created readbody=true>
puts res.body

Вывод:

{
  "title": "foo",
  "body": "bar",
  "userId": "1",
  "id": 101
}
proxy_class?() Показать исходный код
# File lib/net/http.rb, line 1762
def proxy_class?
  defined?(@is_proxy_class) ? @is_proxy_class : false
end

Возвращает true, если self — класс, созданный с помощью HTTP::Proxy.

END_OF_DOCUMENT_MARKER
start(address, port = nil, p_addr = :ENV, p_port = nil, p_user = nil, p_pass = nil, opts) → http Показать исходный код
start(address, port = nil, p_addr = :ENV, p_port = nil, p_user = nil, p_pass = nil, opts) {|http| ... } → object
# File lib/net/http.rb, line 1010
def HTTP.start(address, *arg, &block) # :yield: +http+
  arg.pop if opt = Hash.try_convert(arg[-1])
  port, p_addr, p_port, p_user, p_pass = *arg
  p_addr = :ENV if arg.size < 2
  port = https_default_port if !port && opt && opt[:use_ssl]
  http = new(address, port, p_addr, p_port, p_user, p_pass)
  http.ipaddr = opt[:ipaddr] if opt && opt[:ipaddr]

  if opt
    if opt[:use_ssl]
      opt = {verify_mode: OpenSSL::SSL::VERIFY_PEER}.update(opt)
    end
    http.methods.grep(/\A(\w+)=\z/) do |meth|
      key = $1.to_sym
      opt.key?(key) or next
      http.__send__(meth, opt[key])
    end
  end

  http.start(&block)
end

Создаёт новый объект Net::HTTP, http, через Net::HTTP.new:

  • Для аргументов address и port, см. Net::HTTP.new.

  • Для аргументов, определяющих прокси p_addr по p_pass, см. Прокси-сервер.

  • Для аргумента opts, см. ниже.

Без блока:

  • Вызывает http.start без блока (см. start), что открывает TCP-соединение и HTTP-сессию.

  • Возвращает http.

  • Вызывающий метод должен вызвать finish, чтобы закрыть сессию:

    http = Net::HTTP.start(hostname)
    http.started? # => true
    http.finish
    http.started? # => false
    

С блоком:

  • Вызывает http.start с блоком (см. start), что:

    • Открывает TCP-соединение и HTTP-сессию.

    • Вызывает блок, который может выполнить любое количество запросов к хосту.

    • Закрывает HTTP-сессию и TCP-соединение при выходе из блока.

    • Возвращает значение блока object.

  • Возвращает object.

Пример:

hostname = 'jsonplaceholder.typicode.com'
Net::HTTP.start(hostname) do |http|
  puts http.get('/todos/1').body
  puts http.get('/todos/2').body
end

Вывод:

{
  "userId": 1,
  "id": 1,
  "title": "delectus aut autem",
  "completed": false
}
{
  "userId": 1,
  "id": 2,
  "title": "quis ut nam facilis et officia qui",
  "completed": false
}

Если последним аргументом является хеш, это хеш opts, где каждый ключ — это метод или аксессор, который нужно вызвать, а значение — значение, которое нужно установить.

Ключи могут включать:

  • ca_file

  • ca_path

  • cert

  • cert_store

  • ciphers

  • close_on_empty_response

  • ipaddr (вызывает ipaddr=)

  • keep_alive_timeout

  • key

  • open_timeout

  • read_timeout

  • ssl_timeout

  • ssl_version

  • use_ssl (вызывает use_ssl=)

  • verify_callback

  • verify_depth

  • verify_mode

  • write_timeout

Примечание: Если port равно nil и opts[:use_ssl] имеет истинное значение, значение, переданное в new — Net::HTTP.https_default_port, а не port.

version_1_2() Показать исходный код
# File lib/net/http.rb, line 736
def HTTP.version_1_2
  true
end

Возвращает true; сохранено для совместимости.

version_1_2?() Показать исходный код
# File lib/net/http.rb, line 741
def HTTP.version_1_2?
  true
end

Возвращает true; сохранено для совместимости.

Также алиас: is_version_1_2?

Общедоступные методы экземпляров

active?()
Псевдоним для: started?
continue_timeout=(sec) Показать исходный код
# File lib/net/http.rb, line 1380
def continue_timeout=(sec)
  @socket.continue_timeout = sec if @socket
  @continue_timeout = sec
end

Устанавливает значение таймаута ожидания ответа 100 Continue, которое представляет собой количество секунд, в течение которых ожидается ответ 100 Continue. Если объект HTTP не получает ответа в течение этого времени, он отправляет тело запроса.

copy(path, initheader = nil) Показать исходный код
# File lib/net/http.rb, line 2123
def copy(path, initheader = nil)
  request(Copy.new(path, initheader))
end

Отправляет запрос COPY на сервер; возвращает экземпляр подкласса Net::HTTPResponse.

Запрос основан на объекте Net::HTTP::Copy, созданном из строки path и начального хэша заголовков initheader.

http = Net::HTTP.new(hostname)
http.copy('/todos/1')
delete(path, initheader = {'Depth' => 'Infinity'}) Показать исходный код
# File lib/net/http.rb, line 2097
def delete(path, initheader = {'Depth' => 'Infinity'})
  request(Delete.new(path, initheader))
end

Отправляет запрос DELETE на сервер; возвращает экземпляр подкласса Net::HTTPResponse.

Запрос основан на объекте Net::HTTP::Delete, созданном из строки path и начального хэша заголовков initheader.

http = Net::HTTP.new(hostname)
http.delete('/todos/1')
finish() Показать исходный код
# File lib/net/http.rb, line 1708
def finish
  raise IOError, 'HTTP session not yet started' unless started?
  do_finish
end

Завершает сеанс HTTP:

http = Net::HTTP.new(hostname)
http.start
http.started? # => true
http.finish   # => nil
http.started? # => false

Вызывает исключение IOError, если сеанс не активен.

get(path, initheader = nil) {|res| ... } Показать исходный код
# File lib/net/http.rb, line 1914
def get(path, initheader = nil, dest = nil, &block) # :yield: +body_segment+
  res = nil

  request(Get.new(path, initheader)) {|r|
    r.read_body dest, &block
    res = r
  }
  res
end

Отправляет запрос GET на сервер; возвращает экземпляр подкласса Net::HTTPResponse.

Запрос основан на объекте Net::HTTP::Get, созданном из строки path и начального хэша заголовков initheader.

При наличии блока вызывает блок с телом ответа:

http = Net::HTTP.new(hostname)
http.get('/todos/1') do |res|
  p res
end # => #<Net::HTTPOK 200 OK readbody=true>

Вывод:

"{\n  \"userId\": 1,\n  \"id\": 1,\n  \"title\": \"delectus aut autem\",\n  \"completed\": false\n}"

При отсутствии блока просто возвращает объект ответа:

http.get('/') # => #<Net::HTTPOK 200 OK readbody=true>

Связанные:

  • Net::HTTP::Get: класс запроса для HTTP метода GET.

  • Net::HTTP.get: отправляет запрос GET, возвращает тело ответа.

get2(path, initheader = nil)
Псевдоним для: request_get
head(path, initheader = nil) Показать исходный код
# File lib/net/http.rb, line 1938
def head(path, initheader = nil)
  request(Head.new(path, initheader))
end

Отправляет запрос HEAD на сервер; возвращает экземпляр подкласса Net::HTTPResponse.

Запрос основан на объекте Net::HTTP::Head, созданном из строки path и начального хэша заголовков initheader:

res = http.head('/todos/1') # => #<Net::HTTPOK 200 OK readbody=true>
res.body                    # => nil
res.to_hash.take(3)
# =>
[["date", ["Wed, 15 Feb 2023 15:25:42 GMT"]],
 ["content-type", ["application/json; charset=utf-8"]],
 ["connection", ["close"]]]
head2(path, initheader = nil, &block)
Псевдоним для: request_head
inspect() Показать исходный код
# File lib/net/http.rb, line 1135
def inspect
  "#<#{self.class} #{@address}:#{@port} open=#{started?}>"
end

Возвращает строковое представление self:

Net::HTTP.new(hostname).inspect
# => "#<Net::HTTP jsonplaceholder.typicode.com:80 open=false>"
ipaddr() Показать исходный код
# File lib/net/http.rb, line 1274
def ipaddr
  started? ?  @socket.io.peeraddr[3] : @ipaddr
end

Возвращает IP-адрес для соединения.

Если сеанс не начат, возвращает значение, установленное методом ipaddr=, или nil, если оно не было установлено:

http = Net::HTTP.new(hostname)
http.ipaddr # => nil
http.ipaddr = '172.67.155.76'
http.ipaddr # => "172.67.155.76"

Если сеанс начат, возвращает IP-адрес из сокета:

http = Net::HTTP.new(hostname)
http.start
http.ipaddr # => "172.67.155.76"
http.finish
ipaddr=(addr) Показать исходный код
# File lib/net/http.rb, line 1286
def ipaddr=(addr)
  raise IOError, "ipaddr value changed, but session already started" if started?
  @ipaddr = addr
end

Устанавливает IP-адрес для соединения:

http = Net::HTTP.new(hostname)
http.ipaddr # => nil
http.ipaddr = '172.67.155.76'
http.ipaddr # => "172.67.155.76"

IP-адрес может не быть установлен, если сеанс уже начат.

lock(path, body, initheader = nil) Показать исходный код
# File lib/net/http.rb, line 2043
def lock(path, body, initheader = nil)
  request(Lock.new(path, initheader), body)
end

Отправляет запрос LOCK на сервер; возвращает экземпляр подкласса Net::HTTPResponse.

Запрос основан на объекте Net::HTTP::Lock, созданном из строки path, строки body, и начального хэша заголовков initheader.

data = '{"userId": 1, "id": 1, "title": "delectus aut autem", "completed": false}'
http = Net::HTTP.new(hostname)
http.lock('/todos/1', data)
max_retries=(retries) Показать исходный код
# File lib/net/http.rb, line 1320
def max_retries=(retries)
  retries = retries.to_int
  if retries < 0
    raise ArgumentError, 'max_retries should be non-negative integer number'
  end
  @max_retries = retries
end

Устанавливает максимальное количество попыток повтора идемпотентного запроса в случае Net::ReadTimeout, IOError, EOFError, Errno::ECONNRESET, Errno::ECONNABORTED, Errno::EPIPE, OpenSSL::SSL::SSLError, Timeout::Error. Начальное значение равно 1.

Аргумент retries должен быть неотрицательным числовым значением:

http = Net::HTTP.new(hostname)
http.max_retries = 2   # => 2
http.max_retries       # => 2
mkcol(path, body = nil, initheader = nil) Показать исходный код
# File lib/net/http.rb, line 2137
def mkcol(path, body = nil, initheader = nil)
  request(Mkcol.new(path, initheader), body)
end

Отправляет запрос MKCOL на сервер; возвращает экземпляр подкласса Net::HTTPResponse.

Запрос основан на объекте Net::HTTP::Mkcol, созданном из строки path, строки body, и начального хэша заголовков initheader.

data = '{"userId": 1, "id": 1, "title": "delectus aut autem", "completed": false}'
http.mkcol('/todos/1', data)
http = Net::HTTP.new(hostname)
move(path, initheader = nil) Показать исходный код
# File lib/net/http.rb, line 2110
def move(path, initheader = nil)
  request(Move.new(path, initheader))
end

Отправляет запрос MOVE на сервер; возвращает экземпляр подкласса Net::HTTPResponse.

Запрос основан на объекте Net::HTTP::Move, созданном из строки path и начального хэша заголовков initheader.

http = Net::HTTP.new(hostname)
http.move('/todos/1')
options(path, initheader = nil) Показать исходный код
# File lib/net/http.rb, line 2070
def options(path, initheader = nil)
  request(Options.new(path, initheader))
end

Отправляет запрос Options на сервер; возвращает экземпляр подкласса Net::HTTPResponse.

Запрос основан на объекте Net::HTTP::Options, созданном из строки path и начального хэша заголовков initheader.

http = Net::HTTP.new(hostname)
http.options('/')
patch(path, data, initheader = nil) {|res| ... } Показать исходный код
# File lib/net/http.rb, line 2001
def patch(path, data, initheader = nil, dest = nil, &block) # :yield: +body_segment+
  send_entity(path, data, initheader, dest, Patch, &block)
end

Отправляет запрос PATCH на сервер; возвращает экземпляр подкласса Net::HTTPResponse.

Запрос основан на объекте Net::HTTP::Patch, созданном из строки path, строки data, и начального хеша заголовков initheader.

При передаче блока, вызывает блок с телом ответа:

data = '{"userId": 1, "id": 1, "title": "delectus aut autem", "completed": false}'
http = Net::HTTP.new(hostname)
http.patch('/todos/1', data) do |res|
  p res
end # => #<Net::HTTPOK 200 OK readbody=true>

Вывод:

"{\n  \"userId\": 1,\n  \"id\": 1,\n  \"title\": \"delectus aut autem\",\n  \"completed\": false,\n  \"{\\\"userId\\\": 1, \\\"id\\\": 1, \\\"title\\\": \\\"delectus aut autem\\\", \\\"completed\\\": false}\": \"\"\n}"

При отсутствии блока, просто возвращает объект ответа:

http.patch('/todos/1', data) # => #<Net::HTTPCreated 201 Created readbody=true>
peer_cert() Показать исходный код
# File lib/net/http.rb, line 1537
def peer_cert
  if not use_ssl? or not @socket
    return nil
  end
  @socket.io.peer_cert
end

Возвращает цепочку сертификатов X509 (массив строк) для сокета клиента сессии, или nil если нет.

post(path, data, initheader = nil) {|res| ... } Показать исходный код
# File lib/net/http.rb, line 1972
def post(path, data, initheader = nil, dest = nil, &block) # :yield: +body_segment+
  send_entity(path, data, initheader, dest, Post, &block)
end

Отправляет запрос POST на сервер; возвращает экземпляр подкласса Net::HTTPResponse.

Запрос основан на объекте Net::HTTP::Post, созданном из строки path, строки data, и начального хеша заголовков initheader.

При передаче блока, вызывает блок с телом ответа:

data = '{"userId": 1, "id": 1, "title": "delectus aut autem", "completed": false}'
http = Net::HTTP.new(hostname)
http.post('/todos', data) do |res|
  p res
end # => #<Net::HTTPCreated 201 Created readbody=true>

Вывод:

"{\n  \"{\\\"userId\\\": 1, \\\"id\\\": 1, \\\"title\\\": \\\"delectus aut autem\\\", \\\"completed\\\": false}\": \"\",\n  \"id\": 201\n}"

При отсутствии блока, просто возвращает объект ответа:

http.post('/todos', data) # => #<Net::HTTPCreated 201 Created readbody=true>

Связанные:

  • Net::HTTP::Post: класс запроса для HTTP метода POST.

  • Net::HTTP.post: отправляет запрос POST, возвращает тело ответа.

post2(path, data, initheader = nil)
Псевдоним для: request_post
propfind(path, body = nil, initheader = {'Depth' => '0'}) Показать исходный код
# File lib/net/http.rb, line 2084
def propfind(path, body = nil, initheader = {'Depth' => '0'})
  request(Propfind.new(path, initheader), body)
end

Отправляет запрос PROPFIND на сервер; возвращает экземпляр подкласса Net::HTTPResponse.

Запрос основан на объекте Net::HTTP::Propfind, созданном из строки path, строки body, и начального хеша заголовков initheader.

data = '{"userId": 1, "id": 1, "title": "delectus aut autem", "completed": false}'
http = Net::HTTP.new(hostname)
http.propfind('/todos/1', data)
proppatch(path, body, initheader = nil) Показать исходный код
# File lib/net/http.rb, line 2029
def proppatch(path, body, initheader = nil)
  request(Proppatch.new(path, initheader), body)
end

Отправляет запрос PROPPATCH на сервер; возвращает экземпляр подкласса Net::HTTPResponse.

Запрос основан на объекте Net::HTTP::Proppatch, созданном из строки path, строки body, и начального хеша заголовков initheader.

data = '{"userId": 1, "id": 1, "title": "delectus aut autem", "completed": false}'
http = Net::HTTP.new(hostname)
http.proppatch('/todos/1', data)
proxy?() Показать исходный код
# File lib/net/http.rb, line 1785
def proxy?
  !!(@proxy_from_env ? proxy_uri : @proxy_address)
end

Возвращает true если прокси-сервер определён, false в противном случае; см. Прокси-сервер.

proxy_address() Показать исходный код
# File lib/net/http.rb, line 1807
def proxy_address
  if @proxy_from_env then
    proxy_uri&.hostname
  else
    @proxy_address
  end
end

Возвращает адрес прокси-сервера, если определён, nil в противном случае; см. Прокси-сервер.

Также алиасируется как: proxyaddr
proxy_from_env?() Показать исходный код
# File lib/net/http.rb, line 1792
def proxy_from_env?
  @proxy_from_env
end

Возвращает true если прокси-сервер определён в среде, false в противном случае; см. Прокси-сервер.

proxy_pass() Показать исходный код
# File lib/net/http.rb, line 1838
def proxy_pass
  if @proxy_from_env
    pass = proxy_uri&.password
    unescape(pass) if pass
  else
    @proxy_pass
  end
end

Возвращает пароль прокси-сервера, если определён, nil в противном случае; см. Прокси-сервер.

proxy_port() Показать исходный код
# File lib/net/http.rb, line 1817
def proxy_port
  if @proxy_from_env then
    proxy_uri&.port
  else
    @proxy_port
  end
end

Возвращает номер порта прокси-сервера, если определён, nil в противном случае; см. Прокси-сервер.

Также алиасируется как: proxyport
proxy_user() Показать исходный код
# File lib/net/http.rb, line 1827
def proxy_user
  if @proxy_from_env
    user = proxy_uri&.user
    unescape(user) if user
  else
    @proxy_user
  end
end

Возвращает имя пользователя прокси-сервера, если определён, nil в противном случае; см. Прокси-сервер.

proxyaddr()
Псевдоним для: proxy_address
proxyport()
Псевдоним для: proxy_port
put(path, data, initheader = nil) Показать исходный код
# File lib/net/http.rb, line 2015
def put(path, data, initheader = nil)
  request(Put.new(path, initheader), data)
end

Отправляет запрос PUT на сервер; возвращает экземпляр подкласса Net::HTTPResponse.

Запрос основан на объекте Net::HTTP::Put, созданном из строки path, строки data, и начального хеша заголовков initheader.

data = '{"userId": 1, "id": 1, "title": "delectus aut autem", "completed": false}'
http = Net::HTTP.new(hostname)
http.put('/todos/1', data) # => #<Net::HTTPOK 200 OK readbody=true>
read_timeout=(sec) Показать исходный код
# File lib/net/http.rb, line 1343
def read_timeout=(sec)
  @socket.read_timeout = sec if @socket
  @read_timeout = sec
end

Устанавливает таймаут чтения в секундах для self до целого числа sec; начальное значение - 60.

Аргумент sec должен быть неотрицательным числовым значением:

http = Net::HTTP.new(hostname)
http.read_timeout # => 60
http.get('/todos/1') # => #<Net::HTTPOK 200 OK readbody=true>
http.read_timeout = 0
http.get('/todos/1') # Raises Net::ReadTimeout.
request(req, body = nil) { |response| ... } Показать исходный код
# File lib/net/http.rb, line 2295
def request(req, body = nil, &block)  # :yield: +response+
  unless started?
    start {
      req['connection'] ||= 'close'
      return request(req, body, &block)
    }
  end
  if proxy_user()
    req.proxy_basic_auth proxy_user(), proxy_pass() unless use_ssl?
  end
  req.set_body_internal body
  res = transport_request(req, &block)
  if sspi_auth?(res)
    sspi_auth(req)
    res = transport_request(req, &block)
  end
  res
end

Отправляет заданный запрос req на сервер; формирует ответ в объект Net::HTTPResponse.

Переданный req должен быть экземпляром подкласса Net::HTTPRequest. Аргумент body должен быть передан только если это необходимо для запроса.

При отсутствии блока, возвращает объект ответа:

http = Net::HTTP.new(hostname)

req = Net::HTTP::Get.new('/todos/1')
http.request(req)
# => #<Net::HTTPOK 200 OK readbody=true>

req = Net::HTTP::Post.new('/todos')
http.request(req, 'xyzzy')
# => #<Net::HTTPCreated 201 Created readbody=true>

При передаче блока, вызывает блок с ответом и возвращает ответ:

req = Net::HTTP::Get.new('/todos/1')
http.request(req) do |res|
  p res
end # => #<Net::HTTPOK 200 OK readbody=true>

Вывод:

#<Net::HTTPOK 200 OK readbody=false>
request_get(path, initheader = nil) { |response| ... } Show source
# File lib/net/http.rb, line 2176
def request_get(path, initheader = nil, &block) # :yield: +response+
  request(Get.new(path, initheader), &block)
end

Отправляет GET-запрос на сервер; формирует ответ в объект Net::HTTPResponse.

Запрос основан на объекте Net::HTTP::Get, созданном из строки path и хеша начальных заголовков initheader.

Без блока возвращает объект ответа:

http = Net::HTTP.new(hostname)
http.request_get('/todos') # => #<Net::HTTPOK 200 OK readbody=true>

С блоком, вызывает блок с объектом ответа и возвращает объект ответа:

http.request_get('/todos') do |res|
  p res
end # => #<Net::HTTPOK 200 OK readbody=true>

Вывод:

#<Net::HTTPOK 200 OK readbody=false>
Также известен как: get2
request_head(path, initheader = nil, &block) Show source
# File lib/net/http.rb, line 2189
def request_head(path, initheader = nil, &block)
  request(Head.new(path, initheader), &block)
end

Отправляет HEAD-запрос на сервер; возвращает экземпляр подкласса Net::HTTPResponse.

Запрос основан на объекте Net::HTTP::Head, созданном из строки path и хеша начальных заголовков initheader.

http = Net::HTTP.new(hostname)
http.head('/todos/1') # => #<Net::HTTPOK 200 OK readbody=true>
Также известен как: head2
request_post(path, data, initheader = nil) { |response| ... } Show source
# File lib/net/http.rb, line 2216
def request_post(path, data, initheader = nil, &block) # :yield: +response+
  request Post.new(path, initheader), data, &block
end

Отправляет POST-запрос на сервер; формирует ответ в объект Net::HTTPResponse.

Запрос основан на объекте Net::HTTP::Post, созданном из строки path, строки data, и хеша начальных заголовков initheader.

Без блока возвращает объект ответа:

http = Net::HTTP.new(hostname)
http.post('/todos', 'xyzzy')
# => #<Net::HTTPCreated 201 Created readbody=true>

С блоком, вызывает блок с телом ответа и возвращает объект ответа:

http.post('/todos', 'xyzzy') do |res|
  p res
end # => #<Net::HTTPCreated 201 Created readbody=true>

Вывод:

"{\n  \"xyzzy\": \"\",\n  \"id\": 201\n}"
Также известен как: post2
response_body_encoding=(value) Show source
# File lib/net/http.rb, line 1229
def response_body_encoding=(value)
  value = Encoding.find(value) if value.is_a?(String)
  @response_body_encoding = value
end

Устанавливает кодировку, которая будет использоваться для тела ответа; возвращает кодировку.

Указанное value может быть:

  • Объектом Encoding.

  • Наименованием кодировки.

  • Псевдонимом для наименования кодировки.

См. Encoding.

Примеры:

http = Net::HTTP.new(hostname)
http.response_body_encoding = Encoding::US_ASCII # => #<Encoding:US-ASCII>
http.response_body_encoding = 'US-ASCII'         # => "US-ASCII"
http.response_body_encoding = 'ASCII'            # => "ASCII"
send_request(name, path, data = nil, header = nil) Show source
# File lib/net/http.rb, line 2259
def send_request(name, path, data = nil, header = nil)
  has_response_body = name != 'HEAD'
  r = HTTPGenericRequest.new(name,(data ? true : false),has_response_body,path,header)
  request r, data
end

Отправляет HTTP-запрос на сервер; возвращает экземпляр подкласса Net::HTTPResponse.

Запрос основан на объекте Net::HTTPRequest, созданном из строки path, строки data, и хеша начальных заголовков header. Этот объект является экземпляром подкласса Net::HTTPRequest, который соответствует данной строке в верхнем регистре name, которая должна быть методом HTTP-запроса или методом WebDAV-запроса.

Примеры:

http = Net::HTTP.new(hostname)
http.send_request('GET', '/todos/1')
# => #<Net::HTTPOK 200 OK readbody=true>
http.send_request('POST', '/todos', 'xyzzy')
# => #<Net::HTTPCreated 201 Created readbody=true>
set_debug_output(output) Show source
# File lib/net/http.rb, line 1188
def set_debug_output(output)
  warn 'Net::HTTP#set_debug_output called after HTTP started', uplevel: 1 if started?
  @debug_output = output
end

ПРЕДУПРЕЖДЕНИЕ Этот метод открывает серьёзную уязвимость в системе безопасности. Никогда не используйте этот метод в рабочем коде.

Устанавливает выходной поток для отладки:

http = Net::HTTP.new(hostname)
File.open('t.tmp', 'w') do |file|
  http.set_debug_output(file)
  http.start
  http.get('/nosuch/1')
  http.finish
end
puts File.read('t.tmp')

Вывод:

opening connection to jsonplaceholder.typicode.com:80...
opened
<- "GET /nosuch/1 HTTP/1.1\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: */*\r\nUser-Agent: Ruby\r\nHost: jsonplaceholder.typicode.com\r\n\r\n"
-> "HTTP/1.1 404 Not Found\r\n"
-> "Date: Mon, 12 Dec 2022 21:14:11 GMT\r\n"
-> "Content-Type: application/json; charset=utf-8\r\n"
-> "Content-Length: 2\r\n"
-> "Connection: keep-alive\r\n"
-> "X-Powered-By: Express\r\n"
-> "X-Ratelimit-Limit: 1000\r\n"
-> "X-Ratelimit-Remaining: 999\r\n"
-> "X-Ratelimit-Reset: 1670879660\r\n"
-> "Vary: Origin, Accept-Encoding\r\n"
-> "Access-Control-Allow-Credentials: true\r\n"
-> "Cache-Control: max-age=43200\r\n"
-> "Pragma: no-cache\r\n"
-> "Expires: -1\r\n"
-> "X-Content-Type-Options: nosniff\r\n"
-> "Etag: W/\"2-vyGp6PvFo4RvsFtPoIWeCReyIC8\"\r\n"
-> "Via: 1.1 vegur\r\n"
-> "CF-Cache-Status: MISS\r\n"
-> "Server-Timing: cf-q-config;dur=1.3000000762986e-05\r\n"
-> "Report-To: {\"endpoints\":[{\"url\":\"https:\\/\\/a.nel.cloudflare.com\\/report\\/v3?s=yOr40jo%2BwS1KHzhTlVpl54beJ5Wx2FcG4gGV0XVrh3X9OlR5q4drUn2dkt5DGO4GDcE%2BVXT7CNgJvGs%2BZleIyMu8CLieFiDIvOviOY3EhHg94m0ZNZgrEdpKD0S85S507l1vsEwEHkoTm%2Ff19SiO\"}],\"group\":\"cf-nel\",\"max_age\":604800}\r\n"
-> "NEL: {\"success_fraction\":0,\"report_to\":\"cf-nel\",\"max_age\":604800}\r\n"
-> "Server: cloudflare\r\n"
-> "CF-RAY: 778977dc484ce591-DFW\r\n"
-> "alt-svc: h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\r\n"
-> "\r\n"
reading 2 bytes...
-> "{}"
read 2 bytes
Conn keep-alive
start() { |http| ... } Show source
# File lib/net/http.rb, line 1565
def start  # :yield: http
  raise IOError, 'HTTP session already opened' if @started
  if block_given?
    begin
      do_start
      return yield(self)
    ensure
      do_finish
    end
  end
  do_start
  self
end

Запускает HTTP-сеанс.

Без блока возвращает self:

http = Net::HTTP.new(hostname)
# => #<Net::HTTP jsonplaceholder.typicode.com:80 open=false>
http.start
# => #<Net::HTTP jsonplaceholder.typicode.com:80 open=true>
http.started? # => true
http.finish

С блоком, вызывает блок с self, завершает сеанс после выхода из блока и возвращает значение блока:

http.start do |http|
  http
end
# => #<Net::HTTP jsonplaceholder.typicode.com:80 open=false>
http.started? # => false
started?() Show source
# File lib/net/http.rb, line 1413
def started?
  @started
end

Возвращает true, если HTTP-сеанс был запущен:

http = Net::HTTP.new(hostname)
http.started? # => false
http.start
http.started? # => true
http.finish # => nil
http.started? # => false

Net::HTTP.start(hostname) do |http|
  http.started?
end # => true
http.started? # => false
Также известен как: active?
trace(path, initheader = nil) Show source
# File lib/net/http.rb, line 2150
def trace(path, initheader = nil)
  request(Trace.new(path, initheader))
end

Отправляет TRACE-запрос на сервер; возвращает экземпляр подкласса Net::HTTPResponse.

Запрос основан на объекте Net::HTTP::Trace, созданном из строки path и хеша начальных заголовков initheader.

http = Net::HTTP.new(hostname)
http.trace('/todos/1')
unlock(path, body, initheader = nil) Show source
# File lib/net/http.rb, line 2057
def unlock(path, body, initheader = nil)
  request(Unlock.new(path, initheader), body)
end

Отправляет UNLOCK-запрос на сервер; возвращает экземпляр подкласса Net::HTTPResponse.

Запрос основан на объекте Net::HTTP::Unlock, созданном из строки path, строки body, и хеша начальных заголовков initheader.

data = '{"userId": 1, "id": 1, "title": "delectus aut autem", "completed": false}'
http = Net::HTTP.new(hostname)
http.unlock('/todos/1', data)
use_ssl=(flag) Show source
# File lib/net/http.rb, line 1435
def use_ssl=(flag)
  flag = flag ? true : false
  if started? and @use_ssl != flag
    raise IOError, "use_ssl value changed, but session already started"
  end
  @use_ssl = flag
end

Устанавливает, будет ли новый сеанс использовать Transport Layer Security:

Вызывает исключение IOError, если попытка изменить во время сессии.

Вызывает исключение OpenSSL::SSL::SSLError, если порт не является HTTPS-портом.

use_ssl?() Show source
# File lib/net/http.rb, line 1425
def use_ssl?
  @use_ssl
end

Возвращает true, если self использует SSL, false в противном случае. См. Net::HTTP#use_ssl=.

write_timeout=(sec) Show source
# File lib/net/http.rb, line 1367
def write_timeout=(sec)
  @socket.write_timeout = sec if @socket
  @write_timeout = sec
end

Устанавливает таймаут записи, в секундах, для self в целое число sec; начальное значение равно 60.

Аргумент sec должен быть неотрицательным числовым значением:

_uri = uri.dup
_uri.path = '/posts'
body = 'bar' * 200000
data = <<EOF
{"title": "foo", "body": "#{body}", "userId": "1"}
EOF
headers = {'content-type': 'application/json'}
http = Net::HTTP.new(hostname)
http.write_timeout # => 60
http.post(_uri.path, data, headers)
# => #<Net::HTTPCreated 201 Created readbody=true>
http.write_timeout = 0
http.post(_uri.path, data, headers) # Raises Net::WriteTimeout.

Методы экземпляра (приватные)

D(msg)
Псевдоним для: debug
addr_port() Показать исходный код
# File lib/net/http.rb, line 2464
def addr_port
  addr = address
  addr = "[#{addr}]" if addr.include?(":")
  default_port = use_ssl? ? HTTP.https_default_port : HTTP.http_default_port
  default_port == port ? addr : "#{addr}:#{port}"
end

utils

begin_transport(req) Показать исходный код
# File lib/net/http.rb, line 2381
def begin_transport(req)
  if @socket.closed?
    connect
  elsif @last_communicated
    if @last_communicated + @keep_alive_timeout < Process.clock_gettime(Process::CLOCK_MONOTONIC)
      debug 'Conn close because of keep_alive_timeout'
      @socket.close
      connect
    elsif @socket.io.to_io.wait_readable(0) && @socket.eof?
      debug "Conn close because of EOF"
      @socket.close
      connect
    end
  end

  if not req.response_body_permitted? and @close_on_empty_response
    req['connection'] ||= 'close'
  end

  req.update_uri address, port, use_ssl?
  req['host'] ||= addr_port()
end
connect() Показать исходный код
# File lib/net/http.rb, line 1585
def connect
  if use_ssl?
    # reference early to load OpenSSL before connecting,
    # as OpenSSL may take time to load.
    @ssl_context = OpenSSL::SSL::SSLContext.new
  end

  if proxy? then
    conn_addr = proxy_address
    conn_port = proxy_port
  else
    conn_addr = conn_address
    conn_port = port
  end

  debug "opening connection to #{conn_addr}:#{conn_port}..."
  s = Timeout.timeout(@open_timeout, Net::OpenTimeout) {
    begin
      TCPSocket.open(conn_addr, conn_port, @local_host, @local_port)
    rescue => e
      raise e, "Failed to open TCP connection to " +
        "#{conn_addr}:#{conn_port} (#{e.message})"
    end
  }
  s.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
  debug "opened"
  if use_ssl?
    if proxy?
      plain_sock = BufferedIO.new(s, read_timeout: @read_timeout,
                                  write_timeout: @write_timeout,
                                  continue_timeout: @continue_timeout,
                                  debug_output: @debug_output)
      buf = +"CONNECT #{conn_address}:#{@port} HTTP/#{HTTPVersion}\r\n" \
        "Host: #{@address}:#{@port}\r\n"
      if proxy_user
        credential = ["#{proxy_user}:#{proxy_pass}"].pack('m0')
        buf << "Proxy-Authorization: Basic #{credential}\r\n"
      end
      buf << "\r\n"
      plain_sock.write(buf)
      HTTPResponse.read_new(plain_sock).value
      # assuming nothing left in buffers after successful CONNECT response
    end

    ssl_parameters = Hash.new
    iv_list = instance_variables
    SSL_IVNAMES.each_with_index do |ivname, i|
      if iv_list.include?(ivname)
        value = instance_variable_get(ivname)
        unless value.nil?
          ssl_parameters[SSL_ATTRIBUTES[i]] = value
        end
      end
    end
    @ssl_context.set_params(ssl_parameters)
    unless @ssl_context.session_cache_mode.nil? # a dummy method on JRuby
      @ssl_context.session_cache_mode =
          OpenSSL::SSL::SSLContext::SESSION_CACHE_CLIENT |
              OpenSSL::SSL::SSLContext::SESSION_CACHE_NO_INTERNAL_STORE
    end
    if @ssl_context.respond_to?(:session_new_cb) # not implemented under JRuby
      @ssl_context.session_new_cb = proc {|sock, sess| @ssl_session = sess }
    end

    # Still do the post_connection_check below even if connecting
    # to IP address
    verify_hostname = @ssl_context.verify_hostname

    # Server Name Indication (SNI) RFC 3546/6066
    case @address
    when Resolv::IPv4::Regex, Resolv::IPv6::Regex
      # don't set SNI, as IP addresses in SNI is not valid
      # per RFC 6066, section 3.

      # Avoid openssl warning
      @ssl_context.verify_hostname = false
    else
      ssl_host_address = @address
    end

    debug "starting SSL for #{conn_addr}:#{conn_port}..."
    s = OpenSSL::SSL::SSLSocket.new(s, @ssl_context)
    s.sync_close = true
    s.hostname = ssl_host_address if s.respond_to?(:hostname=) && ssl_host_address

    if @ssl_session and
       Process.clock_gettime(Process::CLOCK_REALTIME) < @ssl_session.time.to_f + @ssl_session.timeout
      s.session = @ssl_session
    end
    ssl_socket_connect(s, @open_timeout)
    if (@ssl_context.verify_mode != OpenSSL::SSL::VERIFY_NONE) && verify_hostname
      s.post_connection_check(@address)
    end
    debug "SSL established, protocol: #{s.ssl_version}, cipher: #{s.cipher[0]}"
  end
  @socket = BufferedIO.new(s, read_timeout: @read_timeout,
                           write_timeout: @write_timeout,
                           continue_timeout: @continue_timeout,
                           debug_output: @debug_output)
  @last_communicated = nil
  on_connect
rescue => exception
  if s
    debug "Conn close because of connect error #{exception}"
    s.close
  end
  raise
end
debug(msg) Показать исходный код
# File lib/net/http.rb, line 2472
def debug(msg)
  return unless @debug_output
  @debug_output << msg
  @debug_output << "\n"
end

Добавляет сообщение в вывод отладки

Также используется как: D
do_finish() Показать исходный код
# File lib/net/http.rb, line 1713
def do_finish
  @started = false
  @socket.close if @socket
  @socket = nil
end
do_start() Показать исходный код
# File lib/net/http.rb, line 1579
def do_start
  connect
  @started = true
end
edit_path(path) Показать исходный код
# File lib/net/http.rb, line 1867
def edit_path(path)
  if proxy?
    if path.start_with?("ftp://") || use_ssl?
      path
    else
      "http://#{addr_port}#{path}"
    end
  else
    path
  end
end
end_transport(req, res) Показать исходный код
# File lib/net/http.rb, line 2404
def end_transport(req, res)
  @curr_http_version = res.http_version
  @last_communicated = nil
  if @socket.closed?
    debug 'Conn socket closed'
  elsif not res.body and @close_on_empty_response
    debug 'Conn close'
    @socket.close
  elsif keep_alive?(req, res)
    debug 'Conn keep-alive'
    @last_communicated = Process.clock_gettime(Process::CLOCK_MONOTONIC)
  else
    debug 'Conn close'
    @socket.close
  end
end
keep_alive?(req, res) Показать исходный код
# File lib/net/http.rb, line 2421
def keep_alive?(req, res)
  return false if req.connection_close?
  if @curr_http_version <= '1.0'
    res.connection_keep_alive?
  else   # HTTP/1.1 or later
    not res.connection_close?
  end
end
on_connect() Показать исходный код
# File lib/net/http.rb, line 1695
def on_connect
end
send_entity(path, data, initheader, dest, type, &block) Показать исходный код
# File lib/net/http.rb, line 2318
def send_entity(path, data, initheader, dest, type, &block)
  res = nil
  request(type.new(path, initheader), data) {|r|
    r.read_body dest, &block
    res = r
  }
  res
end

Выполняет запрос, использующий представление, и возвращает его тело.

sspi_auth(req) Показать исходный код
# File lib/net/http.rb, line 2445
def sspi_auth(req)
  n = Win32::SSPI::NegotiateAuth.new
  req["Proxy-Authorization"] = "Negotiate #{n.get_initial_token}"
  # Some versions of ISA will close the connection if this isn't present.
  req["Connection"] = "Keep-Alive"
  req["Proxy-Connection"] = "Keep-Alive"
  res = transport_request(req)
  authphrase = res["Proxy-Authenticate"]  or return res
  req["Proxy-Authorization"] = "Negotiate #{n.complete_authentication(authphrase)}"
rescue => err
  raise HTTPAuthenticationError.new('HTTP authentication failed', err)
end
sspi_auth?(res) Показать исходный код
# File lib/net/http.rb, line 2430
def sspi_auth?(res)
  return false unless @sspi_enabled
  if res.kind_of?(HTTPProxyAuthenticationRequired) and
      proxy? and res["Proxy-Authenticate"].include?("Negotiate")
    begin
      require 'win32/sspi'
      true
    rescue LoadError
      false
    end
  else
    false
  end
end
transport_request(req) { |res| ... } Показать исходный код
# File lib/net/http.rb, line 2329
def transport_request(req)
  count = 0
  begin
    begin_transport req
    res = catch(:response) {
      begin
        req.exec @socket, @curr_http_version, edit_path(req.path)
      rescue Errno::EPIPE
        # Failure when writing full request, but we can probably
        # still read the received response.
      end

      begin
        res = HTTPResponse.read_new(@socket)
        res.decode_content = req.decode_content
        res.body_encoding = @response_body_encoding
        res.ignore_eof = @ignore_eof
      end while res.kind_of?(HTTPInformation)

      res.uri = req.uri

      res
    }
    res.reading_body(@socket, req.response_body_permitted?) {
      yield res if block_given?
    }
  rescue Net::OpenTimeout
    raise
  rescue Net::ReadTimeout, IOError, EOFError,
         Errno::ECONNRESET, Errno::ECONNABORTED, Errno::EPIPE, Errno::ETIMEDOUT,
         # avoid a dependency on OpenSSL
         defined?(OpenSSL::SSL) ? OpenSSL::SSL::SSLError : IOError,
         Timeout::Error => exception
    if count < max_retries && IDEMPOTENT_METHODS_.include?(req.method)
      count += 1
      @socket.close if @socket
      debug "Conn close because of error #{exception}, and retry"
      retry
    end
    debug "Conn close because of error #{exception}"
    @socket.close if @socket
    raise
  end

  end_transport req, res
  res
rescue => exception
  debug "Conn close because of error #{exception}"
  @socket.close if @socket
  raise exception
end
unescape(value) Показать исходный код
# File lib/net/http.rb, line 1852
def unescape(value)
  require 'cgi/util'
  CGI.unescape(value)
end

Ruby Core © 1993–2022 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API