Модуль mod_dav. Введение в WebDAV


1. Введение

Если посмотреть на статистику сайта SecuritySpace.com, то можно увидеть, что вот уже 5 лет в десятку самых используемых модулей сервера Apache входит модуль mod_dav. Однако, как не странно, данное обстоятельство никоим образом не повлияло на количество материалов о mod_dav в русскоязычной части сети. Хотя такие парадоксы происходят у нас нередко. Что ж, попытаемся устранить этот пробел. Тем более, что модуль действительно заслуживает самого пристального внимания.
Статья, которую Вы читаете, является первой из серии статей про модуль mod_dav. Сама серия состоит из трех статей. Первая статья расскажет об основной задачи модуля, а именно о протоколе WebDAV. Вторая статья расскажет о том, как протокол реализован в Apache и как настроить сервер на работу с ним. А третья статья рассмотрит детали реализации модуля mod_dav. Итак, начнем.

2. Что такое WebDAV?

А начнем мы с названия. И что же означает “dav” в названии mod_dav? Такое название модуль получил потому, что основная его задача - реализация протокола WebDAV. С вопросом “что такое WebDAV?” обратимся к статье на Wikipedia.org:

“WebDAV - это современный и защищённый сетевой протокол высокого уровня, работающий поверх HTTP для доступа к объектам и коллекциям объектов. Сокращение от Web-based Distributed Authoring and Versioning.”
Не знаю как вам, а мне данное определение ясности в назначении протокола не дало. Но попробуем все же разобраться.
Начнем с задач протокола. Как ясно из определения, протокол позволяет работать с документами на удаленном сервере. Однако, это слишком общее определение протокола, и не дает никакого представления об его особенностях. А особенностей у него довольно много. Перечислим основные из них:
  • Выполнение основных файловых операций над объектами на удаленном сервере;
  • Выполнение расширенных файловых операций (блокировки, поддержка версий);
  • Работа с любым типом объектов (не только файлы);
  • Поддержка метаданных (свойств) объектов;
  • Поддержка одновременной работы над объектами.
Как видите, протокол предоставляет довольно много интересных возможностей. Теперь осталось разобраться, где эти возможности протокола будут востребованы.
Вот основные сценарии применения протокола WebDAV:
  • Совместная работа с веб-документами;
  • Сетевая файловая система;
  • Распределенная разработка программного обеспечения;
  • Унифицированный доступ к произвольному хранилищу.
И в качестве доказательства полезности протокола приведем примеры его реального использования. Вот только некоторые из них:
  1. Subversion. Использует WebDAV для совместной работы при разработке программного обеспечения.
  2. Microsoft Explorer/Office/Outlook. Протокол WebDAV используется для возможности работы с документами на удаленном сервере.
  3. Adobe GoLive. Протокол используется для совместной работы с веб-документами.
  4. Apache. Реализует поддержку WebDAV в модуле mod_dav.
  5. Zope и Tomcat. WebDAV используется для управления контентом.
Примечание: Работа WebDAV регулируется следующими стандартами:

3. Как работает WebDAV?

Как уже говорилось выше, WebDAV является расширением протокола HTTP/1.1. WebDAV добавил в HTTP/1.1 несколько новых заголовков и методов, а также изменил существующие методы HTTP.
Были добавлены следующие заголовки:
  1. DAV:
  2. If:
  3. Depth:
  4. Overwrite:
  5. Destination:
  6. Lock-Token:
  7. Timeout:
  8. Status-URI:
И следующие методы:
  1. PROPFIND;
  2. PROPPATCH;
  3. MKCOL;
  4. LOCK UNLOCK;
  5. COPY/MOVE.
Для того чтобы понять принцип работы протокола, рассмотрим каждый метод подробнее.

3.1 Метод PROPFIND

Метод PROPFIND является одним из основных методов протокола. Он предназначается для получения свойств ресурса или коллекции. Требуемый ресурс (коллекция) задается в методе с помощью URI. Если URI идентифицирует коллекцию, то метод возвращает свойства всех ресурсов, принадлежащих этой коллекции. Данный метод бывает трех типов:
  1. <prop> - возвращает значение заданных свойств;
  2. <allprop> - возвращает имена и значение всех свойств ресурса;
  3. <propname> - возвращает имена свойств ресурса.
