http.client — Клиент протокола HTTP

Источник: Lib/http/client.py


Этот модуль определяет классы, реализующие клиентскую часть протоколов HTTP и HTTPS. Обычно он не используется напрямую - модуль urllib.request использует его для обработки URL, использующих HTTP и HTTPS.

См.также

Значение Requests package рекомендуется для клиентского интерфейса HTTP более высокого уровня.

Примечание

Поддержка HTTPS доступна только в том случае, если Python был скомпилирован с поддержкой SSL (через модуль ssl).

Availability: не WASI.

Этот модуль не работает или недоступен на WebAssembly. Дополнительную информацию см. в разделе Платформы WebAssembly.

Модуль предоставляет следующие классы:

class http.client.HTTPConnection(host, port=None, [timeout, ]source_address=None, blocksize=8192)

Экземпляр HTTPConnection представляет собой одну транзакцию с HTTP-сервером. Для его инстанцирования необходимо передать ему хост и необязательный номер порта. Если номер порта не передан, порт извлекается из строки хоста, если она имеет вид host:port, в противном случае используется HTTP-порт по умолчанию (80). Если указан необязательный параметр timeout, блокирующие операции (например, попытки соединения) завершаются по истечении этого количества секунд (если параметр не указан, используется глобальное значение таймаута по умолчанию). Необязательный параметр source_address может представлять собой кортеж (хост, порт), используемый в качестве адреса источника, с которого устанавливается HTTP-соединение. Необязательный параметр blocksize задает размер буфера в байтах для отправки файлоподобного тела сообщения.

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

>>> h1 = http.client.HTTPConnection('www.python.org')
>>> h2 = http.client.HTTPConnection('www.python.org:80')
>>> h3 = http.client.HTTPConnection('www.python.org', 80)
>>> h4 = http.client.HTTPConnection('www.python.org', 80, timeout=10)

Изменено в версии 3.2: Был добавлен адрес_источника.

Изменено в версии 3.4: Параметр strict был удален. «Простые ответы» в стиле HTTP 0.9 больше не поддерживаются.

Изменено в версии 3.7: Добавлен параметр blocksize.

class http.client.HTTPSConnection(host, port=None, *, [timeout, ]source_address=None, context=None, blocksize=8192)

Подкласс HTTPConnection, использующий SSL для связи с защищенными серверами. По умолчанию используется порт 443. Если указан context, то это должен быть экземпляр ssl.SSLContext, описывающий различные опции SSL.

Пожалуйста, прочитайте Соображения безопасности для получения дополнительной информации о лучших практиках.

Изменено в версии 3.2: Были добавлены source_address, context и check_hostname.

Изменено в версии 3.2: Этот класс теперь поддерживает виртуальные хосты HTTPS, если это возможно (то есть, если ssl.HAS_SNI равен true).

Изменено в версии 3.4: Параметр strict был удален. «Простые ответы» в стиле HTTP 0.9 больше не поддерживаются.

Изменено в версии 3.4.3: Теперь этот класс по умолчанию выполняет все необходимые проверки сертификатов и имен хостов. Чтобы вернуться к предыдущему, непроверенному, поведению, в параметр context можно передать ssl._create_unverified_context().

Изменено в версии 3.8: Этот класс теперь включает TLS 1.3 ssl.SSLContext.post_handshake_auth для стандартного контекста или когда cert_file передается вместе с пользовательским контекстом.

Изменено в версии 3.10: Теперь этот класс отправляет расширение ALPN с индикатором протокола http/1.1, когда не задан контекст. Пользовательский контекст должен устанавливать протоколы ALPN с индикатором set_alpn_protocols().

Изменено в версии 3.12: Устаревшие параметры key_file, cert_file и check_hostname были удалены.

class http.client.HTTPResponse(sock, debuglevel=0, method=None, url=None)

Класс, экземпляры которого возвращаются при успешном подключении. Не инстанцируется непосредственно пользователем.

Изменено в версии 3.4: Параметр strict был удален. Стиль HTTP 0.9 «Простые ответы» больше не поддерживается.

Этот модуль выполняет следующие функции:

http.client.parse_headers(fp)

