Spec-Zone.ru › Ruby 3.4

класс Net::HTTPSession

Класс 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)
    data = '{"title": "foo", "body": "bar", "userId": 1}'
    Net::HTTP.put(uri, data)
    
  • Если производительность важна, рассмотрите использование сеансов, которые снижают накладные расходы на запросы. Этот сеанс содержит несколько запросов для методов 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 — строка имени хоста, возвращаемый 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': не распаковывает тело, но удаляет заголовок.

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

Что здесь

Сначала, что где-то ещё. Class Net::HTTP:

  • Наследуется от класса Object.

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

Объекты Net::HTTP

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

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

Сессии

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

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

  • #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 с данными и возвращает объект ответа.

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

  • #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: Отправляет запрос GET и формирует объект ответа; если передан блок, вызывает блок с объектом, в противном случае возвращает объект.

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

  • #request_post: Отправляет запрос 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: Возвращает адрес прокси.

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

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

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

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

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

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

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

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

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

  • :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? (алиас ::version_1_2): Возвращает true; сохранено для совместимости.

Отладка

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

Атрибуты

default_configuration [RW]

Позволяет установить конфигурацию по умолчанию, которая будет использоваться при создании нового соединения.

Пример:

Net::HTTP.default_configuration = {
  read_timeout: 1,
  write_timeout: 1
}
http = Net::HTTP.new(hostname)
http.open_timeout   # => 60
http.read_timeout   # => 1
http.write_timeout  # => 1
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_use_ssl [R]

Использовать SSL при обращении к прокси-серверу. Если Net::HTTP не использует прокси, nil.

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. См. :SSL::SSLContext#ciphers=.

close_on_empty_response [RW]

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

continue_timeout [R]

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

extra_chain_cert [RW]

Устанавливает или возвращает дополнительные сертификаты X509, которые будут добавлены в цепочку сертификатов. См. :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. См. :SSL::SSLContext#max_version=.

min_version [RW]

Устанавливает или возвращает минимальную версию SSL. См. :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_use_ssl [W]
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. См. :SSL::SSLContext#ssl_version=.

verify_callback [RW]

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

verify_depth [RW]

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

verify_hostname [RW]

Устанавливает или возвращает флаг, указывающий на необходимость проверки соответствия сертификата сервера имени хоста. См. :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 935
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 804
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 763
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 814
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 943
def HTTP.http_default_port
  80
end

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

Net::HTTP.http_default_port # => 80
https_default_port ()
Исходный код
# File lib/net/http.rb, line 951
def HTTP.https_default_port
  443
end

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