Для наглядности рассмотрим каждый вид метода на примере.

Тип PROP метода PROPFIND

Данный тип метода PROPFIND предназначен для запроса значений определенных свойств ресурса или коллекции. Для получения этих значений, клиент должен указать в запросе серверу имена всех необходимых ему свойств.
Вот так выглядит запрос клиента серверу:
PROPFIND /file HTTP/1.1
Host: www.foo.bar
Content-type: text/xml; charset=“utf-8″
Content-Length: xxxx
<?xml version=“1.0″ encoding=“utf-8″ ?>
<D:propfind xmlns:D=“DAV:”>
<D:prop xmlns:R=“http://www.foo.bar/boxschema/”>
<R:bigbox/>
<R:author/>
<R:DingALing/>
<R:Random/>
</D:prop>
</D:propfind>
В этом запросе клиент запрашивает значения свойств: bigbox, author, DingALing, Random для ресурса (не коллекции) http://www.foo.bar/file.
Примечание: URI коллекции обязательно должен содержать символ “/” в качестве завершающего символа. Пример: http://www.foo.bar/bar/
А вот так выглядит ответ сервера клиенту на данный запрос:
HTTP/1.1 207 Multi-Status
Content-Type: text/xml; charset=“utf-8″
Content-Length: xxxx
<?xml version=“1.0″ encoding=“utf-8″ ?>
<D:multistatus xmlns:D=“DAV:”>
<D:response>
<D:href>http://www.foo.bar/file</D:href>
<D:propstat>
<D:prop xmlns:R=“http://www.foo.bar/boxschema/”>
<R:bigbox>
<R:BoxType>Box type A</R:BoxType>
</R:bigbox>
<R:author>
<R:Name>J.J. Johnson</R:Name>
</R:author>
</D:prop>
<D:status>HTTP/1.1 200 OK</D:status>
</D:propstat>
<D:propstat>
<D:prop>
<R:DingALing/>
<R:Random/>
</D:prop>
<D:status>HTTP/1.1 403 Forbidden</D:status>
<D:responsedescription>
The user does not have access to the DingALing property.
</D:responsedescription>
</D:propstat>
</D:response>
<D:responsedescription>
There has been an access violation error.
</D:responsedescription>
</D:multistatus>
Данный ответ возвращает значения свойств bigbox, author, а также описание того, что данный пользователь не имеет доступа к свойствам DingALing и Random.
Примечание: В случае, если хоть одно свойство вернет значение отличное от HTTP/1.1 200 OK, то запрос считается неуспешным (<D:responsedescription> There has been an access violation error. </D:responsedescription>).

Тип ALLPROP метода PROPFIND

Тип ALLPROP предназначен для запроса всех значений всех имеющихся свойств ресурса или коллекции. Для формирования метода этого типа клиенту необходимо только указать URI ресурса (коллекции).
Так выглядит запрос клиента серверу:
PROPFIND /container/ HTTP/1.1
Host: www.foo.bar
Depth: 1
Content-Type: text/xml; charset=“utf-8″
Content-Length: xxxx
<?xml version=“1.0″ encoding=“utf-8″ ?>
<D:propfind xmlns:D=“DAV:”>
<D:allprop/>
</D:propfind>
Вот ответ сервера клиенту на данный запрос:
HTTP/1.1 207 Multi-Status
Content-Type: text/xml; charset=“utf-8″
Content-Length: xxxx
<?xml version=“1.0″ encoding=“utf-8″ ?>
<D:multistatus xmlns:D=“DAV:”>
<D:response>
<D:href>http://www.foo.bar/container/</D:href>
<D:propstat>
<D:prop xmlns:R=“http://www.foo.bar/boxschema/”>
<R:bigbox>
<R:BoxType>Box type A</R:BoxType>
</R:bigbox>
<R:author>
<R:Name>Hadrian</R:Name>
</R:author>
<D:creationdate>
1997-12-01T17:42:21-08:00
</D:creationdate>
<D:displayname>
Example collection
</D:displayname>
<D:resourcetype>
<D:collection/>
</D:resourcetype>
</D:prop>
<D:status>HTTP/1.1 200 OK</D:status>
</D:propstat>
</D:response>
<D:response>
<D:href>http://www.foo.bar/container/front.html</D:href>
<D:propstat>
<D:prop xmlns:R=“http://www.foo.bar/boxschema/”>
<R:bigbox>
<R:BoxType>Box type B</R:BoxType>
</R:bigbox>
<D:creationdate>
1997-12-01T18:27:21-08:00
</D:creationdate>
<D:displayname>
Example HTML resource
</D:displayname>
<D:getcontentlength>
4525
</D:getcontentlength>
<D:getcontenttype>
text/html
</D:getcontenttype>
<D:getetag>
zzyzx
</D:getetag>
<D:getlastmodified>
Monday, 12-Jan-98 09:25:56 GMT
</D:getlastmodified>
</D:prop>
<D:status>HTTP/1.1 200 OK</D:status>
</D:propstat>
</D:response>
</D:multistatus>
Ответ сервера возвращает все свойства (bigbox, author, creationdate, displayname, resourcetype) коллекции http://www.foo.bar/container/ и все свойства вложенных в эту коллекцию ресурсов. В нашем случае таким ресурсом является файл http://www.foo.bar/container/front.html, который обладает следующими свойствами: bigbox, creationdate, displayname, getcontentlength, getcontenttype, getetag, getlastmodified.

