Модуль mod_dav. Архитектура модуля


В предыдущей статье мы рассмотрели реализацию протокола WebDAV в сервере Apache. В этой статье, которая является последней в серии, мы рассмотрим устройство модуля mod_dav - центрального модуля поддержки протокола WebDAV в Apache. Также мы покажем как создавать собственные dav-провайдеры.

Данная статья впервые была опубликова в 6 номере рассылки "Информационный бюллетень от ApacheDev.ru". Теперь, начиная с 6 выпуска, данная рассылка выпускается на базе сервиса Subscribe.ru. Подписаться на рассылку.

Введение


Как уже было сказано в предыдущих статьях [1,2], модуль mod_dav является интерфейсным модулем, в котором происходит только обработка протокола WebDAV, а реализацию взаимодействия с хранилищем ресурсов, хранение свойств и т.п. модуль mod_dav делегирует сторонним модулям (back-end модулям или dav-провайдерами). В mod_dav такое взаимодействие реализовано в виде нескольких семейств хуков (сгруппированных по функциональности), обработчики которых должны быть реализованы dav-провайдерами.
Всего в mod_dav предоставлено семь групп хуков: обработка двух из них обязательна, а остальных - опционально. Сперва мы покажем общую схему, а затем опишем основные группы подробно.

Архитектура mod_dav

Архитектура mod_dav
Архитектура mod_dav
На рисунке изображены все группы хуков, предоставляемых модулем mod_dav. Синим цветом выделены те группы хуков, для которых в dav-провайдере необходимы обработчики. Сейчас мы кратко рассмотрим каждую из этих групп, а ниже, уже более детально, изучим самые важные из них.
Название группы Описание
dav_hooks_repository Обязательная группа хуков. Объединяет хуки, отвечающие за взаимодействие с хранилищем ресурсов.
dav_hooks_propdb Обязательная группа хуков. В ней собраны хуки необходимые для работы со свойствами ресурсов (метаданными).
dav_hooks_liveprop Хуки для работы с Live-свойствами. Live-свойства предназначены для хранения значений, определяемых сервером, например: "getcontentlength" - длина тела ответа.
dav_hooks_locks Хуки для работы с блокировками ресурсов.
dav_hooks_vsn Версионность ресурсов.
dav_hooks_binding Связывание ресурсов.
dav_hooks_search Поиск ресурсов.
Теперь подробно рассмотрим три наиболее важные группы: dav_hooks_repository, dav_hooks_propdb и dav_hooks_locks.

mod_dav: Работа с хранилищем ресурсов

Для взаимодействия с хранилищем (репозитарием) ресурсов в mod_dav существует группа хуков dav_hooks_repository. Основное ее предназначение - это обработка входных и выходных потоков хранилища ресурсов. Обработчики этих хуков также обеспечивают выполнение основных файловых операций над ресурсами, например: копирование/перемещение ресурсов, создание коллекции, удаление ресурса и т.п.
Рассмотрим все хуки этой группы подробнее:
get_resource
Один из главных хуков данной группы. Обработчик хука get_resource связывает ресурс с URI запроса. Он должен возвращать структуру dav_resource, описывающую запрошенный ресурс. Структура dav_resource возвращается даже в случае, если запрошенный ресурс не существует.
get_parent_resource
Обработчик этого хука возвращает описатель (дескриптор) родительского ресурса для запрошенного URI. Если URI запроса указывает на корневую коллекцию, тогда возвращается NULL.
is_same_resource
Определяет, ссылаются ли два дескриптора на один и тот же ресурс.
is_parent_resource
Служит для определения, является ли один ресурс родительским для другого.
open_stream
Создает структуру потока - dav_stream, необходимую при заливке ресурса. Обработчик вызывается каждый раз, когда в хранилище добавляется новый ресурс.
close_stream
Закрывает открытый поток. Вызывается после того, как ресурс полностью залит.
write_stream
Вызывается циклически для блочной обработки данных закачиваемого ресурса.
seek_stream
Абсолютное смещение в потоке. Используется для поддержки заголовка Content-Range в методах GET/PUT.
set_headers
Вызывается перед отправкой ответа клиенту для установки заголовков. Обработчик хука deliver не вызывается, если используется метод HEAD.
deliver
Одни из главных хуков группы. Используется для отправки ресурса в заданный фильтр. Используется как для ресурсов, так и для коллекций.
create_collection
Создает коллекцию. В случае, если коллекция создана успешно, обработчик должен вернуть NULL.
copy_resource
Хук копирования ресурса или коллекции. Свойства ресурсов также копируются.
move_resource
Перенос ресурса.
remove_resource
Хук удаления ресурса или коллекции. При удалении ресурса также удаляются и его свойства.
walk
Хук обхода иерархии коллекций и ресурсов. Используется, когда запрос поступил на коллекцию и глубина обхода больше 0 (т.е. необходимо обработать вложенные объекты).
getetag
Получить ETag для ресурса.

