Что есть модули Apache2 под Microsoft Windows
Сегодня хочу предложить вам статью читателя сайта ApacheDev.ru, в которой изложен его личный опыт в исследовании структуры модуля Apache 2. Статья будет интересна в первую очередь новичкам в области разработки модулей, так как в ней подробно рассмотрен процесс создания модуля Apache для ОС Windows с помощью Microsoft Visual C++ .NET. Приятного чтения.
В этой статье я попытаюсь ответить на этот вопрос, который меня начал волновать не так давно и впрочем, волнует и сейчас, т.е. содержимое этого текста не является завершенным.
Для этого я скачал и установил Apache2 (apache_2.2.4-win32-x86-no_ssl.msi).
В директории \modules содержатся исполняемые файлы модулей, файлы модулей имеют расширение *.so (насколько я знаю, в unix-подобных ОС такое расширение файлов имеют исполняемые модули с бинарным кодом, скорее всего в формате elf).
Так же были взяты на рассмотрение исходные коды примеров модулей.
В директории \modules содержатся исполняемые файлы модулей, файлы модулей имеют расширение *.so (насколько я знаю, в unix-подобных ОС такое расширение файлов имеют исполняемые модули с бинарным кодом, скорее всего в формате elf).
Так же были взяты на рассмотрение исходные коды примеров модулей.
Исследование модуля Apache2
Просматривая исходники в httpd-2.2.4\modules, я мало что понял.
Понятно, что общее для всех модулей это код:
module AP_MODULE_DECLARE_DATA logio_module;
…
module AP_MODULE_DECLARE_DATA logio_module =
{
STANDARD20_MODULE_STUFF,
NULL, /* create per-dir config */
NULL, /* merge per-dir config */
NULL, /* server config */
NULL, /* merge server config */
NULL, /* command apr_table_t */
register_hooks /* register hooks */
};
…
module AP_MODULE_DECLARE_DATA logio_module =
{
STANDARD20_MODULE_STUFF,
NULL, /* create per-dir config */
NULL, /* merge per-dir config */
NULL, /* server config */
NULL, /* merge server config */
NULL, /* command apr_table_t */
register_hooks /* register hooks */
};
Где register_hooks функция обратного вызова, которая регистрирует функции обратного вызова, вызываемые при определенных условиях, той частью, которую некоторые зовут «ядром апача»
Но как проходит взаимодействие, как построена плагинная (модульная система) Apache2?
Как компилировать модули? И многие другие вопросы остались неясны.
Как компилировать модули? И многие другие вопросы остались неясны.
Поэтому, был взят первый попавшийся модуль для Apache2 (мне попался mod_status.so) и был подвергнут препарации, посредством замечательной утилиты IDA Pro.
Выяснено, что модуль mod_status.so ни что иное как DLL, в которой присутствуют секции: релокации, данных, кода, ресурсов (где собственно и определена версия, которую видно на рисунке 1) импорта, экспорта.
Зачем нужны эти секции и что такое можно, почитать в гугле, так как это выходит за рамки содержания этого текста.
Итак, у DLL mod_status.so есть точка входа DllMain (на самом деле это не настоящая точка входа этого модуля, так как в нем используется CRT и реальная точка входа вызывает __CRT_INIT, что это такое и что она делает опять-таки можно почитать в гугле)
А чем же занимается DllMain в данном модуле?
Да собственно ничем:
Эта точка входа вызывается при событиях:
- загрузки процессом этой DLL (DLL_PROCESS_ATTACH),
- выгрузки DLL процессом (DLL_PROCESS_DETACH),
- создание процессом нового потока (DLL_THREAD_ATTACH),
- завершением потока процессом (DLL_THREAD_DETACH)
Вызов DisableThreadLibraryCalls() запрещает вызов DllMain при событиях связанных с созданием и удалением потоков процессом. Сделано это для оптимизации.
Просмотрев секцию импорта, определено что, модуль статически импортирует функции из:
- KERNEL32.DLL
- MSVCRT.DLL
- LIBAPR-1.DLL
- LIBAPRUTILS-1.DLL
- LIBHTTPD.DLL
Что это за библиотеки, я думаю, читающий понимает.
Просматривание секции экспорта дало вот что: каждый модуль экспортирует некую переменную name_module, где name – имя модуля, например status_module
А эта переменная – указатель на структуру module, определенную в файле http_config.h:
/**
* Module structures. Just about everything is dispatched through
* these, directly or indirectly (through the command and handler
* tables).
*/
typedef struct module_struct module;
struct module_struct {
/** API version, *not* module version; check that module is
* compatible with this version of the server.
*/
int version;
/** API minor version. Provides API feature milestones. Not checked
* during module init */
int minor_version;
/** Index to this modules structures in config vectors. */
int module_index;
/** The name of the module’s C file */
const char *name;
/** The handle for the DSO. Internal use only */
void *dynamic_load_handle;
/** A pointer to the next module in the list
* @defvar module_struct *next */
struct module_struct *next;
/** Magic Cookie to identify a module structure; It’s mainly
* important for the DSO facility (see also mod_so). */
unsigned long magic;
/** Function to allow MPMs to re-write command line arguments. This
* hook is only available to MPMs.
* @param The process that the server is running in.
*/
void (*rewrite_args) (process_rec *process);
/** Function to allow all modules to create per directory configuration
* structures.
* @param p The pool to use for all allocations.
* @param dir The directory currently being processed.
* @return The per-directory structure created
*/
void *(*create_dir_config) (apr_pool_t *p, char *dir);
/** Function to allow all modules to merge the per directory configuration
* structures for two directories.
* @param p The pool to use for all allocations.
* @param base_conf The directory structure created for the parent directory.
* @param new_conf The directory structure currently being processed.
* @return The new per-directory structure created
*/
void *(*merge_dir_config) (apr_pool_t *p, void *base_conf, void *new_conf);
/** Function to allow all modules to create per server configuration
* structures.
* @param p The pool to use for all allocations.
* @param s The server currently being processed.
* @return The per-server structure created
*/
void *(*create_server_config) (apr_pool_t *p, server_rec *s);
/** Function to allow all modules to merge the per server configuration
* structures for two servers.
* @param p The pool to use for all allocations.
* @param base_conf The directory structure created for the parent directory.
* @param new_conf The directory structure currently being processed.
* @return The new per-directory structure created
*/
void *(*merge_server_config) (apr_pool_t *p, void *base_conf,
void *new_conf);
/** A command_rec table that describes all of the directives this module
* defines. */
const command_rec *cmds;
/** A hook to allow modules to hook other points in the request processing.
* In this function, modules should call the ap_hook_*() functions to
* register an interest in a specific step in processing the current
* request.
* @param p the pool to use for all allocations
*/
void (*register_hooks) (apr_pool_t *p);
* Module structures. Just about everything is dispatched through
* these, directly or indirectly (through the command and handler
* tables).
*/
typedef struct module_struct module;
struct module_struct {
/** API version, *not* module version; check that module is
* compatible with this version of the server.
*/
int version;
/** API minor version. Provides API feature milestones. Not checked
* during module init */
int minor_version;
/** Index to this modules structures in config vectors. */
int module_index;
/** The name of the module’s C file */
const char *name;
/** The handle for the DSO. Internal use only */
void *dynamic_load_handle;
/** A pointer to the next module in the list
* @defvar module_struct *next */
struct module_struct *next;
/** Magic Cookie to identify a module structure; It’s mainly
* important for the DSO facility (see also mod_so). */
unsigned long magic;
/** Function to allow MPMs to re-write command line arguments. This
* hook is only available to MPMs.
* @param The process that the server is running in.
*/
void (*rewrite_args) (process_rec *process);
/** Function to allow all modules to create per directory configuration
* structures.
* @param p The pool to use for all allocations.
* @param dir The directory currently being processed.
* @return The per-directory structure created
*/
void *(*create_dir_config) (apr_pool_t *p, char *dir);
/** Function to allow all modules to merge the per directory configuration
* structures for two directories.
* @param p The pool to use for all allocations.
* @param base_conf The directory structure created for the parent directory.
* @param new_conf The directory structure currently being processed.
* @return The new per-directory structure created
*/
void *(*merge_dir_config) (apr_pool_t *p, void *base_conf, void *new_conf);
/** Function to allow all modules to create per server configuration
* structures.
* @param p The pool to use for all allocations.
* @param s The server currently being processed.
* @return The per-server structure created
*/
void *(*create_server_config) (apr_pool_t *p, server_rec *s);
/** Function to allow all modules to merge the per server configuration
* structures for two servers.
* @param p The pool to use for all allocations.
* @param base_conf The directory structure created for the parent directory.
* @param new_conf The directory structure currently being processed.
* @return The new per-directory structure created
*/
void *(*merge_server_config) (apr_pool_t *p, void *base_conf,
void *new_conf);
/** A command_rec table that describes all of the directives this module
* defines. */
const command_rec *cmds;
/** A hook to allow modules to hook other points in the request processing.
* In this function, modules should call the ap_hook_*() functions to
* register an interest in a specific step in processing the current
* request.
* @param p the pool to use for all allocations
*/
void (*register_hooks) (apr_pool_t *p);
Теперь примерно ясно, как работают модули:
Apache из файла httpd.conf, выбирает записи типа LoadModule actions_module modules/mod_actions.so, где modules/mod_actions.so – путь к модулю, а actions_module – имя экспортируемой модулем mod_actions.so переменной, в которой содержится структура module, ну а далее думаю все понятно.
Подведем итоги:
Модуль для Apache2 под Microsoft Windows – это DLL, экспортирующая указатель на переменную типа module, корректно заполненную, модуль может использовать функции из DLL:
- LIBAPR-1.DLL
- LIBAPRUTILS-1.DLL
- LIBHTTPD.DLL
которые импортируются им статически.
Создание модуля Apache2 с помощью Microsoft Visual C++ .NET
Ну теперь пример модуля, который можно собрать с помощью Microsoft Visual C++ .NET:
1.Создаем новый проект:
Какой тип приложения мы выберем, не имеет значения, потому что это DLL. Но выбирать что-то надо, поэтому выбираем Console. Далее указываем:
2. Далее добавляем новый файл, где будет размещаться исходный код:
Далее размещаем наш исходный код в нем.
3. Настраиваем созданный проект:
Указываем включаемые файлы:
Указать, где находятся DLL, используемые этим модулем:
Так же можно указать расширение исполняемого файла:
Если вы создали cpp файл, то следует указать компилятору, что его нужно компилировать как c-файл:
И собираем модуль
В архиве содержится пример такого модуля, для компиляции которого вам необходимо указать путь к включаемым файлам и библиотекам статической линковки.
Автор: unknow [regiomontanus(at)mail(dot)ru]
Источник: ApacheDev.ru
Источник: ApacheDev.ru
Комментарий от LesHka — Май 5, 2007 @ 2:19 pm
Что делать?
Комментарий от Филипп — Июль 11, 2007 @ 6:31 am
возможно Вы или автор забыли убрать breakpoint:)
Комментарий от unknow — Июль 14, 2007 @ 10:52 pm
Комментарий от Филипп — Июль 19, 2007 @ 5:24 am
таки адрес прендлежэащий ДЛЛ
Комментарий от unknow — Август 5, 2007 @ 8:18 pm
Комментарий от Ferh — Июнь 26, 2008 @ 4:39 pm
Комментарий от Зима — Июль 26, 2008 @ 2:08 pm
Блин не знаю что делать.
Может это винда глючнаяч?
Комментарий от Sam — Август 26, 2008 @ 10:14 pm
У меня когда-то была похожая проблема из-за глюка винды..
Комментарий от Alex — Август 27, 2008 @ 12:52 am
_____________
/go.php?url=/go.php?url=/go.php?url=http://torip.ru/
Комментарий от андрюха — Август 29, 2008 @ 2:00 pm
Комментарий от yahud — Сентябрь 3, 2008 @ 5:58 pm
_____________________________
/go.php?url=/go.php?url=/go.php?url=http://sporeco.ru/
Комментарий от чувак — Сентябрь 10, 2008 @ 8:46 pm
___________________________
/go.php?url=/go.php?url=/go.php?url=http://www.stroymaterials.com/
Комментарий от чувак — Сентябрь 12, 2008 @ 9:10 pm
___________________________
/go.php?url=/go.php?url=/go.php?url=http://www.fastmed.ru/
Комментарий от чувак — Сентябрь 12, 2008 @ 9:13 pm
_________________________
/go.php?url=/go.php?url=http://omnigo.ru/
Комментарий от иванов@!!! — Сентябрь 18, 2008 @ 4:44 pm
_____________________
/go.php?url=/go.php?url=http://wowing.ru/
Комментарий от вадик — Сентябрь 18, 2008 @ 4:47 pm
Комментарий от Голосочек — Сентябрь 20, 2008 @ 1:35 am
Комментарий от Kolchin — Октябрь 10, 2008 @ 11:47 pm
Комментарий от Жанна — Октябрь 16, 2008 @ 11:03 pm
Комментарий от Berman — Октябрь 17, 2008 @ 2:24 pm
Комментарий от Анна — Октябрь 28, 2008 @ 1:25 pm
Комментарий от Мартин — Ноябрь 8, 2008 @ 12:15 pm
Комментарий от Тамара — Ноябрь 8, 2008 @ 4:42 pm
Комментарий от Валерия — Ноябрь 8, 2008 @ 4:50 pm
Судя по не которым комментам, даже у более опытных траблы с этим модулем.
Комментарий от Потолков — Ноябрь 15, 2008 @ 3:03 pm
Комментарий от Hitro — Декабрь 3, 2008 @ 12:42 am
Комментарий от Василь Иваныч — Декабрь 4, 2008 @ 2:15 am
Комментарий от Балчик — Декабрь 4, 2008 @ 7:49 pm
Комментарий от Справочник — Декабрь 5, 2008 @ 10:58 pm
Комментарий от Настасья — Декабрь 7, 2008 @ 8:18 pm
Комментарий от Пал Палыч — Декабрь 18, 2008 @ 11:30 pm
Комментарий от ПОТОЛКОВ — Декабрь 24, 2008 @ 1:58 pm
Комментарий от Заработок в Интернете — Декабрь 27, 2008 @ 10:02 am
Комментарий от Lass — Январь 9, 2009 @ 6:09 pm
Комментарий от Антон М. — Январь 23, 2009 @ 5:30 pm
Комментарий от givi — Январь 26, 2009 @ 2:47 pm
\include\ap_config.h(20) : fatal error C1083: Не удается открыть файл include: apr.h: No such file or directory
исходники apache скачивал под win32 вроде кнонибуть знает вчем проблема
Комментарий от fantasma — Январь 29, 2009 @ 5:15 pm
Комментарий от pizzdozz — Февраль 3, 2009 @ 3:12 am
Комментарий от ivan76 — Февраль 3, 2009 @ 3:13 am
Комментарий от Вероника — Февраль 12, 2009 @ 10:22 am
Комментарий от Звезда — Февраль 12, 2009 @ 10:25 am
Комментарий от Май — Февраль 12, 2009 @ 1:26 pm
Комментарий от deggit — Март 2, 2009 @ 10:03 pm
Комментарий от Юлия — Март 3, 2009 @ 10:03 am
Комментарий от Алёна — Март 5, 2009 @ 8:47 pm
Комментарий от Антон — Март 7, 2009 @ 8:09 pm
Комментарий от Олег — Март 9, 2009 @ 9:00 am
Комментарий от Даниил — Март 17, 2009 @ 9:55 am
Комментарий от Аркадий — Март 20, 2009 @ 2:21 pm
Комментарий от Roma — Март 26, 2009 @ 9:40 am
Комментарий от экономика недвижимости — Апрель 1, 2009 @ 2:20 am
Комментарий от Alsu — Апрель 2, 2009 @ 1:32 pm
Комментарий от Тектоник — Апрель 6, 2009 @ 8:31 am
Комментарий от Kostya — Апрель 7, 2009 @ 8:36 am
Комментарий от Andrey — Апрель 8, 2009 @ 8:45 am
Комментарий от Serg — Апрель 9, 2009 @ 2:45 pm
Комментарий от Serg — Апрель 10, 2009 @ 12:04 am
Комментарий от Инга — Апрель 13, 2009 @ 12:08 pm
Комментарий от Мартин — Апрель 13, 2009 @ 12:10 pm
Комментарий от тут менеджмент читают — Апрель 15, 2009 @ 11:31 am
Комментарий от Ольга — Апрель 16, 2009 @ 10:54 am
Комментарий от Сергей — Апрель 16, 2009 @ 8:13 pm
Комментарий от Виталий Игоревич — Апрель 17, 2009 @ 6:46 am
Комментарий от инвестиции тут — Апрель 17, 2009 @ 12:12 pm
Комментарий от Лариса — Апрель 18, 2009 @ 5:47 am
а что значит сторонних разработчиков? Вроде сафари браузер нормальный не сторонний
Комментарий от авто — Апрель 18, 2009 @ 6:12 pm
Комментарий от Венеция — Апрель 20, 2009 @ 2:38 pm