Разбор заголовков из файла-указателя fp, представляющего HTTP-запрос/ответ. Файл должен быть BufferedIOBase читаемым (т. е. не текстовым) и должен содержать корректный заголовок в стиле RFC 2822.

Эта функция возвращает экземпляр http.client.HTTPMessage, содержащий поля заголовка, но без полезной нагрузки (как и HTTPResponse.msg и http.server.BaseHTTPRequestHandler.headers). После возврата указатель файла fp готов к чтению тела HTTP.

Примечание

Функция parse_headers() не разбирает начальную строку HTTP-сообщения; она разбирает только строки Name: value. Файл должен быть готов к чтению этих строк поля, поэтому первая строка должна быть уже обработана до вызова функции.

Следующие исключения будут сделаны по мере необходимости:

exception http.client.HTTPException

Базовый класс остальных исключений в этом модуле. Является подклассом Exception.

exception http.client.NotConnected

Подкласс HTTPException.

exception http.client.InvalidURL

Подкласс HTTPException, возникающий, если задан порт, который либо не является числовым, либо пуст.

exception http.client.UnknownProtocol

Подкласс HTTPException.

exception http.client.UnknownTransferEncoding

Подкласс HTTPException.

exception http.client.UnimplementedFileMode

Подкласс HTTPException.

exception http.client.IncompleteRead

Подкласс HTTPException.

exception http.client.ImproperConnectionState

Подкласс HTTPException.

exception http.client.CannotSendRequest

Подкласс ImproperConnectionState.

exception http.client.CannotSendHeader

Подкласс ImproperConnectionState.

exception http.client.ResponseNotReady

Подкласс ImproperConnectionState.

exception http.client.BadStatusLine

Подкласс HTTPException. Возникает, если сервер отвечает непонятным нам кодом состояния HTTP.

exception http.client.LineTooLong

Подкласс HTTPException. Возникает, если в протоколе HTTP от сервера получена слишком длинная строка.

exception http.client.RemoteDisconnected

Подкласс ConnectionResetError и BadStatusLine. Вызывается HTTPConnection.getresponse(), когда попытка прочитать ответ не приводит к считыванию данных из соединения, указывая на то, что удаленный конец закрыл соединение.

Added in version 3.5: Ранее были подняты BadStatusLine('').

В этом модуле определены следующие константы:

http.client.HTTP_PORT

Порт по умолчанию для протокола HTTP (всегда 80).

http.client.HTTPS_PORT

Порт по умолчанию для протокола HTTPS (всегда 443).

http.client.responses

Этот словарь сопоставляет коды состояния HTTP 1.1 с названиями W3C.

Пример: http.client.responses[http.client.NOT_FOUND] - это 'Not Found'.

Список кодов состояния HTTP, которые доступны в этом модуле в виде констант, смотрите в Коды состояния HTTP.

Объекты HTTPConnection

У экземпляров HTTPConnection есть следующие методы:

HTTPConnection.request(method, url, body=None, headers={}, *, encode_chunked=False)

Это отправит запрос на сервер, используя метод HTTP-запроса method и URI запроса url. Указанный url должен быть абсолютным путем, чтобы соответствовать стандарту RFC 2616 §5.1.2 (если только вы не подключаетесь к HTTP-прокси-серверу или не используете методы OPTIONS или CONNECT).

Если указано body, то после завершения заголовков будут отправлены указанные данные. Это может быть str, bytes-like object, открытый file object или итерируемый bytes. Если body - строка, она кодируется как ISO-8859-1, по умолчанию для HTTP. Если это байтоподобный объект, то байты отправляются как есть. Если это объект типа file object, отправляется содержимое файла; этот объект файла должен поддерживать, по крайней мере, метод read(). Если объект файла является экземпляром io.TextIOBase, то данные, возвращаемые методом read(), будут закодированы как ISO-8859-1, в противном случае данные, возвращаемые методом read(), отправляются как есть. Если body является итерируемым объектом, элементы итерируемого объекта отправляются как есть до тех пор, пока итерируемый объект не будет исчерпан.

Аргумент headers должен представлять собой отображение дополнительных HTTP-заголовков для отправки вместе с запросом. Необходимо указать Host header, чтобы соответствовать RFC 2616 §5.1.2 (если только вы не подключаетесь к HTTP-прокси-серверу или не используете методы OPTIONS или CONNECT).

