Пример простого web-сервера на основе perl и POE. Модуль POE::Component::Server::HTTP

Ниже приводится код простого web-сервера, на основе Perl и POE.

Web-сервер получает запрос от клиента и отправляет в ответ текущую дату и время (в общем, он может отправлять что угодно).

Для организации работы сервера используется POE-компонента - POE::Component::Server::HTTP. POE::Component::Server::HTTP - это небольшой фреймворк для создания HTTP-серверов на основе POE. Разрабатывался с опорой на принципы работы Apache и mod_perl.

Указанный в примере сервер будет слушать порт 32080. Можно обратиться к нему из браузера, используя адрес http://localhost:32080/ . При обращении к корневому каталогу сервера, для генерации контента будет вызываться подпрограмма web_handler() .

В качестве входных параметров обработчик web_handler() получит ссылки на объекты HTTP::Request и HTTP::Response. Первый параметр - объект HTTP::Request, который содержит данные о поступившем запросе. Второй - пустой объект HTTP::Response, который наполняется данными для последующей отправки ответа клиенту.

 

Этапы обработки запроса в POE::Component::Server::HTTP

POE::Component::Server::HTTP - очень простой фреймворк, скрывающий внутри достаточно сложную логику работы сервера.

Пользователям этого модуля, при создании своего сервера остается только создать объект POE::Component::Server::HTTP и добавить подпрограммы для обработки поступившего запроса.

Каждый запрос обрабатывается в несколько этапов. Каждый этап обрабатывается соответствующим обработчиком: TransHandler, PreHandler, ContentHandler, ErrorHandler, PostHandler, StreamHandler. Обработчики вызываются в перечисленном порядке.

Все обработчики, кроме ContentHandler, являются не обязательными (Точнее, каждый уже имеет соответствующую дефолтную программу, которая выполняет возможный минимум работы). Каждый обработчик может быть переопределен.

Обработчики получают в качестве аргументов ссылки на объекты HTTP::Request и HTTP::Response.

Каждый обработчик должен по завершении работы вернуть одно из значений на выбор:

  • RC_OK - Все хорошо, продолжаем обработку.
  • RC_DENY - Возвращает клиенту отказ в обслуживании. Есть нюансы при работе с различными
    хендлерами. См. документацию.
  • RC_WAIT - Это специальный обработчик, который приостанавливает выполнение всех других обработчиков. Для продолжения обработки надо вызвать $response->continue() . Может оказаться полезным во время работы с тяжелыми и длительными запросами.

TransHandler

Обработчик выполняется до того, как будет разобран URI. Это дает возможность внести в URI изменения. Выполнение TransHandler можно прервать и перейти к следующему обработчику, вызвав RC_DENY.

PreHandler

Обработчик вызывается после TransHandler, но до ContentHandler.

ContentHandler

Данный обработчик должен определить содержимое ответа клиенту.

Можно для разных URL задать разных обработчиков.

Если не задан обработчик для вызываемого пользователем URL, то система просто найдет ближайший подходящий обработчик и будет использовать его для подготовки ответа пользователю.

Например, если в программе (см. пример выше) задан обработчик только для корневого каталога, то можно ввести в браузере http://localhost:32080/pages/12.html, программа все равно будет использовать обработчик web_handler(), и вернет в ответ текущую дату.

Обработчик автоматически проставит Content-Length и Date, если они не заданы специально. При необходимости, из этого обработчика можно проставлять cookies.

ErrorHandler

Обработчик вызывается, если на сокете возникла ошибка. Например, клиент разорвал соединение. Если возникает такая ситуация, после ErrorHandler может быть вызван PostHanlder, но TransHandler и PreHandler вызываться не будут.

PostHandler

Этот обработчик вызывается, после того, как ответ был отправлен клиенту.

StreamHandler

Специальный обработчик. См. документацию.

Полезные ссылки

POE: Cookbook - Web Server With Components

search.cpan.org: POE::Component::Server::HTTP