Документация Python неофициальный перевод
Содержание страницы

http.server – HTTP-серверыhttp.server – HTTP servers

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


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

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

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

Доступность: not Emscripten, not 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

Задаёт HTTP-заголовок Content-Type ответов об ошибках, отправляемых клиенту. Значение по умолчанию – '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() для обхода каталога и возвращает ответ с ошибкой 404, если 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.

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- скриптов. При попытке выполнить POST на не-CGI URL выводится ошибка 501: «Can only POST to CGI scripts».

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

Интерфейс командной строкиCommand-line interface

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

python -m http.server [OPTIONS] [port]

Принимаются следующие опции:

port

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

python -m http.server 9000
-b, --bind <address>

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

python -m http.server --bind 127.0.0.1

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

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

-d, --directory <dir>

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

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

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

-p, --protocol <version>

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

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

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

--cgi

CGIHTTPRequestHandler можно включить в командной строке, передав параметр --cgi:

python -m http.server --cgi

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

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

Соображения безопасностиSecurity considerations

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

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

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