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