mod_dav: Работа со свойствами

Второй важнейшей и обязательной группой хуков является группа работы со свойствами. Основной задачей обработчиков этой группы является организация хранения свойств ресурсов и коллекций. Также они обеспечивают выполнения всех операций над свойствами. Рассмотрим эти хуки.
open
Получаем дескриптор хранилища свойств.
close
Закрываем открытое хранилище свойств.
define_namespaces
Определение внутренних пространств имен для свойств.
output_value
Получение значения определенного свойства для указанного ресурса.
map_namespaces
Отображение глобальных пространств имен на пространства имен dav-провайдера.
store
Сохранить значение свойства для указанного имени.
remove
Удалить свойство.
exists
Проверяет, существует ли такое свойство.
first_name
Возвращает имя первого свойства ресурса.
next_name
Возвращает имя следующего свойства.
get_rollback
apply_rollback
Поддержка механизма отката изменений. Провайдером задается структура dav_deadprop_rollback, в которой хранятся старые имена и значения свойств.

mod_dav: Блокировки

Последняя группа, которую мы рассмотрим, отвечает за функционирование механизма блокировок. Она не является обязательной, но необходима для реализации методов WebDAV: Lock и Unlock.
get_supportedlock
Возвращает значение свойства supportedlock для ресурса.
parse_locktoken
Парсит поступивший токен блокировки. Тут мы создаем и возвращаем структуру dav_locktoken.
format_locktoken
Преобразуем структуру dav_locktoken в строку URI.
compare_locktoken
Сравниваем два токена блокировок.
open_lockdb
Открывает и подготавливает хранилище блокировок. Dav-провайдер может воспользоваться значением директивы DAVLockDB для размещения своего хранилища (значение можно получить с помощью функции dav_get_lockdb_path()).
close_lockdb
Хук завершения работы с блокировками.
remove_locknull_state
Выводим ресурс из состояния lock-null.
create_lock
Создаем блокировку для ресурса. В обработчике этого хука должен быть создан токен новой блокировки.
get_locks
Получить все блокировки указанного ресурса.
find_lock
Найти блокировку ресурса по заданному токену.
has_locks
Хук проверки ресурса на наличие блокировок. Должна возвращать TRUE, даже если у ресурса есть только блокировки с истекшим сроком жизни (time-out).
append_locks
Добавить блокировки ресурсу.
remove_lock
Удалить блокировку с заданным токеном.
refresh_locks
Обновить блокировки у ресурса. Список токенов задает блокировки, которые необходимо обновить. Также в качестве аргумента передается структура time_t, описывающая текущее время.
lookup_resource
Найти ресурс, связанный с указанным токеном блокировки.
Теперь, после рассмотрения основных групп хуков модуля mod_dav, перейдем к практике. И посмотрим на код модуля-провайдера. Я не буду мешать код с текстом, поэтому все пояснения оформлены в виде комментариев к коду.
Совет: Нижеизложенный код изучать лучше с конца.

Структура dav - провайдера

// структура модуля для хранения директив
typedef struct {
const char *test_dav_directive;
}test_dav_server_conf;
// Обработчик хука post_config
static int test_dav_post_config(apr_pool_t *p, apr_pool_t *plog,
apr_pool_t *ptemp, server_rec *s) {
// Выполняем действия, необходимые для инициализации
// Данный обработчик вызывается после загрузки модуля и
// после обработки конфигурации
// (Примечание: Данный обработчик выполняется при загрузке дважды.
// Способ обойти такое поведение читайте в статье :
// /2006/03/13/problemi-pri-sozdanii-modula/)

return OK;
}
// Создать структуру конфигурации модуля
static void *create_server_config(apr_pool_t *p, server_rec *s){
test_dav_server_conf *conf = NULL;
conf = (test_dav_server_conf*)apr_palloc(p, sizeof(*conf));
return (void*)conf;
}
// Обработчик директивы
static const char *test_dav_cmd(cmd_parms *cmd, void *config,
const char *arg1){
test_dav_server_conf *conf;
// Получить указатель на структуру конфигурации модуля
conf = ap_get_module_config(cmd->server->module_config, &test_dav_provider_module);
// Сохранить значение директивы
conf->test_dav_directive = apr_pstrdup(cmd->pool, arg1);
return NULL;
}
// Директивы модуля
static const command_rec test_dav_cmds[] = {
// Декларация директивы и ее обработчика
AP_INIT_TAKE1("tes_dav_directive", test_dav_cmd, NULL, ACCESS_CONF|RSRC_CONF,
"Тестовая директива с одним аргументом"),
{NULL}
};
// Структура DAV провайдера
static dav_provider test_dav_provider =
{
&test_dav_hooks_repos, // Работа с хранилищем
&test_dav_hooks_propdb, // Работа со свойствами
&test_dav_hooks_locks, // Блокировка
NULL, // Версионность
NULL, // Связывание
NULL // Поиск
};
// Регистрация обработчиков хуков
static void register_hooks(apr_pool_t *pconf){
ap_hook_post_config(test_dav_post_config, NULL, NULL, APR_HOOK_MIDDLE);
// Регистрация DAV провайдера
dav_register_provider(pconf, "test_dav_provider", &test_dav_provider);
}
// Главная структура модуля Apache
module AP_MODULE_DECLARE_DATA test_dav_provider_module = {
STANDARD20_MODULE_STUFF,
NULL,
NULL,
create_server_config, // создание конфигурации модуля
NULL,
test_dav_cmds, // список директив модуля
register_hooks, // регистрация обработчиков
};
Данный код, а также код обработчиков test_dav_hooks_repos, test_dav_hooks_propdb и test_dav_hooks_locks можно скачать в виде архива.

