Spec-Zone.ru › Python 3.12

http.server — HTTP-серверы

Исходный код: Lib/http/server.py

Этот модуль определяет классы для реализации HTTP-серверов.

Предупреждение

http.server не рекомендуется для использования в производстве. Он реализует только базовые проверки безопасности.

Доступность: не Emscripten, не WASI.

Этот модуль не работает или недоступен на платформах WebAssembly wasm32-emscripten и wasm32-wasi. См. Платформы WebAssembly для получения дополнительной информации.

Один класс, HTTPServer, является подклассом socketserver.TCPServer. Он создаёт и прослушивает HTTP-сокет, передавая запросы обработчику. Код для создания и запуска сервера выглядит следующим образом:

def run(server_class=HTTPServer, handler_class=BaseHTTPRequestHandler):
    server_address = ('', 8000)
    httpd = server_class(server_address, handler_class)
    httpd.serve_forever()
class http.server.HTTPServer(server_address, RequestHandlerClass)

Этот класс основан на классе TCPServer и хранит адрес сервера в переменных экземпляра с именами server_name и server_port. Сервер доступен обработчику, обычно через переменную экземпляра обработчика server.

class http.server.ThreadingHTTPServer(server_address, RequestHandlerClass)

Этот класс идентичен HTTPServer, но использует потоки для обработки запросов, используя ThreadingMixIn. Это полезно для обработки случаев, когда веб-браузеры предварительно открывают сокеты, на которых HTTPServer будет ожидать неопределённо долго.

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

Для HTTPServer и ThreadingHTTPServer необходимо указать RequestHandlerClass при создании экземпляра, для которого этот модуль предоставляет три варианта:

class http.server.BaseHTTPRequestHandler(request, client_address, server)

Этот класс используется для обработки HTTP-запросов, поступающих на сервер. Сам по себе он не может отвечать на реальные HTTP-запросы; он должен быть расширен, чтобы обрабатывать каждый метод запроса (например, GET или POST). BaseHTTPRequestHandler предоставляет ряд переменных класса и экземпляра, а также методы для использования подклассами.

Обработчик будет анализировать запрос и заголовки, а затем вызывать метод, специфичный для типа запроса. Имя метода строится из запроса. Например, для метода запроса SPAM, будет вызван метод do_SPAM() без аргументов. Вся релевантная информация хранится в переменных экземпляра обработчика. Подклассам не нужно переопределять или расширять метод __init__().

BaseHTTPRequestHandler имеет следующие переменные экземпляра:

client_address

Содержит кортеж вида (host, port), относящийся к адресу клиента.

server

Содержит экземпляр сервера.

close_connection

Булево значение, которое должно быть установлено перед тем, как handle_one_request() вернётся, указывая, ожидается ли ещё запрос или соединение должно быть закрыто.

requestline

Содержит строковое представление строки HTTP-запроса. Завершающий CRLF удаляется. Это свойство должно быть установлено методом handle_one_request(). Если не был обработан действительный запрос, оно должно быть установлено в пустую строку.

command

Содержит команду (тип запроса). Например, 'GET'.

path

Содержит путь запроса. Если в URL есть компонент запроса, то path включает запрос. Используя терминологию RFC 3986, path здесь включает hier-part и query.

request_version

Содержит строку версии из запроса. Например, 'HTTP/1.0'.

headers

Содержит экземпляр класса, указанного переменной класса MessageClass. Этот экземпляр анализирует и управляет заголовками в HTTP-запросе. Функция parse_headers() из http.client используется для анализа заголовков, и она требует, чтобы HTTP-запрос предоставлял действительный заголовок в стиле RFC 2822.

rfile

Поток ввода io.BufferedIOBase, готовый к чтению с начала необязательных входных данных.

wfile

Содержит поток вывода для записи ответа обратно клиенту. При записи в этот поток необходимо строго следовать протоколу HTTP для успешной работы с HTTP-клиентами.

Изменено в версии 3.6: Это поток io.BufferedIOBase.

BaseHTTPRequestHandler имеет следующие атрибуты:

server_version

Указывает версию программного обеспечения сервера. Вы можете это переопределить. Формат — несколько разделенных пробелами строк, где каждая строка имеет вид имя[/версия]. Например, 'BaseHTTP/0.2'.