Тип PROPNAME метода PROPFIND

И последним типом метода PROPFIND является тип PROPNAME. Этот тип метода предназначен для получения имен всех свойств указанного ресурса (коллекции).
Так выглядит запрос этого типа:
PROPFIND /container/ HTTP/1.1
Host: www.foo.bar
Content-Type: text/xml; charset=”utf-8″
Content-Length: xxxx
<?xml version=”1.0″ encoding=”utf-8″ ?>
<propfind xmlns=”DAV:”>
<propname/>
</propfind>
В нем клиент запрашивает имена всех свойств коллекции /container/, а также имена свойств всех вложенных в этот контейнер ресурсов.
Так выглядит ответ сервера на данный запрос:
HTTP/1.1 207 Multi-Status
Content-Type: text/xml; charset=“utf-8″
Content-Length: xxxx
<?xml version=“1.0″ encoding=“utf-8″ ?>
<multistatus xmlns=“DAV:”>
<response>
<href>http://www.foo.bar/container/</href>
<propstat>
<prop xmlns:R=“http://www.foo.bar/boxschema/”>
<R:bigbox/>
<R:author/>
<creationdate/>
<displayname/>
<resourcetype/>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<response>
<href>http://www.foo.bar/container/front.html</href>
<propstat>
<prop xmlns:R=“http://www.foo.bar/boxschema/”>
<R:bigbox/>
<creationdate/>
<displayname/>
<getcontentlength/>
<getcontenttype/>
<getetag/>
<getlastmodified/>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
</multistatus>
Данный ответ показывает, что у коллекции http://www.foo.bar/container/ есть пять свойств: bigbox, author, creationdate, displayname, resourcetype. А вложенный ресурс http://www.foo.bar/container/front.html обладает следующими свойствами: bigbox, creationdate, displayname, getcontentlength, getcontenttype, getetag, getlastmodified.

3.2 Метод PROPPATCH