Net::HTTP.https_default_port # => 443
new (address, port = nil, p_addr = :ENV, p_port = nil, p_user = nil, p_pass = nil, p_no_proxy = nil, p_use_ssl = nil)
Исходный код
# File lib/net/http.rb, line 1100
def HTTP.new(address, port = nil, p_addr = :ENV, p_port = nil, p_user = nil, p_pass = nil, p_no_proxy = nil, p_use_ssl = 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
    http.proxy_use_ssl  = @proxy_use_ssl
  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
    http.proxy_use_ssl = p_use_ssl
  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, см. Прокси-сервер.

Вызывает метод суперкласса
post (url, data, header = nil)
Исходный код
# File lib/net/http.rb, line 857
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 884
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 1826
def proxy_class?
  defined?(@is_proxy_class) ? @is_proxy_class : false
end

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

put (url, data, header = nil)
Исходный код
# File lib/net/http.rb, line 920
def HTTP.put(url, data, header = nil)
  start(url.hostname, url.port,
        :use_ssl => url.scheme == 'https' ) {|http|
    http.put(url, data, header)
  }
end

Отправляет PUT-запрос на сервер; возвращает объект 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.put(_uri, data, headers) # => #<Net::HTTPCreated 201 Created readbody=true>
puts res.body

Вывод:

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

Связанные элементы:

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

  • Net::HTTP#put: вспомогательный метод для метода HTTP PUT.

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 1045
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 738
def HTTP.version_1_2
  true
end

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

version_1_2? ()
Исходный код
# File lib/net/http.rb, line 743
def HTTP.version_1_2?
  true
end

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

END_OF_DOCUMENT_MARKER

Публичные методы экземпляра

continue_timeout= (sec)
Исходный код
# File lib/net/http.rb, line 1451
def continue_timeout=(sec)
  @socket.continue_timeout = sec if @socket
  @continue_timeout = sec
end

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

copy (path, initheader = nil)
Исходный код
# File lib/net/http.rb, line 2195
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 2169
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 1770
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 1981
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, возвращает тело ответа.

head (path, initheader = nil)
Исходный код
# File lib/net/http.rb, line 2005
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"]]]
inspect ()
Исходный код
# File lib/net/http.rb, line 1205
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 1345
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 1357
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 2115
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 1391
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 2209
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 2182
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 2142
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 2068
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 1593
def peer_cert
  if not use_ssl? or not @socket
    return nil
  end
  @socket.io.peer_cert
end

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

post(path, data, initheader = nil) {|res| ... }
Исходный код
# File lib/net/http.rb, line 2039
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, возвращает тело ответа.

propfind (path, body = nil, initheader = {'Depth' => '0'})
Исходный код
# File lib/net/http.rb, line 2156
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 2101
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 1852
def proxy?
  !!(@proxy_from_env ? proxy_uri : @proxy_address)
end

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

proxy_address ()
Исходный код
# File lib/net/http.rb, line 1874
def proxy_address
  if @proxy_from_env then
    proxy_uri&.hostname
  else
    @proxy_address
  end
end

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

proxy_from_env? ()
Исходный код
# File lib/net/http.rb, line 1859
def proxy_from_env?
  @proxy_from_env
end

Возвращает true если сервер прокси определён в переменных окружения, false в противном случае; см. Сервер прокси.

proxy_pass ()
Исходный код
# File lib/net/http.rb, line 1905
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 1884
def proxy_port
  if @proxy_from_env then
    proxy_uri&.port
  else
    @proxy_port
  end
end

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

proxy_user ()
Исходный код
# File lib/net/http.rb, line 1894
def proxy_user
  if @proxy_from_env
    user = proxy_uri&.user
    unescape(user) if user
  else
    @proxy_user
  end
end

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

put (path, data, initheader = nil)
Исходный код
# File lib/net/http.rb, line 2087
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>

Связанные:

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

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

END_OF_DOCUMENT_MARKER
read_timeout= (sec)
Исходный код
# File lib/net/http.rb, line 1414
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 2367
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| ... }
Исходный код
# File lib/net/http.rb, line 2248
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>
request_head (path, initheader = nil, &block)
Исходный код
# File lib/net/http.rb, line 2261
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>
request_post (path, data, initheader = nil) { |response| ... }
Исходный код
# File lib/net/http.rb, line 2288
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}"
response_body_encoding= (value)
Исходный код
# File lib/net/http.rb, line 1299
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)
Исходный код
# File lib/net/http.rb, line 2331
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)
Исходный код
# File lib/net/http.rb, line 1258
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| ... }
Исходный код
# File lib/net/http.rb, line 1621
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? ()
Исходный код
# File lib/net/http.rb, line 1484
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
trace (path, initheader = nil)
Исходный код
# File lib/net/http.rb, line 2222
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)
Исходный код
# File lib/net/http.rb, line 2129
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)
END_OF_DOCUMENT_MARKER
use_ssl= (flag)
Исходный код
# File lib/net/http.rb, line 1506
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? ()
Исходный код
# File lib/net/http.rb, line 1496
def use_ssl?
  @use_ssl
end

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

write_timeout= (sec)
Исходный код
# File lib/net/http.rb, line 1438
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 2539
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 2456
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 1641
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?
      if @proxy_use_ssl
        proxy_sock = OpenSSL::SSL::SSLSocket.new(s)
        ssl_socket_connect(proxy_sock, @open_timeout)
      else
        proxy_sock = s
      end
      proxy_sock = BufferedIO.new(proxy_sock, 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"
      proxy_sock.write(buf)
      HTTPResponse.read_new(proxy_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 2547
def debug(msg)
  return unless @debug_output
  @debug_output << msg
  @debug_output << "\n"
end

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

Также имеет псевдоним: D
do_finish ()
Исходный код
# File lib/net/http.rb, line 1775
def do_finish
  @started = false
  @socket.close if @socket
  @socket = nil
end
do_start ()
Исходный код
# File lib/net/http.rb, line 1635
def do_start
  connect
  @started = true
end
edit_path (path)
Исходный код
# File lib/net/http.rb, line 1934
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 2479
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 2496
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 1757
def on_connect
end
send_entity (path, data, initheader, dest, type, &block)
Исходный код
# File lib/net/http.rb, line 2390
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 2520
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 2505
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 2401
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?) {
      if block_given?
        count = max_retries # Don't restart in the middle of a download
        yield res
      end
    }
  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 1919
def unescape(value)
  require 'cgi/util'
  CGI.unescape(value)
end

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

Spec-Zone.ru

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