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


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

См.также

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

Примечание

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

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

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('digitology.tech')
>>> h2 = http.client.HTTPConnection('digitology.tech:80')
>>> h3 = http.client.HTTPConnection('digitology.tech', 80)
>>> h4 = http.client.HTTPConnection('digitology.tech', 80, timeout=10)

Изменено в версии 3.2: Добавлен source_address.

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

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

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

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

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

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

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

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

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

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

Не рекомендуется, начиная с версии 3.6: key_file и cert_file устарели в пользу context. Вместо этого используйте ssl.SSLContext.load_cert_chain() или позвольте ssl.create_default_context() выбрать для вас доверенные CA сертификаты системы.

Параметр check_hostname также устарел; вместо этого следует использовать атрибут ssl.SSLContext.check_hostname context.

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(), когда попытка прочитать ответ приводит к тому, что данные из соединения не считываются, что указывает на то, что удалённый конец закрыл соединение.

Добавлено в версии 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, которые доступны в этом модуле как константы.

Объекты HTTP-соединения

Экземпляры HTTPConnection имеют следующие методы:

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

Отправляет запрос на сервер, используя метод HTTP-запроса method и селектор url.

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

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

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

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

Примечание

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

Добавлено в версии 3.2: body теперь может быть итерируемым.

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

HTTPConnection.getresponse()

Должен вызываться после отправки запроса для получения ответа от сервера. Возвращает экземпляр HTTPResponse.

Примечание

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

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

HTTPConnection.set_debuglevel(level)

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

Добавлено в версии 3.1.

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

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

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

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

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

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

Добавлено в версии 3.2.

HTTPConnection.connect()

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

HTTPConnection.close()

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

HTTPConnection.blocksize

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

Добавлено в версии 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 реализует буферный интерфейс, результатом кодирования будет один фрагмент. Если message_body — это collections.abc.Iterable, то каждая итерация message_body приведёт к фрагменту. Если message_body — это файловый объект, то каждый вызов .read() приведёт к фрагменту. Метод автоматически сигнализирует об окончании закодированных данных сразу после message_body.

Примечание

Из-за спецификации фрагментированного кодирования пустые фрагменты полученный телом итератора, будут игнорироваться кодировщиком фрагментов. Это делается для того, чтобы избежать преждевременного завершения чтения запроса целевым сервером из-за неправильного кодирования.

Добавлено в версии 3.6: Поддержка фрагментированного кодирования. Добавлен параметр encode_chunked.

HTTPConnection.send(data)

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

Объекты HTTPResponse

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

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

HTTPResponse.read([amt])

Читает и возвращает тело ответа или до следующих amt байтов.

HTTPResponse.readinto(b)

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

Добавлено в версии 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.status

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

HTTPResponse.reason

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

HTTPResponse.debuglevel

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

HTTPResponse.closed

True, если поток закрыт.

Примеры

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

>>> import http.client
>>> conn = http.client.HTTPSConnection("digitology.tech")
>>> conn.request("GET", "/")
>>> r1 = conn.getresponse()
>>> print(r1.status, r1.reason)
200 OK
>>> data1 = r1.read()  # Это вернёт все содержимое целиком.
>>> # Следующий пример демонстрирует чтение данных порциями.
>>> conn.request("GET", "/")
>>> r1 = conn.getresponse()
>>> while chunk := r1.read(200):
...     print(repr(chunk))
b'<!doctype html>\n<!--[if"...
...
>>> # Пример недопустимого запроса
>>> conn = http.client.HTTPSConnection("digitology.tech")
>>> 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("digitology.tech")
>>> 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("digitology.tech")
>>> 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://digitology.tech/issue12524">https://digitology.tech/issue12524</a>'
>>> conn.close()

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

>>> # Это создаёт HTTP-сообщение
>>> # с содержанием BODY в качестве вложенного представления
>>> # для ресурса 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

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