sys_version

Содержит версию Python, в формате, используемом методом version_string и переменной класса server_version. Например, 'Python/1.4'.

error_message_format

Указывает строку формата, которая должна использоваться методом send_error() для создания ответа об ошибке для клиента. Строка заполняется по умолчанию переменными из responses на основе кода состояния, переданного методу send_error().

error_content_type

Указывает заголовок Content-Type HTTP ответа об ошибке, отправляемого клиенту. Значение по умолчанию — 'text/html'.

protocol_version

Указывает версию HTTP, с которой сервер совместим. Она отправляется в ответах, чтобы клиент знал возможности сервера для будущих запросов. Если установлено значение 'HTTP/1.1', сервер позволит HTTP-постоянным соединениям; однако ваш сервер обязан затем включить правильный заголовок Content-Length (используя send_header()) во всех ответах клиентам. Для обратной совместимости значение по умолчанию — 'HTTP/1.0'.

MessageClass

Указывает класс типа email.message.Message для анализа HTTP-заголовков. Как правило, это не переопределяется, и по умолчанию используется http.client.HTTPMessage.

responses

Этот атрибут содержит сопоставление целых чисел кодов ошибок с кортежами из двух элементов, содержащими короткое и длинное сообщение. Например, {code: (shortmessage, longmessage)}. shortmessage обычно используется в качестве ключа message в ответе об ошибке, а longmessage — как ключ explain. Используется методами send_response_only() и send_error().

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

handle()

Вызывает handle_one_request() один раз (или, если включены постоянные соединения, несколько раз) для обработки входящих HTTP-запросов. Вам никогда не нужно его переопределять; вместо этого реализуйте соответствующие методы do_*().

handle_one_request()

Этот метод проанализирует и направит запрос соответствующему методу do_*(). Вам никогда не нужно его переопределять.

handle_expect_100()

Когда сервер HTTP/1.1 получает заголовок запроса Expect: 100-continue, он отвечает 100 Continue за которым следуют 200 OK заголовки. Этот метод можно переопределить, чтобы вызвать ошибку, если сервер не хочет, чтобы клиент продолжил. Например, сервер может выбрать отправку 417 Expectation Failed в качестве заголовка ответа и return False.

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

send_error(code, message=None, explain=None)

Отправляет и регистрирует полный ответ об ошибке клиенту. Числовое значение code указывает код HTTP-ошибки, а message — необязательное, короткое, понятное для человека описание ошибки. Аргумент explain может быть использован для предоставления более подробной информации об ошибке; он будет отформатирован с использованием атрибута error_message_format и выведен после полного набора заголовков в качестве тела ответа. Атрибут responses содержит значения по умолчанию для message и explain, которые будут использованы, если не указаны; для неизвестных кодов значение по умолчанию для обоих — строка ???. Тело будет пустым, если метод — HEAD или код ответа — один из следующих: 1xx, 204 No Content, 205 Reset Content, 304 Not Modified.

Изменено в версии 3.4: Ответ об ошибке включает заголовок Content-Length. Добавлен аргумент explain.

send_response(code, message=None)

Добавляет заголовок ответа в буфер заголовков и регистрирует принятый запрос. Строка HTTP-ответа записывается во внутренний буфер, за ней следуют заголовки Server и Date. Значения этих двух заголовков взяты из методов version_string() и date_time_string() соответственно. Если сервер не намерен отправлять другие заголовки с помощью метода send_header(), то вызов send_response() должен быть последовыательно за вызовом end_headers().

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

send_header(keyword, value)

Добавляет HTTP-заголовок во внутренний буфер, который будет записан в выходной поток при вызове end_headers() или flush_headers(). keyword должен указать имя заголовка, а value — его значение. Обратите внимание, что после вызовов send_header, end_headers() ОБЯЗАТЕЛЬНО должен быть вызван для завершения операции.

Изменено в версии 3.2: Заголовки хранятся во внутреннем буфере.

send_response_only(code, message=None)

Отправляет только заголовок ответа, используется в тех случаях, когда сервер отправляет клиенту 100 Continue ответ. Заголовки не буферизуются и отправляются непосредственно в выходной поток. Если message не указан, отправляется HTTP-сообщение, соответствующее коду code.

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

end_headers()