Как видно из названия метода PROPPATCH он предназначен для изменения свойств ресурсов, а именно для добавления, удаления или изменения свойств ресурса, заданного в URI.
Рассмотрим пример такого запроса:
PROPPATCH /bar.html HTTP/1.1
Host: www.foo.com
Content-Type: text/xml; charset=“utf-8″
Content-Length: xxxx
<?xml version=“1.0″ encoding=“utf-8″ ?>
<D:propertyupdate xmlns:D=“DAV:”
xmlns:Z=“http://www.w3.com/standards/z39.50/”>
<D:set>
<D:prop>
<Z:authors>
<Z:Author>Jim Whitehead</Z:Author>
<Z:Author>Roy Fielding</Z:Author>
</Z:authors>
</D:prop>
</D:set>
<D:remove>
<D:prop>
<Z:Copyright-Owner/>
</D:prop>
</D:remove>
</D:propertyupdate>
В этом запросе клиент пытается создать для ресурса http://www.foo.com/bar.html свойство authors и удалить свойство Copyright-Owner.
А вот так выглядит ответ сервера клиенту на этот запрос:
HTTP/1.1 207 Multi-Status
Content-Type: text/xml; charset=“utf-8″
Content-Length: xxxx
<?xml version=“1.0″ encoding=“utf-8″ ?>
<D:multistatus xmlns:D=“DAV:”
xmlns:Z=“http://www.w3.com/standards/z39.50″>
<D:response>
<D:href>http://www.foo.com/bar.html</D:href>
<D:propstat>
<D:prop>
<Z:Authors/>
</D:prop>
<D:status>HTTP/1.1 424 Failed Dependency</D:status>
</D:propstat>
<D:propstat>
<D:prop>
<Z:Copyright-Owner/>
</D:prop>
<D:status>HTTP/1.1 409 Conflict</D:status>
</D:propstat>
<D:responsedescription>
Copyright Owner can not be deleted or altered.
</D:responsedescription>
</D:response>
</D:multistatus>
Сервер показывает, что свойство Copyright-Owner не может быть удалено, поэтому ни одно свойство не будет изменено.
Ответ 424 Failed Dependency показывает, что операция над свойством Authors была бы выполнена успешно, если не произошел бы конфликт с удалением Copyright-Owner.

3.3 Метод MKCOL

Метод MKCOL является одним из самых простых методов WebDAV и предназначен для создания новой коллекции.
В этом примере клиент запрашивает сервер создать коллекцию /webdisc/xfiles/:
MKCOL /webdisc/xfiles/ HTTP/1.1
Host: www.server.org
В ответе сервер сообщает, что коллекция создана:
HTTP/1.1 201 Created

3.4 Метод LOCK

Метод LOCK предназначен для создания блокировки доступа любого типа. Блокировки влияют и на ресурсы, и на коллекции. Если заблокирован ресурс, то и все его свойства также являются заблокированными.
Данный пример запроса пытается наложить эксклюзивную блокировку на изменения ресурса /file.html
LOCK /file.html HTTP/1.1
Host: www.host.com
Content-Type: text/xml; charset=“utf-8″
Content-Length: xxx
<?xml version=“1.0″ encoding=“utf-8″ ?>
<D:lockinfo xmlns:D=“DAV:”>
<D:lockscope>
<D:exclusive/>
</D:lockscope>
<D:locktype>
<D:write/>
</D:locktype>
</D:lockinfo>
Сервер показывает, что блокировка успешно создана. Ответ сервера также содержит значение opaquelocktoken, которое является уникальным идентификатором блокировки.
HTTP/1.1 200 OK
Content-Type: text/xml; charset=“utf-8″
Content-Length: xxx
<?xml version=”1.0″ encoding=“utf-8″?>
<D:prop xmlns:D=“DAV:”>
<D:lockdiscovery>
<D:activelock>
<D:locktype>
<D:write/>
</D:locktype>
<D:lockscope>
<D:exclusive/>
</D:lockscope>
<D:locktoken>
<D:href>
opaquelocktoken: e71d4fae-5dec-22d6-fea5-00a0c91e6be4
</D:href>
</D:locktoken>
</D:activelock>
</D:lockdiscovery>
</D:prop>

3.5 Метод UNLOCK

Метод UNLOCK предназначен для снятия блокировки с ресурса. Для формирования запроса требуется URI ресурса и значение opaquelocktoken созданной ранее блокировки.
Пример снятия блокировки:
UNLOCK /1234.html HTTP/1.1
Host: www.host.ru
Lock-Token: <opaquelocktoken:e71d4fae-5dec-22d6-fea5-00a0c91e6be4>
Данный запрос пытается снять блокировку (opaquelocktoken:e71d4fae-5dec-22d6-fea5-00a0c91e6be4) с ресурса 1234.html.
Ответ сервера показывает, что блокировка была успешно снята:
HTTP/1.1 204 No Content
Использование кода 204 (No Content) вместо 200 (OK) происходит, потому что сообщение ответа не содержит тела.

3.6 Методы COPY/MOVE