Если headers не содержит ни Content-Length, ни Transfer-Encoding, но есть тело запроса, одно из этих полей заголовка будет добавлено автоматически. Если body имеет значение None, заголовок Content-Length устанавливается в значение 0 для методов, ожидающих тело (PUT, POST и PATCH). Если body является строкой или байтоподобным объектом, который также не является file, заголовок Content-Length устанавливается на его длину. Любой другой тип body (файлы и итерабельные объекты в целом) будет закодирован в чанки, и вместо Content-Length автоматически будет установлен заголовок Transfer-Encoding.

Аргумент encode_chunked имеет значение только в том случае, если в headers указано Transfer-Encoding. Если encode_chunked равен False, то объект HTTPConnection предполагает, что все кодировки обрабатываются вызывающим кодом. Если значение True, тело будет закодировано по частям.

Например, чтобы выполнить запрос GET к https://docs.python.org/3/:

>>> import http.client
>>> host = "docs.python.org"
>>> conn = http.client.HTTPSConnection(host)
>>> conn.request("GET", "/3/", headers={"Host": host})
>>> response = conn.getresponse()
>>> print(response.status, response.reason)
200 OK

Примечание

В протокол HTTP версии 1.1 было добавлено кодирование передачи в виде кусков. Если не известно, что HTTP-сервер поддерживает HTTP 1.1, вызывающая сторона должна либо указать Content-Length, либо передать str или байтоподобный объект, который не является файлом, в качестве представления тела.

Изменено в версии 3.2: Теперь body может быть итерируемым.

Изменено в версии 3.6: Если в заголовках не заданы ни Content-Length, ни Transfer-Encoding, объекты file и iterable body теперь кодируются в виде кусков. Был добавлен аргумент encode_chunked. Не делается попыток определить Content-Length для файловых объектов.

HTTPConnection.getresponse()

Вызывается после отправки запроса, чтобы получить ответ от сервера. Возвращает экземпляр HTTPResponse.

Примечание

Обратите внимание, что вы должны прочитать весь ответ, прежде чем отправлять новый запрос на сервер.

Изменено в версии 3.5: Если поднят ConnectionError или подкласс, то объект HTTPConnection будет готов к переподключению при отправке нового запроса.

HTTPConnection.set_debuglevel(level)

Установка уровня отладки. По умолчанию уровень отладки равен 0, что означает, что отладочный вывод не выводится. Любое значение, превышающее 0, приведет к тому, что все определенные в данный момент отладочные данные будут выведены в stdout. Значение debuglevel передается всем новым создаваемым объектам HTTPResponse.

Added in version 3.1.

HTTPConnection.set_tunnel(host, port=None, headers=None)

Установите хост и порт для HTTP Connect Tunnelling. Это позволяет запускать соединение через прокси-сервер.

Аргументы host и port указывают конечную точку туннелируемого соединения (т.е. адрес, включенный в запрос CONNECT, не адрес прокси-сервера).

Аргумент headers должен представлять собой отображение дополнительных HTTP-заголовков, которые следует отправить вместе с запросом CONNECT.

Поскольку HTTP/1.1 используется для туннельного запроса HTTP CONNECT, as per the RFC, должен быть предоставлен заголовок HTTP Host:, соответствующий авторитетной форме цели запроса, указанной в качестве назначения для запроса CONNECT. Если заголовок HTTP Host: не указан в аргументе headers, он генерируется и передается автоматически.

Например, чтобы проложить туннель через HTTPS-прокси-сервер, работающий локально на порту 8080, мы передадим адрес прокси в конструктор HTTPSConnection, а адрес хоста, до которого мы хотим добраться, в метод set_tunnel():

>>> import http.client
>>> conn = http.client.HTTPSConnection("localhost", 8080)
>>> conn.set_tunnel("www.python.org")
>>> conn.request("HEAD","/index.html")

Added in version 3.2.

Изменено в версии 3.12: Туннельные запросы HTTP CONNECT используют протокол HTTP/1.1, усовершенствованный по сравнению с протоколом HTTP/1.0. Host: HTTP-заголовки являются обязательными для HTTP/1.1, поэтому один из них будет автоматически сгенерирован и передан, если он не указан в аргументе headers.