Послесловие

Это последняя статья из серии про модуль mod_dav. Надеюсь, что она стала вам полезной и сняла часть вопросов, касающихся реализации WebDAV в сервере. Если у вас остались вопросы, то присылайте их мне на info@apachedev.ru. До встречи.

Другие статьи серии

Автор: Сипягин Максим.
Источник: ApacheDev.ru

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
Опубликовано в: Модули Apache Июль 17, 2006

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

  1. Класс статейка! Респект!!
    ___________________________
    http://www.pictgallery.ru/

    Комментарий от андрюха — Сентябрь 6, 2008 @ 11:36 am

  2. Согласен! ПОлезная инфа!!!
    ___________________________
    http://playboy-design.com/

    Комментарий от skif — Сентябрь 6, 2008 @ 11:38 am

  3. и куда это пихать?

    Комментарий от Ножки Буша — Октябрь 16, 2008 @ 8:14 am

  4. непонятно

    Комментарий от Ножки Буша — Октябрь 16, 2008 @ 8:15 am

  5. СТАТЬЯ УНЫЛЕ!11!!1

    Комментарий от УПЯЧКА — Октябрь 16, 2008 @ 8:19 am

  6. ОЯЕБУ!

    Комментарий от УПЯЧКА — Октябрь 16, 2008 @ 8:20 am

  7. СВОБОДА! РАВЕНСТВО! УПЯЧКА!
    УПЯЧКА СЛЕДИТ ЗА ТОБОЙ ВЕЗДЕ!

    Комментарий от УПЯЧКА — Октябрь 16, 2008 @ 8:21 am

  8. ПОПЯТЧСА!

    Комментарий от УПЯЧКА — Октябрь 16, 2008 @ 8:22 am

  9. ОНОТОЛЕ НАСТУПАЕТ!11!!!11

    Комментарий от УПЯЧКА — Октябрь 16, 2008 @ 8:26 am

  10. ПЫЩЬ!11!111

    Комментарий от УПЯЧКА — Октябрь 16, 2008 @ 8:27 am

  11. ЛЕОНИДЕ жж0т

    Комментарий от УПЯЧКА — Октябрь 16, 2008 @ 8:29 am

  12. ЙА РУБЛЮ БАБЛО САЙТЕ ОПАСНОСТЕ!

    Комментарий от УПЯЧКА — Октябрь 16, 2008 @ 8:33 am

  13. СУпер сайт, наешл тут кучу классной инфы! РЕСПЕКТ!
    _________________________
    http://eliteforex.ru/
    http://www.kondu.ru/

    Комментарий от Олег — Декабрь 17, 2008 @ 9:18 pm

  14. Очень классная статейка, для нубов конечно сложновато))
    но мне помогло! Респект!

    Комментарий от Инесса — Декабрь 20, 2008 @ 12:28 pm

  15. Весьма не плохо!! НО поймите тут нада добавить обьяснения для *нубов*! НУ написано на 5 баллов!

    Комментарий от Кирилл — Декабрь 20, 2008 @ 12:30 pm

  16. Спс за подробный инстракшн, будем попробовать.

    Комментарий от Субаровод — Март 10, 2009 @ 2:54 am

  17. А как он ложится вообще ? Спокойно ?

    Комментарий от Любитель драйва — Март 11, 2009 @ 1:37 am

  18. Да отлично всё! Ставьте, не беспокойтесь.

    Комментарий от неумёха — Март 13, 2009 @ 3:31 am

  19. Спасибо что подсказали, пригодится модуль.

    Комментарий от Марио — Апрель 16, 2009 @ 11:30 am

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

You must be logged in to post a comment.

Работает на WordPress