Метод COPY предназначен для создания копии ресурса, заданного с помощью URI. А URI копии ресурса задается в заголовке Destination. Метод копирует как ресурсы, так и коллекции (в зависимости от значения заголовка Depth).
В этом примере клиент пытается скопировать ресурс /~fielding/index.html и переписать им ресурс http://www.ics.uci.edu/users/f/fielding/index.html
COPY /~fielding/index.html HTTP/1.1
Host: www.ics.uci.edu
Destination: http://www.ics.uci.edu/users/f/fielding/index.html
Ответ сервера 204 No Content показывает, что ресурс http://www.ics.uci.edu/users/f/fielding/index.html был успешно перезаписан ресурсом /~fielding/index.html
HTTP/1.1 204 No Content
Метод MOVE функционирует аналогично методу COPY за исключением того, что после копирования ресурс удаляется.
Пример запроса:
MOVE /~fielding/index.html HTTP/1.1
Host: www.ics.uci.edu
Destination: http://www.ics.uci.edu/users/f/fielding/index.html
Ответ сервера 201 Created показывает, что ресурс http://www.ics.uci.edu/users/f/fielding/index.html не существовал до копирования.
HTTP/1.1 201 Created
Location: http://www.ics.uci.edu/users/f/fielding/index.html
Примечание: Помимо рассмотренных выше новых методов, протокол WebDAV переопределяет семантику методов HTTP/1.1: GET, HEAD, POST, DELETE. Значение методов осталось то же, но теперь они стали работать с ресурсами, коллекциями и свойствами.
Вот и все, что я хотел рассказать вам про протокол WebDAV. Информации, полученной из данной статьи, вполне достаточно, чтобы приступить к нашей основной цели, а именно, к изучению работы модуля mod_dav. Чем мы и займемся в следующей статье.
Более подробно про протокол WebDAV вы можете узнать в книге “WebDAV: Next-Generation Collaborative Web Authoring”, которую можно заказать в Озоне.

Ссылки

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

Автор: Сипягин Максим
Источник: www.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 Март 13, 2006

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

  1. Спасибо за интересную статью!

    Комментарий от Dmitry — Март 25, 2006 @ 2:13 pm

  2. Спасибо. Лично для меня было весьма познавательно. Жду продолжения.

    Комментарий от Charon — Март 27, 2006 @ 12:33 pm

  3. Благодарю. Статья помогла разобраться с вопросом, и корректно представить процессы.

    Комментарий от Александр — Апрель 11, 2006 @ 9:19 am

  4. Если кому не сложно . может подбросите рабочий конф с вебдавом ?

    Комментарий от AlienZzzz — Май 17, 2006 @ 10:05 pm

  5. Премного благодарен Вам за эту очень полезную статью и ресурс в целом!

    Комментарий от Ниязов Бакыт — Июль 29, 2006 @ 9:28 pm

  6. Отличная статья!!!!

    Комментарий от Shadow — Август 2, 2006 @ 10:18 am

  7. Вот только так и не ясно, каким образом заставить MS Office открывать файлы по ссылкам. Если тот же doc открывается кликом по , то он открывается в readonly режиме, хотя в логах апача есть все OPTIONS и PROPFIND. Если же URL документа вставить в File -> Open, то всё пучком, файл и открывается, и сохраняется по прежнему URL. Куда копать?

    Комментарий от Klopp — Декабрь 5, 2006 @ 7:22 pm

  8. Трудно не выполнить просьбу, высказанную в столь категоричной форме, да и любопытство берет верх, поворачиваемся налево.Желательно предложить что-то одно, но на Ваш взгляд самое важно условие, без которого любовный договор просто не может быть заключен.

    Комментарий от Александра — Февраль 9, 2007 @ 12:35 pm

  9. Интересная статья, жаль только не рассматриваются аспекты его практического применения, в частности использование в subversion, а также в других инструментах.

    Комментарий от smik — Март 13, 2007 @ 2:25 pm

  10. где б найти как его заставить работать на апаче 1.3.
    что-то у меня при запросе на сервер 500ю ошибку говорит… а в логах тишина…

    Комментарий от mrdaark — Август 20, 2008 @ 10:55 am

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

You must be logged in to post a comment.

Работает на WordPress