http.server — HTTP-серверы¶
Исходный код: Lib/http/server.py.
Этот модуль определяет классы для реализации HTTP-серверов.
Предупреждение
http.server не рекомендуется для производства. Он реализует только basic security checks.
Один класс, 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 присутствует компонент 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.Добавлено в версии 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-сообщение, соответствующее коду ответа.
Добавлено в версии 3.2.
-
end_headers()¶ Добавляет пустую строку (указывающую на конец заголовков HTTP в ответе) в буфер заголовков и вызывает
flush_headers().Изменено в версии 3.2: Буферизованные заголовки записываются в выходной поток.
-
flush_headers()¶ Наконец, отправьте заголовки в выходной поток и промойте внутренний буфер заголовков.
Добавлено в версии 3.3.
-
log_request(code='-', size='-')¶ Регистрирует принятый (успешный) запрос. code должен указывать числовой HTTP-код, связанный с ответом. Если доступен размер ответа, то его следует передать в качестве параметра size.
-
log_error(...)¶ Выдает сообщение об ошибке, когда запрос не может быть выполнен. По умолчанию он передает сообщение в
log_message(), поэтому принимает те же аргументы (формат и дополнительные значения).
-
log_message(format, ...)¶ Записывает произвольное сообщение в журнал
sys.stderr. Это обычно переопределяется для создания пользовательских механизмов регистрации ошибок. Аргумент формат представляет собой стандартную строку формата в стиле 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: Параметр директория.
Изменено в версии 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()в модулеhttp.server.Изменено в версии 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: Аргумент --bind улучшен для поддержки IPv6
По умолчанию сервер использует текущий каталог. Опция -d/--directory указывает каталог, в который он должен обслуживать файлы. Например, следующая команда использует определенный каталог:
python -m http.server --directory /tmp/
Добавлено в версии 3.7: Был введен аргумент --directory.
-
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.
-
CGIHTTPRequestHandler можно включить в командной строке, передав опцию --cgi:
python -m http.server --cgi
Соображения безопасности¶
SimpleHTTPRequestHandler будет следовать символическим ссылкам при обработке запросов, что позволяет обслуживать файлы вне указанного каталога.