Добавляет пустую строку (указывает конец HTTP-заголовков в ответе) в буфер заголовков и вызывает flush_headers().

Изменено в версии 3.2: Буферизованные заголовки записываются в выходной поток.

flush_headers()

Наконец, отправляет заголовки в выходной поток и очищает внутренний буфер заголовков.

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

log_request(code='-', size='-')

Регистрирует принятый (успешный) запрос. code должен указать числовой HTTP-код, связанный с ответом. Если размер ответа доступен, он должен быть передан как параметр size.

log_error(...)

Регистрирует ошибку, когда запрос не может быть выполнен. По умолчанию он передает сообщение в log_message(), поэтому принимает те же аргументы (format и дополнительные значения).

log_message(format, ...)

Регистрирует произвольное сообщение в sys.stderr. Обычно это переопределяется для создания собственных механизмов регистрации ошибок. Аргумент format — это строка формата в стиле printf, где дополнительные аргументы к log_message() применяются как входные данные для форматирования. К каждому зарегистрированному сообщению добавляются IP-адрес клиента и текущая дата и время.

version_string()

Возвращает строку версии программного обеспечения сервера. Это комбинация атрибутов server_version и sys_version.

date_time_string(timestamp=None)

Возвращает дату и время, заданные timestamp (который должен быть None или в формате, возвращаемом time.time()), отформатированном для заголовка сообщения. Если timestamp опущен, используется текущая дата и время.

Результат выглядит как 'Sun, 06 Nov 1994 08:49:37 GMT'.

log_date_time_string()

Возвращает текущую дату и время, отформатированную для регистрации.

address_string()

Возвращает адрес клиента.

Изменено в версии 3.3: Ранее выполнялся поиск имени. Чтобы избежать задержек при разрешении имен, теперь он всегда возвращает IP-адрес.

class http.server.SimpleHTTPRequestHandler(request, client_address, server, directory=None)

Этот класс предоставляет файлы из каталога directory и ниже, или из текущего каталога, если directory не указан, напрямую сопоставляя структуру каталогов с HTTP-запросами.

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

Изменено в версии 3.9: Параметр directory принимает объект-путь.

Большая часть работы, такая как парсинг запроса, выполняется базовым классом BaseHTTPRequestHandler. Этот класс реализует функции do_GET() и do_HEAD().

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

server_version

Это будет "SimpleHTTP/" + __version__, где __version__ определено на уровне модуля.

extensions_map

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

Изменено в версии 3.9: Этот словарь больше не заполняется стандартными системными сопоставлениями, а содержит только переопределения.

Класс SimpleHTTPRequestHandler определяет следующие методы:

do_HEAD()

Этот метод обрабатывает запрос типа 'HEAD': он отправляет заголовки, которые он отправил бы для эквивалентного запроса GET. См. метод do_GET() для более полного объяснения возможных заголовков.

do_GET()

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

Если запрос был сопоставлен с каталогом, каталог проверяется на наличие файла с именем index.html или index.htm (в указанном порядке). Если найден, содержимое файла возвращается; в противном случае генерируется список каталога путём вызова метода list_directory(). Этот метод использует os.listdir() для сканирования каталога и возвращает ошибочный ответ 500, если listdir() завершается с ошибкой.

Если запрос был сопоставлен с файлом, он открывается. Любая ошибка OSError при открытии запрошенного файла преобразуется в ошибку 404, 'File not found'. Если в запросе был заголовок 'If-Modified-Since', и файл не изменялся после этого времени, отправляется ответ 304, 'Not Modified'. В противном случае тип содержимого определяется путём вызова метода guess_type(), который в свою очередь использует переменную extensions_map, и содержимое файла возвращается.

Выводится заголовок 'Content-type:' с предполагаемым типом содержимого, за которым следует заголовок 'Content-Length:' с размером файла и заголовок 'Last-Modified:' с временем изменения файла.

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

Пример использования см. в реализации функции test в Lib/http/server.py.

Изменено в версии 3.7: Поддержка заголовка 'If-Modified-Since'.

Класс SimpleHTTPRequestHandler может быть использован следующим образом для создания очень простого веб-сервера, предоставляющего файлы, относительные к текущей директории:

import http.server
import socketserver

PORT = 8000

Handler = http.server.SimpleHTTPRequestHandler