HTTPConnection.get_proxy_response_headers()

Возвращает словарь с заголовками ответа, полученного от прокси-сервера на запрос CONNECT.

Если запрос CONNECT не был отправлен, метод возвращает None.

Added in version 3.12.

HTTPConnection.connect()

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

Поднимает auditing event http.client.connect с аргументами self, host, port.

HTTPConnection.close()

Закройте соединение с сервером.

HTTPConnection.blocksize

Размер буфера в байтах для отправки файлоподобного тела сообщения.

Added in version 3.7.

В качестве альтернативы описанному выше методу request() вы также можете отправить запрос шаг за шагом, используя четыре функции, приведенные ниже.

HTTPConnection.putrequest(method, url, skip_host=False, skip_accept_encoding=False)

Это должен быть первый вызов после установления соединения с сервером. Он отправляет на сервер строку, состоящую из строки method, строки url и версии HTTP (HTTP/1.1). Чтобы отключить автоматическую отправку заголовков Host: или Accept-Encoding: (например, чтобы принять дополнительные кодировки содержимого), укажите skip_host или skip_accept_encoding со значениями, отличными от False.

HTTPConnection.putheader(header, argument[, ...])

Отправляет на сервер заголовок в стиле RFC 822. Отправляет на сервер строку, состоящую из заголовка, двоеточия и пробела, а также первого аргумента. Если указано больше аргументов, отправляются продолженные строки, каждая из которых состоит из табуляции и аргумента.

HTTPConnection.endheaders(message_body=None, *, encode_chunked=False)

Отправляет серверу пустую строку, сигнализирующую о завершении заголовков. Необязательный аргумент message_body может быть использован для передачи тела сообщения, связанного с запросом.

Если encode_chunked имеет значение True, результат каждой итерации message_body будет закодирован в виде кусков, как указано в RFC 7230, раздел 3.3.1. Способ кодирования данных зависит от типа message_body. Если message_body реализует buffer interface, то в результате кодирования будет получен один чанк. Если message_body представляет собой collections.abc.Iterable, то каждая итерация message_body приведет к появлению чанка. Если message_body - это file object, то каждый вызов .read() будет содержать один чанк. Метод автоматически сигнализирует о конце закодированных в чанк данных сразу после message_body.

Примечание

В соответствии со спецификацией кодирования chunked, пустые куски, выдаваемые телом итератора, будут игнорироваться chunk-encoder’ом. Это необходимо для того, чтобы избежать преждевременного завершения чтения запроса целевым сервером из-за неправильного кодирования.

Изменено в версии 3.6: Добавлена поддержка кодировки chunked и параметр encode_chunked.

HTTPConnection.send(data)

Отправка данных на сервер. Этот метод следует использовать непосредственно только после вызова метода endheaders() и до вызова getresponse().

Поднимает auditing event http.client.send с аргументами self, data.

Объекты HTTPResponse

Экземпляр HTTPResponse оборачивает HTTP-ответ от сервера. Он предоставляет доступ к заголовкам запроса и телу сущности. Ответ является итерируемым объектом и может быть использован в операторе with.

Изменено в версии 3.5: Интерфейс io.BufferedIOBase теперь реализован, и все его операции чтения поддерживаются.

HTTPResponse.read([amt])

Считывает и возвращает тело ответа или до следующего amt байта.

HTTPResponse.readinto(b)

Считывает до следующего len(b) байта тела ответа в буфер b. Возвращает количество прочитанных байт.

Added in version 3.3.

HTTPResponse.getheader(name, default=None)

Возвращает значение заголовка name, или default, если нет заголовка, соответствующего name. Если существует более одного заголовка с именем name, возвращаются все значения, объединенные символами „, „. Если default - это любая итерируемая величина, отличная от одиночной строки, ее элементы аналогично возвращаются через запятую.

HTTPResponse.getheaders()

Возвращает список кортежей (заголовок, значение).

HTTPResponse.fileno()

Возвращает fileno базового сокета.

HTTPResponse.msg

