Раздел 11. Документация для разработчиков RU EN Пункт 218. Хук-функции Apache 2.x Этот документ все еще находится в разработке и может быть частично устаревшим. В общем, функция ловушки — это функция, которую HTTP-сервер Apache будет вызывать в какой-то момент во время обработки запроса. Модули могут предоставлять функции, которые вызываются, и указывать, когда они вызываются по сравнению с другими модулями. Основные крючкиОсновные модули httpd предлагают заранее определенный список ловушек, используемых на стандартной фазе обработки запросов. Создание нового хука откроет функцию, которая его реализует (см. разделы ниже), но важно понимать, что вы не будете расширять основные хуки httpd. Их присутствие и порядок в обработке запросов на самом деле являются следствием того, как они вызываются Прежде чем продолжить, настоятельно рекомендуется прочитать руководство по разработке модулей и обработке запросов. Создание функции ловушкиЧтобы создать новый хук, необходимо сделать четыре вещи: Объявите функцию ловушкиИспользуйте AP_DECLARE_HOOK(int, do_something, (request_rec *r, int n)) Это должно быть в заголовке, в который будут включены модули, если они захотят использовать хук. Создайте структуру крючкаКаждый исходный файл, который экспортирует ловушку, имеет частную структуру, которая используется для записи функций модуля, использующих ловушку. Это объявляется следующим образом: APR_HOOK_STRUCT( APR_HOOK_LINK(сделать что-нибудь) ... ) Реализовать вызывающий хукИсходный файл, который экспортирует хук, должен реализовать функцию, которая вызовет хук. В настоящее время есть три возможных способа сделать это. Во всех случаях вызывается вызывающая функция . Пустые крючкиЕсли возвращаемое значение хука равно AP_IMPLEMENT_HOOK_VOID(do_something, (request_rec *r, int n), (r, n)) Второй и третий аргументы — это объявление фиктивного аргумента и фиктивные аргументы, поскольку они будут использоваться при вызове хука. Другими словами, этот макрос расширяется примерно так: недействительным ap_run_do_something (request_rec * r, int n) { ... сделать_что-то (г, п); } Хуки, возвращающие значениеЕсли хук возвращает значение, то его можно запустить до первого хука, который делает что-то интересное, например: AP_IMPLEMENT_HOOK_RUN_FIRST(int, do_something, (request_rec *r, int n), (r, n), ОТКЛОНЕН) Первый хук, который не возвращает значение, В качестве альтернативы все хуки могут выполняться до тех пор, пока не произойдет ошибка. Это сводится к разрешению двух возвращаемых значений, одно из которых означает «я что-то сделал, и все было в порядке», а другое означает «я ничего не сделал». Первая функция, которая возвращает значение, отличное от одного из этих двух, останавливает цикл, и ее возвращаемое значение является возвращаемым значением. Объявите их так: AP_IMPLEMENT_HOOK_RUN_ALL(int, do_something, (request_rec *r, int n), (r, n), OK, ОТКЛОНЕН) Опять же, Позвоните вызывающим абонентамВ соответствующие моменты в коде вызовите вызывающий хук, например: инт н, рет; запрос_рек *r; ret=ap_run_do_something(r, n); Зацепить крючокМодуль, который хочет вызвать хук, должен сделать две вещи. Реализовать функцию ловушкиВключите соответствующий заголовок и определите статическую функцию правильного типа: статический интервал my_something_doer (request_rec * r, int n) { ... вернуть ОК; } Добавить функцию регистрации хукаВо время инициализации сервер будет вызывать функцию регистрации хука каждого модуля, которая включена в структуру модуля: статическая пустота my_register_hooks() { ap_hook_do_something(my_something_doer, NULL, NULL, APR_HOOK_MIDDLE); } режим MODULE_VAR_EXPORT my_module = { ... my_register_hooks /* регистрация хуков */ }; Управление порядком вызова хукаВ приведенном выше примере мы не использовали три аргумента в функции регистрации хука, которые управляют порядком вызова всех функций, зарегистрированных в хуке. Для этого есть два механизма. Первый, довольно грубый, метод позволяет нам примерно указать, где запускается хук по отношению к другим модулям. Последний аргумент контролирует это. Возможны три значения: Все модули, использующие какое-либо конкретное значение, могут запускаться в любом порядке относительно друг друга, но, конечно, все модули, использующие,
Обратите внимание, что есть еще два значения
Другой метод позволяет более точно контролировать. Когда модуль знает, что он должен быть запущен до (или после) некоторых других модулей, он может указать их по имени. Второй (третий) аргумент — это завершающийся NULL массив строк, состоящий из имен модулей, которые должны быть запущены до (после) текущего модуля. Например, предположим, что мы хотим, чтобы «mod_xyz.c» и «mod_abc.c» запускались раньше, чем мы, тогда мы бы подключились следующим образом: статическая пустота register_hooks() { static const char * const aszPre[] = { "mod_xyz.c", "mod_abc.c", NULL }; ap_hook_do_something(my_something_doer, aszPre, NULL, APR_HOOK_MIDDLE); } Обратите внимание, что сортировка, используемая для достижения этого, является стабильной, поэтому порядок, установленный по, сохраняется, насколько это возможно. |