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


Данный модуль определяет классы для реализации HTTP-серверов (веб-серверов).

Предупреждение

http.server не рекомендуется к промышленному использованию. Он выполняет только базовые проверки безопасности.

Один класс, 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

Содержит путь запроса.

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-сообщение, соответствующее ответу 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)

Данный класс обслуживает файлы из текущего каталога и ниже, напрямую сопоставляя структуру каталогов с HTTP-запросами.

Большая часть работы, например анализ запроса, выполняется базовым классом BaseHTTPRequestHandler. Данный класс реализует функции do_GET() и do_HEAD().

Следующие элементы определены как атрибуты уровня класса SimpleHTTPRequestHandler:

server_version

Это будет "SimpleHTTP/" + __version__, где __version__ определён на уровне модуля.

extensions_map

Суффиксы отображения словаря в типы MIME. Значение по умолчанию обозначается пустой строкой и считается application/octet-stream. Отображение используется без учета регистра, поэтому оно должно содержать только ключи в нижнем регистре.

directory

Если не указано иное, обслуживаемый каталог является текущим рабочим каталогом.

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

python -m http.server 8000

По умолчанию сервер привязывается ко всем интерфейсам. Параметр -b/--bind указывает конкретный адрес, к которому он должен привязаться. Поддерживаются адреса IPv4 и IPv6. Например, следующая команда заставляет сервер привязываться только к localhost:

python -m http.server 8000 --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, «Возможны только сценарии POST для CGI», выводится при попытке выполнить POST для URL-адреса, отличного от CGI.

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

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

python -m http.server --cgi 8000