Содержание страницы
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_headerend_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()
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- скриптов. При попытке выполнить POST на не-CGI URL выводится ошибка 501: «Can only POST to CGI scripts».
Обратите внимание: из соображений безопасности CGI-скрипты будут запускаться с UID пользователя nobody. Проблемы с CGI-скриптом приведут к ошибке 403.
CGIHTTPRequestHandler можно включить в командной строке, передав
параметр --cgi:
python -m http.server --cgi
Предупреждение
CGIHTTPRequestHandler и параметр командной строки --cgi не предназначены для использования ненадёжными клиентами и могут быть уязвимы для эксплуатации. Всегда используйте в защищённой среде.
Вопросы безопасности¶Security Considerations
SimpleHTTPRequestHandler будет следовать по символическим ссылкам при обработке запросов, что позволяет отдавать файлы за пределами указанного каталога.
В более ранних версиях Python не удалялись управляющие символы из
сообщений журнала, выводимых в stderr из python -m http.server или реализации
по умолчанию BaseHTTPRequestHandler .log_message.
Это могло позволить удалённым клиентам, подключающимся к вашему
серверу, отправлять вредоносные управляющие коды на ваш терминал.
Изменено в версии 3.11.1: Управляющие символы удаляются из журналов stderr.