http.server
— HTTP-серверы¶
Источник: Lib/http/server.py
Этот модуль определяет классы для реализации HTTP-серверов.
Предупреждение
http.server
не рекомендуется для использования в производстве. Он реализует только basic security checks.
Availability: не 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
обработчика.
- class http.server.ThreadingHTTPServer(server_address, RequestHandlerClass)¶
Этот класс идентичен HTTPServer, но использует потоки для обработки запросов с помощью
ThreadingMixIn
. Это удобно для работы с веб-браузерами, предварительно открывающими сокеты, на которыхHTTPServer
будет ждать бесконечно долго.Added in version 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 присутствует компонент query, то
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¶
Указывает версию программного обеспечения сервера. Вы можете захотеть переопределить это значение. Формат - несколько строк, разделенных пробелами, где каждая строка имеет вид 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
.Added in version 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-сообщение, соответствующее коду ответа.Added in version 3.2.
- end_headers()¶
Добавляет пустую строку (обозначающую конец HTTP-заголовков в ответе) в буфер заголовков и вызывает
flush_headers()
.Изменено в версии 3.2: Буферизованные заголовки записываются в выходной поток.
- flush_headers()¶
Наконец, отправьте заголовки в выходной поток и промойте внутренний буфер заголовков.
Added in version 3.3.
- log_request(code='-', size='-')¶
Регистрирует принятый (успешный) запрос. Параметр code должен указывать числовой HTTP-код, связанный с ответом. Если размер ответа доступен, то он должен быть передан в качестве параметра size.
- log_error(...)¶
Выводит сообщение об ошибке, когда запрос не может быть выполнен. По умолчанию он передает сообщение в
log_message()
, поэтому принимает те же аргументы (формат и дополнительные значения).
- 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 принимает значение path-like object.
Большую часть работы, например разбор запроса, выполняет базовый класс
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
.
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, «Can only POST to CGI scripts», выдается при попытке POST к не CGI url.
Обратите внимание, что CGI-скрипты будут запускаться с UID пользователя nobody в целях безопасности. Проблемы с CGI-скриптом будут переведены в ошибку 403.
Утратил актуальность с версии 3.13, будет удален в версии 3.15:
CGIHTTPRequestHandler
будет удален в версии 3.15. CGI уже более десяти лет не считается хорошим способом выполнения задач. Этот код уже давно не поддерживается и практически не используется. Его сохранение может привести к дальнейшему security considerations.
CGIHTTPRequestHandler
можно включить в командной строке, передав параметр --cgi
:
python -m http.server --cgi
Утратил актуальность с версии 3.13, будет удален в версии 3.15: Поддержка http.server
командной строки --cgi
удаляется, потому что удаляется CGIHTTPRequestHandler
.
Предупреждение
CGIHTTPRequestHandler
и опция командной строки --cgi
не предназначены для использования недоверенными клиентами и могут быть уязвимы для эксплуатации. Всегда используйте их в безопасной среде.
Соображения безопасности¶
SimpleHTTPRequestHandler
при обработке запросов будет следовать символическим ссылкам, что позволяет обслуживать файлы за пределами указанного каталога.
В ранних версиях Python управляющие символы не удалялись из сообщений журнала, выводимых на stderr из python -m http.server
или стандартной BaseHTTPRequestHandler
.log_message
. Это могло позволить удаленным клиентам, подключающимся к вашему серверу, отправлять на ваш терминал нежелательные управляющие коды.
Изменено в версии 3.12: Управляющие символы затираются в журналах stderr.