Модули Apache 2.0


В предыдущих статьях я рассказал о некоторых новых возможностях Apache 2.0 и о том, как Вы можете реализовать их в своих серверах. В этот раз я расскажу об одной мало обсуждаемой особенности Apache 2.0.
Одним из самых больших достоинств сервера Apache над другими HTTP серверами является то, с какой легкостью для него пишутся мощные модули. Apache, начиная с версии 1.0, использует модули для реализации всех своих функций, кроме отправки статических документов. Так как функциональность Apache полностью реализована в модулях, следовательно, модули имеют доступ к любому этапу обработки запроса. Однако, несмотря на все достоинства модулей, у них есть один большой недостаток.

Модули существуют как отдельные сущности. Так, например, если два модуля делают одинаковую операцию, то каждому из них нужно добавить соответствующий код. Это делает поддержку модулей довольно сложной, так как изменения нужно делать в каждом таком модуле. Вероятно, лучший пример такой ситуации - это модули mod_include и mod_cgi. Модуль mod_include выполняет обработку SSI, а модуль mod_cgi выполняет CGI-скрипты. Тем не менее, модулю mod_include также требуется обработка CGI-скриптов всякий раз, когда он сталкивается с кодом следующего вида:

<-- #exec cgi=/cgi-bin/printenv -->
В Apache 1.3 оба модуля поступали следующим образом: создавали CGI-процесс и в нем выполняли скрипт. На некоторых платформах такое поведение было сложно реализовать, особенно на тех платформах, которые не распознавали в строке #! начало скрипта, и не вызывали для него интерпретатор.
В Apache 2.0 мы можем решить эту проблему, позволяя mod_include вызывать модуль mod_cgi для выполнения CGI-скриптов. Такой подход также имеет свои недостатки. Основной недостаток заключается в том, что mod_include не может использовать результат CGI-скриптов, если модуль mod_cgi не подключен к серверу.
Разработчики Apache решили, что данная уступка будет обоснованная, так как исключение модуля mod_cgi администратором означает, что он запрещает выполнение CGI-скриптов. И мы не нашли обоснованной причины, позволяющей выполнять CGI-скрипты внутри SSI файлов, если они запрещены администратором. Эта возможность mod_include позволила авторам других модулей использовать измененные SSI-тэги, без необходимости изменять код модуля mod_include.
Для демонстрации того, как легко расширить возможности mod_include,давайте посмотрим, как это делает модуль mod_cgi. Первым шагом будет получение двух функций модуля mod_include. Это делается с помощью опциональных функций, новой возможности Apache 2.0, позволяющей любому модулю регистрировать свои функции в ядре как опциональные. Когда другой модуль хочет использовать эти функции, он обращается к ядру сервера, спрашивая, зарегистрировал ли модуль эти функции. Ядро сервера использует имя функции как ключ для поиска указателя на зарегистрированные функции.
Вот три важные функции для работы с mod_include: ap_register_include_handler, ap_ssi_get_tag_and_value, и ap_ssi_parse_string. Функция ap_register_include_handler используется для определения тэга, который будет обрабатываться этим модулем. Функция ap_ssi_get_tag_and_value получает атрибут и его значение из обрабатываемого SSI тэга. Эта функция циклически вызывается до тех пор, пока функция не вернет null атрибут. Что означает, что все атрибуты обработаны. Последняя функция - это ap_ssi_parse_string. Эта функция используется для парсинга тегов и преобразования их в строки.
После того, как указатели на эти функции получены, Ваш модуль должен зарегистрировать свой тег в модуле mod_include. Это можно сделать, только если все предыдущие функции были выполнены с успешным результатом. Для регистрации тега, вызовите регистрирующую функцию. Первый аргумент функции - это строка, которую mod_include должен обнаружить при обработке SSI. Второй аргумент - это функция, которая вызывается при нахождении данной строки. Следующая функция показывает, как это сделано в mod_cgi:
static void cgi_post_config(apr_pool_t *p, apr_pool_t *plog,
apr_pool_t *ptemp, server_rec *s)
{
cgi_pfn_reg_with_ssi = APR_RETRIEVE_OPTIONAL_FN(ap_register_include_handler);
cgi_pfn_gtv = APR_RETRIEVE_OPTIONAL_FN(ap_ssi_get_tag_and_value);
cgi_pfn_ps = APR_RETRIEVE_OPTIONAL_FN(ap_ssi_parse_string);
if ((cgi_pfn_reg_with_ssi) && (cgi_pfn_gtv) && (cgi_pfn_ps)){
cgi_pfn_reg_with_ssi(“exec”, handle_exec);
}
}
Рассмотрим еще одну важную деталь. Если Вы посмотрите на имя предыдущей функции, то обратите внимание, что она вызывается в обработчике post_config. Проблема в том, что модуль mod_include использует хэш-таблицу для хранения пар строка-функция, и создает эту таблицу в своем обработчике post_config. Если функция post_config модуля mod_cgi вызовется первой, тогда сервер при загрузке выдаст ошибку. Это проблема может быть легко решена, используя новый механизм хуков (hook mechanism) в Apache 2.0. Ниже приведен пример этого решения: функция register_hooks модуля mod_cgi. Когда mod_cgi регистрирует свой обработчик post_config, он определяет, что mod_include должен загружаться перед ним.
static void register_hooks(apr_pool_t *p)
{
static const char * const aszPre[] = {“mod_include.c”, NULL};
ap_hook_handler(cgi_handler, NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_post_config(cgi_post_config, aszPre, NULL, APR_HOOK_REALLY_FIRST);
}
Конечно, это только один пример, когда расширение функциональности модулей может быть полезным. Другой пример - это модуль mod_log_config. В mod_log_config мы можем позволить модулям расширять типы данных, доступных для записи в лог. Чем больше людей будут создавать модули для Apache 2.0, тем больше возможностей будет по расширению этих модулей. А команда разработчиков продолжит расширять возможности модулей, которые позволят взаимодействовать им при решении проблем.
Apache 2.0 имеет много возможностей, которые не были доступны в Apache 1.3. Эти возможности помогут сохранить Apache лидирующее место среди веб-серверов в Internet.
Автор: Райн Блум (Ryan Bloom)
Перевод: Сипягин Максим
Оригинал документа (en)

These icons link to social bookmarking sites where readers can share and discover new web pages.
  • News2.ru
  • NewsLand.ru
  • del.icio.us
  • BobrDobr.ru
  • Ma.gnolia
  • Digg
  • Reddit
  • Technorati
  • Slashdot
  • Netscape
  • DZone
  • ThisNext
  • Furl
  • YahooMyWeb
Опубликовано в: Разработка модулей Февраль 4, 2006

6 Комментариев »

  1. СУПЕР!! ЧУВАК большое тебе СПАСИБА!!! Оч давно искал єту инфу!РЕСПЕКТ!)))
    ______________
    iclub-china.com

    Комментарий от skif1993 — Август 28, 2008 @ 4:04 pm

  2. bla-bla-bla

    Комментарий от Вадим — Октябрь 18, 2008 @ 5:47 pm

  3. +!

    Комментарий от Евгений — Октябрь 18, 2008 @ 5:47 pm

  4. +2

    Комментарий от Зоя — Октябрь 18, 2008 @ 5:47 pm

  5. http://danetnavern0.narod.ru
    UT2004 - карты, моды, мутаторы, режимы игры для UT2004, Unreal Tournament 2004

    Комментарий от ЛУЧШИЙ САЙТ В МИРЕ ПРО UT — Октябрь 18, 2008 @ 5:49 pm

  6. Можно иначе:
    static const char * const aszPre[] = {“mod_include.c”, NULL};
    ap_hook_handler(cgi_handler, NULL, NULL, APR_HOOK_MIDDLE);

    Комментарий от Антон — Апрель 8, 2009 @ 7:32 pm

Оставить комментарий

You must be logged in to post a comment.

Работает на WordPress