Экземпляр http.client.HTTPMessage, содержащий заголовки ответа. http.client.HTTPMessage является подклассом email.message.Message.

HTTPResponse.version

Версия протокола HTTP, используемая сервером. 10 для HTTP/1.0, 11 для HTTP/1.1.

HTTPResponse.url

URL-адрес полученного ресурса, обычно используется для определения того, было ли выполнено перенаправление.

HTTPResponse.headers

Заголовки ответа в виде экземпляра email.message.EmailMessage.

HTTPResponse.status

Код состояния, возвращаемый сервером.

HTTPResponse.reason

Фраза причины, возвращаемая сервером.

HTTPResponse.debuglevel

Отладочный крючок. Если debuglevel больше нуля, сообщения будут выводиться в stdout по мере чтения и разбора ответа.

HTTPResponse.closed

Принимает значение True, если поток закрыт.

HTTPResponse.geturl()

Не рекомендуется, начиная с версии 3.9: Утратил актуальность в пользу url.

HTTPResponse.info()

Не рекомендуется, начиная с версии 3.9: Утратил актуальность в пользу headers.

HTTPResponse.getcode()

Не рекомендуется, начиная с версии 3.9: Утратил актуальность в пользу status.

Примеры

Вот пример сессии, в которой используется метод GET:

>>> import http.client
>>> conn = http.client.HTTPSConnection("www.python.org")
>>> conn.request("GET", "/")
>>> r1 = conn.getresponse()
>>> print(r1.status, r1.reason)
200 OK
>>> data1 = r1.read()  # This will return entire content.
>>> # The following example demonstrates reading data in chunks.
>>> conn.request("GET", "/")
>>> r1 = conn.getresponse()
>>> while chunk := r1.read(200):
...     print(repr(chunk))
b'<!doctype html>\n<!--[if"...
...
>>> # Example of an invalid request
>>> conn = http.client.HTTPSConnection("docs.python.org")
>>> conn.request("GET", "/parrot.spam")
>>> r2 = conn.getresponse()
>>> print(r2.status, r2.reason)
404 Not Found
>>> data2 = r2.read()
>>> conn.close()

Вот пример сессии, в которой используется метод HEAD. Обратите внимание, что метод HEAD никогда не возвращает никаких данных.

>>> import http.client
>>> conn = http.client.HTTPSConnection("www.python.org")
>>> conn.request("HEAD", "/")
>>> res = conn.getresponse()
>>> print(res.status, res.reason)
200 OK
>>> data = res.read()
>>> print(len(data))
0
>>> data == b''
True

Вот пример сессии, в которой используется метод POST:

>>> import http.client, urllib.parse
>>> params = urllib.parse.urlencode({'@number': 12524, '@type': 'issue', '@action': 'show'})
>>> headers = {"Content-type": "application/x-www-form-urlencoded",
...            "Accept": "text/plain"}
>>> conn = http.client.HTTPConnection("bugs.python.org")
>>> conn.request("POST", "", params, headers)
>>> response = conn.getresponse()
>>> print(response.status, response.reason)
302 Found
>>> data = response.read()
>>> data
b'Redirecting to <a href="https://bugs.python.org/issue12524">https://bugs.python.org/issue12524</a>'
>>> conn.close()

Клиентские HTTP-запросы PUT очень похожи на запросы POST. Разница заключается только на стороне сервера, где HTTP-серверы позволяют создавать ресурсы с помощью PUT запросов. Следует отметить, что пользовательские HTTP-методы также обрабатываются в urllib.request.Request путем установки соответствующего атрибута method. Вот пример сессии, использующей метод PUT:

>>> # This creates an HTTP request
>>> # with the content of BODY as the enclosed representation
>>> # for the resource http://localhost:8080/file
...
>>> import http.client
>>> BODY = "***filecontents***"
>>> conn = http.client.HTTPConnection("localhost", 8080)
>>> conn.request("PUT", "/file", BODY)
>>> response = conn.getresponse()
>>> print(response.status, response.reason)
200, OK

Объекты HTTPMessage

class http.client.HTTPMessage(email.message.Message)

Экземпляр http.client.HTTPMessage содержит заголовки HTTP-ответа. Он реализуется с помощью класса email.message.Message.