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

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

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


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

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

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

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

Этот модуль не работает или недоступен на WebAssembly. Подробнее см. платформы 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 переменную экземпляра обработчика.

server_name

Полное доменное имя HTTP-сервера.

server_port

Номер порта HTTP-сервера, полученный из server_address.

class http.server.ThreadingHTTPServer(server_address, RequestHandlerClass)

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

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

class http.server.HTTPSServer(server_address, RequestHandlerClass, bind_and_activate=True, *, certfile, keyfile=None, password=None, alpn_protocols=None)

Подкласс HTTPServer с обёрнутым сокетом, использующим модуль ssl. Если модуль ssl недоступен, создание экземпляра HTTPSServer завершается ошибкой RuntimeError.

Аргумент certfile – это путь к файлу цепочки SSL-сертификатов, а keyfile – путь к файлу, содержащему закрытый ключ.

Для файлов, защищённых и зашифрованных с помощью PKCS#8, можно указать password, но стоит учитывать, что это может привести к раскрытию жёстко заданных паролей в открытом виде.

См. также

См. ssl.SSLContext.load_cert_chain() для получения дополнительной информации о допустимых значениях certfile, keyfile и password.

Если указан, аргумент alpn_protocols должен быть последовательностью строк, определяющих протоколы «Согласования протокола прикладного уровня» (ALPN), поддерживаемые сервером. ALPN позволяет серверу и клиенту согласовывать протокол прикладного уровня во время рукопожатия TLS.

По умолчанию он установлен в ["http/1.1"], что означает, что сервер поддерживает HTTP/1.1.

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

class http.server.ThreadingHTTPSServer(server_address, RequestHandlerClass, bind_and_activate=True, *, certfile, keyfile=None, password=None, alpn_protocols=None)

Этот класс идентичен HTTPSServer, но использует потоки для обработки запросов, наследуя от ThreadingMixIn. Это аналогично ThreadingHTTPServer, только с использованием HTTPSServer.

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

Классам HTTPServer, ThreadingHTTPServer, HTTPSServer и ThreadingHTTPSServer при создании экземпляра необходимо передать 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

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

request_version

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

headers

Holds an instance of the class specified by the MessageClass class variable. This instance parses and manages the headers in the HTTP request. The parse_headers() function from http.client is used to parse the headers and it requires that the HTTP request provide a valid RFC 5322 style header.

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() ДОЛЖЕН БЫТЬ ВЫЗВАН для завершения операции.

Этот метод не отклоняет ввод, содержащий последовательности CRLF.

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

send_response_only(code, message=None)

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

Этот метод не отклоняет message, содержащий последовательности CRLF.

Добавлено в версии 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__ определён на уровне модуля.

index_pages

Задаёт имена файлов, которые считаются страницами индекса каталога.

По умолчанию ("index.html", "index.htm").

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

extensions_map

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

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

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

do_HEAD()

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

do_GET()

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

Если запрос был сопоставлен с каталогом, каталог проверяется на наличие страницы индекса, как указано в index_pages. Если найдена, возвращается содержимое файла; в противном случае формируется список каталога вызовом метода 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:' со временем изменения файла.

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

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

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

list_directory(path)

Вспомогательная функция для отображения содержимого каталога path при отсутствии индексной страницы.

Возвращает либо файлоподобный объект (который должен быть закрыт вызывающей стороной), либо None для обозначения ошибки; в этом случае вызывающая сторона больше ничего не делает. В любом случае заголовки отправляются.

guess_type(path)

Определяет тип файла по указанному path.

Возвращает строку вида type/subtype, которую можно использовать в заголовке MIME Content-type.

Реализация по умолчанию ищет расширение файла в extensions_map; если не найдено, обращается к mimetypes.guess_file_type(), а затем к 'application/octet-stream'.

Изменено в версии 3.13: Добавлен mimetypes.guess_file_type() в качестве запасного варианта.

Класс 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.

Устарело с версии 3.13, будет удалено в версии 3.15: CGIHTTPRequestHandler будет удалён в 3.15. CGI уже далеко не первое десятилетие не считается хорошим способом решения задач. Этот код давно не поддерживается и практически не используется. Его сохранение может привести к дополнительным проблемам безопасности.

Интерфейс командной строки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

Устарело с версии 3.13, будет удалено в версии 3.15: http.server Поддержка командной строки --cgi удаляется, потому что CGIHTTPRequestHandler удаляется.

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

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

--tls-cert

Задаёт цепочку TLS-сертификатов для HTTPS-соединений:

python -m http.server --tls-cert fullchain.pem

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

--tls-key

Задаёт файл закрытого ключа для HTTPS-соединений.

Этот параметр требует указания --tls-cert.

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

--tls-password-file

Задаёт файл пароля для закрытых ключей, защищённых паролем:

python -m http.server \
       --tls-cert cert.pem \
       --tls-key key.pem \
       --tls-password-file password.txt

Этот параметр требует указания --tls-cert.

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

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

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

Методы BaseHTTPRequestHandler.send_header() и BaseHTTPRequestHandler.send_response_only() предполагают очищенные входные данные и не выполняют проверку входных данных, например, на наличие последовательностей CRLF. Непроверенные входные данные могут привести к атакам внедрения HTTP-заголовков.

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

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