with socketserver.TCPServer(("", PORT), Handler) as httpd:
    print("serving at port", PORT)
    httpd.serve_forever()

SimpleHTTPRequestHandler также может быть расширен, чтобы улучшить поведение, например, использовать различные имена файлов-индексов путём переопределения атрибута класса index_pages.

http.server также можно вызвать напрямую, используя переключатель -m интерпретатора. Аналогично предыдущему примеру, это предоставляет файлы, относительные к текущей директории:

python -m http.server

Сервер прослушивает порт 8000 по умолчанию. По умолчанию можно переопределить, передав номер желаемого порта в качестве аргумента:

python -m http.server 9000

По умолчанию сервер связывается со всеми интерфейсами. Опция -b/--bind указывает конкретный адрес, к которому он должен подключиться. Поддерживаются как IPv4, так и IPv6 адреса. Например, следующая команда заставляет сервер связываться только с localhost:

python -m http.server --bind 127.0.0.1

Изменено в версии 3.4: Добавлена опция --bind.

Изменено в версии 3.8: Поддержка IPv6 в опции --bind.

По умолчанию сервер использует текущую директорию. Опция -d/--directory указывает директорию, к которой он должен предоставлять файлы. Например, следующая команда использует определённую директорию:

python -m http.server --directory /tmp/

Изменено в версии 3.7: Добавлена опция --directory.

По умолчанию сервер соответствует HTTP/1.0. Опция -p/--protocol указывает версию HTTP, к которой сервер соответствует. Например, следующая команда запускает сервер, соответствующий HTTP/1.1:

python -m http.server --protocol HTTP/1.1

Изменено в версии 3.11: Добавлена опция --protocol.

class http.server.CGIHTTPRequestHandler(request, client_address, server)

Этот класс используется для предоставления либо файлов, либо вывода CGI-скриптов из текущей директории и ниже. Обратите внимание, что сопоставление иерархической структуры HTTP с локальной структурой директорий точно такое же, как в SimpleHTTPRequestHandler.

Примечание

CGI-скрипты, запускаемые классом CGIHTTPRequestHandler, не могут выполнять перенаправления (HTTP-код 302), потому что код 200 (выход скрипта следует) отправляется до запуска CGI-скрипта. Это перекрывает код статуса.

Однако класс запустит CGI-скрипт вместо того, чтобы предоставить его как файл, если определит его как CGI-скрипт. Используются только CGI на основе каталогов — другая распространенная конфигурация сервера заключается в обработке специальных расширений как обозначения CGI-скриптов.

Функции do_GET() и do_HEAD() изменены для запуска CGI-скриптов и предоставления вывода вместо предоставления файлов, если запрос ведёт к адресу ниже пути cgi_directories.

Класс CGIHTTPRequestHandler определяет следующий член данных:

cgi_directories

По умолчанию он равен ['/cgi-bin', '/htbin'] и описывает каталоги, которые следует рассматривать как содержащие CGI-скрипты.

Класс CGIHTTPRequestHandler определяет следующий метод:

do_POST()

Этот метод обрабатывает запрос типа 'POST', разрешённый только для CGI-скриптов. Ошибка 501, «Можно отправлять POST только в CGI-скрипты», выводится при попытке отправки POST на не-CGI URL.

Обратите внимание, что CGI-скрипты будут запускаться с UID пользователя nobody по соображениям безопасности. Проблемы с CGI-скриптом будут преобразованы в ошибку 403.

CGIHTTPRequestHandler может быть включён в командной строке путём передачи опции --cgi:

python -m http.server --cgi

Предупреждение

CGIHTTPRequestHandler и опция командной строки --cgi не предназначены для использования ненадёжными клиентами и могут быть уязвимы к эксплойтам. Используйте всегда в защищённой среде.

Общие соображения по безопасности

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

В более ранних версиях Python управляющие символы не удалялись из сообщений журнала, выводимых в stderr от python -m http.server или реализации по умолчанию BaseHTTPRequestHandler .log_message. Это могло позволить удалённым клиентам, подключённым к вашему серверу, отправлять вредные управляющие коды в вашу консоль.

Изменено в версии 3.12: Управляющие символы удаляются в журналах stderr.

© 2001–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.12/library/http.server.html

Spec-Zone.ru

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