В архитектуре Apache можно выделить следующие базовые объекты:
1. Сервер.
2. Коннект.
3. Запрос.
4. Процесс.
Каждый из этих объектов представлен соответствующей структурой в заголовочном файле httpd.h.
Помимо этих 4-х основных объектов в архитектуре Apache нужно отметить еще два объекта.
Первый объект — это пулы. Управлением ресурсов в Apache занимаются пулы — APR pools (apr_pool_t). Любой ресурс, выделяемый динамически, если он привязан к пулу, будет удален автоматически после использования. Пул привязывает ресурсы к жизненному циклу основных объектов, о которых мы сказали выше. Второй объект — это конфигурационный массив ap_conf_vector_t, причем каждому модулю в нем отводится свое место.
Массив хранит как глобальные конфигурационные данные, так и локальные.
В переводе на язык си основные четыре объекта представлены структурами:
request_rec server_rec conn_rec process_recБолее всего используются первые две. Каждый раз, когда на сервер приходит клиентский запрос, создается объект структуры request_rec, который передается в качестве параметра в любой обработчик, занятый обработкой запроса. Структура содержит не только стандартную информацию о HTTP-запросе, но и внутреннюю служебную информацию: пул запросов, массив глобальных и массив локальных конфигурационных записей, таблицы HTTP-заголовков, таблицу переменных окружения, указатели на сервер, коннект, фильтры, URL и его трансляцию, и т. д. Определение находится в httpd.h:
struct request_rec { apr_pool_t *pool; conn_rec *connection; server_rec *server; request_rec *next; request_rec *prev; request_rec *main;...};Структура server_rec представляет веб-сервер. Для каждого виртуального хоста имеется свой собственный экземпляр server_rec. Этот объект живет на протяжении всей жизни сервера. Ресурсы он берет из пула процессов. После структуры request_rec это вторая наиболее важная структура в Apache:
|
Структура conn_rec представляет TCP-коннект, создается при открытии коннекта и удаляется при его закрытии. Один коннект может породить несколько запросов. Запрос — это производный объект от коннекта:
struct conn_rec { apr_pool_t *pool; server_rec *base_server; void *vhost_lookup_data; apr_sockaddr_t *local_addr; apr_sockaddr_t *remote_addr;...};Структура process_rec имеет более непосредственное отношение к операционной системе, нежели к архитектуре самого сервера. Пул процессов можно получить через нее посредством
server_rec -> process_rec -> pool.Другие структуры Apache разнесены по разным хидерам, из которых можно выделить следующие группы:
1. ap_ — хидеры с таким префиксом генерируют низко-уровневое API и напрямую, как правило, не используются.
2. http_ — в этих хидерах находится API, представляющее наибольший интерес для разработчиков.
3. util_ — эти хидеры аналогичны первой группе.
4. mod_ — здесь находятся определения для модулей.
5. apr_ — APR API.
Для разработчиков наибольший интерес представляют следующие заголовки:
http_config.h http_connection.h http_core.h http_log.h http_main.h http_protocol.h http_request.h http_vhost.h httpd.h util_filter.h ap_provider.h mod_dbd.h util_ldap.h util_script.hВ начало
Обработка запросов
Большинство модулей Apache имеют непосредственное отношение к обработке клиентских запросов, участвуя в этом процессе в определенной последовательности. Такой подход позволяет каждому модулю сфокусироваться на узком аспекте обработки.
Веб-сервер возвращает клиенту ответ, формируемый генератором контента. Любой модуль может зарегистрировать свой генератор с помощью директив SetHandler или AddHandler в файле httpd.conf. Если такой регистрации нет, то генератор по умолчанию просто возвращает файл, получаемый напрямую из запроса. Модули, которые реализуют свои собственные генераторы, называются контент-генераторами. Такой генератор в принципе может управлять всеми функциями. Например, CGI программа, получившая запрос, генерирует ответ, полностью контролируя этот процесс.
|
Apache разбивает запрос на несколько фаз, например, проверяет авторизацию пользователя. Непосредственно самой генерации предшествуют несколько стадий, например:
1. URL проверяется на предмет наличия для него предопределенного конфигурационного генератора контента.
2. URL транслируется на файловую систему, результатом чего может быть статичный файл, CGI-скрипт.
3. Может быть включен модуль mod_negotiation для определения версии ресурса.
4. Может происходить проверка доступа.
5. Модули mod_alias или mod_rewrite могут изменить текущий URL.
Запрос может быть обработан нестандартным образом в силу следующих причин:
1. Может быть сгенерирован дополнительный вложенный запрос или выдан документ с ошибкой.
2. Могут быть добавлены дополнительные фазы обработки запроса.
3. Хук (hook) quick_handler может быть запущен модулем кеширования.
Для изменения процесса обработки запроса существует механизм хуков. К ним в первую очередь относятся:
1. post_read_request — этот хук может быть запущен на ранней стадии обработки запроса.
2. translate_name — трансляция URL.
3. map_to_storage — читает опции конфигурации.
|
4. header_parser — запускается в начале обработки для чтения заголовков.
5. access_checker — этот хук может заменить стандартную логику проверки прав доступа.
6. check_user_id — назначает аутентификацию.
7. type_checker — назначает обработчик контента.
8. fixups — применяется непосредственно перед генерацией контента для его окончательной корректировки, один из наиболее часто используемых хуков.
9. handler — отсылает контент клиенту.
Модуль может использовать хуки в любой точке обработки запроса. В дополнение к этим стандартным хукам модуль может определить свои собственные хуки.
Главным отличием второго Apache является появление фильтров. Фильтры бывают входящими и выходящими. Когда стоит дилемма в выборе между хуком и фильтром, фильтр нужно реализовывать случае, если модуль обрабатывает входные и выходные данные и используется во многих приложениях.
Примеры модулей, реализованных как фильтры:
1. mod_include — подключает скрипты.
2. mod_ssl — реализует защищенный протокол.
3. обработка картинок.
4. mod_form, mod_upload — обработка форм и загрузок.
5. mod_deflate — сжатие данных.
Обычно каждый модуль Apache декларирует набор данных и функций:
module AP_MODULE_DECLARE_DATA my_module = { STANDARD20_MODULE_STUFF, /* версионность */ my_dir_conf, /* локальная конфигурация */ my_dir_merge, my_server_conf, /* генеральная конфигурация */ my_server_merge, my_cmds, /* директивы конфигурации */ my_hooks /* обработчики, регистрируемые в ядре */};Функция для обработки запроса:
static void my_hooks(apr_pool_t *pool) {...}Хук для генератора контента:
ap_hook_handler(my_handler, NULL, NULL, APR_HOOK_MIDDLE);Когда начнется генерация контента, будет вызван my_handler:
static int my_handler(request_rec *r) {...}В начало
Фильтры
В первом Apache обработчик контента работает по стандартной схеме. Вначале вызывается обработчик type_checker для определения типа контента, после чего ядро вызывает нужный обработчик для отсылки контента. Недостатком обработки контента в первом Apache является то, что если контент имеет комплексный тип и для его обработки требуется не один, а несколько обработчиков, то контент отсылается по очереди, и каждый последующий обработчик никак не может повлиять на то, что отсылается клиенту до него или после него.
Во втором Apache обработчик контента расширен путем добавления фильтров, которые могут манипулировать данными, посылаемыми клиенту. И несколько модулей могут параллельно обрабатывать один клиентский запрос. Фильтры могут быть назначены еще на этапе определения типа контента.
Фильтры бывают входящими (input filters) и исходящими (output filters).
Обрабатываемые данные разбиваются на секции (brigade), которые в свою очередь разбиваются на сегменты (bucket). Один фильтр обрабатывает один сегмент, после чего передает его по цепочке на следующий фильтр.
Кроме деления на входящие и исходящие, фильтры можно разбить еще на три категории:
1. Контент-фильтры.