Spec-Zone.ru › Python 3.14

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

Исходный код: 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, однако следует учитывать, что это может привести к раскрытию паролей, жестко заданных в коде, в открытом виде.

См. также

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

Если задан, аргумент 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

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

request_version

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

headers

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

rfile

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

wfile

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

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

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

server_version

Задает версию программного обеспечения сервера. При необходимости этот атрибут можно переопределить. Формат — несколько строк, разделенных пробелами; каждая строка имеет вид name[/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 на URL, не связанный с CGI, выводится ошибка 501 «Метод POST разрешён только для CGI-скриптов».

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

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

Интерфейс командной строки

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.11.

--cgi

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

python -m http.server --cgi

Устарело начиная с версии 3.13, будет удалено в версии 3.15: Поддержка --cgi в командной строке http.server удаляется, поскольку удаляется 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.

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

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

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

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

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

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

Spec-Zone.ru

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