|
Résumé
1 Introduction
2 Conventions d'écriture
3 Terminologie
4 Modèle de données des propriétés
des ressources
4.1 Modèle des propriétés de ressource
4.2 Propositions en cours pour les méta-données
4.3 Propriétés et entêtes HTTP
4.4 Valeurs des propriétés
4.5 Noms des propriétés
4.6 Liens indépendants des médias
5 Collections de ressources WEB
5.1 Modèle de l'espace de noms d'URL HTTP
5.2 Collection de ressources
5.3 Création et extraction de collections de ressources
5.4 Ressources source et ressources de sortie
6 Verrouillage
6.1 Verrous exclusifs et partagés
6.2 Support requis
6.3 Marqueurs de verrous
6.4 schéma URI du marqueur de verrou opaquelocktoken
6.4.1 Génération du champ noeud sans passer
par une adresse IEEE 802
6.5 Exploration des possibilités de verrouillage
6.6 Exploration des verrous actifs
6.7 Considérations d'utilisation
7 Verrou d'écriture
7.1 Méthodes restreintes par les verrous d'écriture
7.2 Verrous d'écriture et marqueurs de verrous
7.3 Verrous d'écriture et propriété
7.4 Verrous d'écriture sur des ressources nulles
7.5 Verrous d'écriture sur des collections
7.6 Verrous d'écriture et entête de requête
If
7.6.1 Exemple - verrou d'écriture
7.7 Verrous d'écriture et méthodes copy/move
7.8 Rafraîchissement des verrous d'écriture
8 Méthodes HTTP pour la rédaction
distribuée
8.1 Méthode PROPFIND
8.1.1 Exemple - obtenir des propriétés nommées
8.1.2 Exemple - utilisation de allprop pour
obtenir toutes les propriétés
8.1.3 Exemple - utilisation de propname pour
obtenir les noms de toutes les propriétés
8.2 Méthode PROPPATCH
8.2.1 Codes d'états à utiliser avec des
méthodes multi-états 207
8.2.2 Exemple - méthode PROPPATCH
8.3 Méthode MKCOL
8.3.1 Requête
8.3.2 Codes d'états
8.3.3 Exemple - méthde MKCOL
8.4 Méthodes GET et HEAD
appliquées à des collections
8.5 Méthode POST appliquée à
des collections
8.6 Méthode DELETE
8.6.1 Méthode DELETE appliquée
à des ressources autres que des collections
8.6.2 Méthode DELETE appliquée
à des collections
8.7 Méthode PUT
8.7.1 Méthode PUT pour des ressources
autres que des collections
8.7.2 Méthode PUT pour des collections
8.8 Méthode COPY
8.8.1 Méthode COPY pour des ressources
HTTP/1.1
8.8.2 Méthode COPY appliquée
à des propriétés
8.8.3 Méthode COPY appliquée
à des collections
8.8.4 Méthode COPY et entête
Overwrite
8.8.5 Codes d'états
8.8.6 Exemple - COPY avec overwrite
8.8.7 Exemple - COPY sans overwrite
8.8.8 Exemple - COPY sur une collection
8.9 Méthode MOVE
8.9.1 Méthode MOVE appliquée
aux propriétés
8.9.2 Méthode MOVE appliquée
à des collections
8.9.3 Méthode MOVE et l'entête
overwrite
8.9.4 Codes d'état
8.9.5 Exemple - MOVE d'une ressource autre
qu'une collection
8.9.6 Exemple - MOVE d'une collection
8.10 Méthode LOCK
8.10.1 Fonctionnement
8.10.2 L'effet des verrous sur les propriétés
et les collections
8.10.3 Verrouillage des ressources dupliquées
8.10.4 Valeur de Depth et verrouillage
8.10.5 Interaction avec d'autres méthodes
8.10.6 Tableau de compatibilité des verrous
8.10.7 Codes d'état
8.10.8 Exemple - une demande de verrouillage simple
8.10.9 Exemple - rafraîchissement d'un verrou d'écriture
8.10.10 exemple - requête de verrou sur plusieurs
ressources
8.11 Méthode UNLOCK
8.11.1 Exemple - UNLOCK
9 Les entêtes HTTP pour la rédaction
distribuée
9.1 Entête DAV
9.2 Entête Depth
9.3 Entête Destination
9.4 Entête If
9.4.1 Règle de production de No-tag-list
9.4.2 Règle de production de Tagged-list
9.4.3 Règle de production inverse (not
)
9.4.4 Fonction matching
9.4.5 Entêtes If et les proxies non conformes DAV
9.5 Entête de marqueur de verrou (Lock-Token)
9.6 Entête Overwrite
9.7 entête de réponse Status-URI
9.8 Entête de requête Timeout
10 Extensions des codes d'état de HTTP/1.1
10.1 Code d'état 102 : Traitements
10.2 Code d'état 207
: Etats multiples
10.3 Code d'état 422
: Entité impossible à traiter
10.4 Code d'état 423
: verrouillé
10.5 Code d'état 424
: Dépendance échue
10.6 Code d'état 507
: Mémoire insuffisante
11 Réponse d'états multiples
12 Définitions des éléments XML
12.1 Elément XML activelock
12.1.1 Elément XML depth
12.1.2 Elément XML locktoken
12.1.3 Elément XML timeout
12.2 Elément XML collection
12.3 Elément XML href
12.4 Elément XML link
12.4.1 Elément XML dst
12.4.2 Elément XML src
12.5 Elément XML lockentry
12.6 Elément XML lockinfo
12.7 Elément XML lockscope
12.7.1 Elément XML exclusive
12.7.2 Elément XML shared
12.8 Elément XML locktype
12.8.1 Elément XML write
12.9 Elément XML multistatus
12.9.1 Elément XML response
12.9.2 Elément XML responsedescription
12.10 Elément XML owner
12.11 Elément XML prop
12.12 Elément XML propertybehavior
12.12.1 Elément XML keepalive
12.12.2 Elément XML omit
12.13 Elément XML propertyupdate
12.13.1 Elément XML remove
12.13.2 Elément XML set
12.14 Elément XML propfind
12.14.1 Elément XML allprop
12.14.2 Elément XML propname
13 Propriétés DAV
13.1 Propriété creationdate
13.2 Propriété displayname
13.3 Propriété getcontentlanguage
13.4 Propriété getcontentlength
13.5 Propriété getcontenttype
13.6 Propriété getetag
13.7 Propriété getlastmodified
13.8 Propriété lockdiscovery
13.8.1 Exemple - obtenir la propriété lockdiscovery
13.9 Propriété resourcetype
13.10 Propriété source
13.10.1 Exemple - une propriété source
13.11 Propriété supportedlock
13.11.1 Exemple - extraire la propriété
supportedlock
14 Règles pour la prise en compte de XML dans DAV
15 Classes conformes DAV
15.1 Classe 1
15.2 Classe 2
16 Considérations sur l'internationalisation
17 Considérations sur la sécurité
17.1 Authentification des clients
17.2 Blocage du service
17.3 La sécurité par l'obscurité
17.4 Considérations sur la confidentialité
par rapport aux verrous
17.5 Considérations sur la confidentialité
par rapport aux propriétés
17.6 Réduction de la sécurité à
cause des liens de type source
17.7 Conséquences de l'usage d'entités externes
XML
17.8 Risques en relation avec les marqueurs de verrous
18 Considérations relatives à l'IANA
19 Propriété intellectuelle
20 Avertissements
21 Références
21.1 Références normatives
21.2 Références informatives
22 Adresses des auteurs
23 Annexes
23.1 Annexe 1 - Définition de Type de Document (DTD)
de WEBDAV
23.2 Annexe 2 - Profil ISO 8601 pour les indications de
date et de temps
23.3 Annexe 3 - Notes sur le traitement des éléments
XML
23.3.1 Notes sur les éléments vides XML
23.3.2 Notes sur les traitements XML interdits
23.4 Annexe 4 -- Les espaces de noms XML pour WebDAV
23.4.1 Introduction
23.4.2 Signification des noms qualifiés
24 COPYRIGHT complet
Ce document décrit une extension du protocole HTTP/1.1 qui permet aux clients WEB de participer à des processus éditoriaux à distance. Cette extension fournit un ensemble cohérent de méthodes, entêtes, formats de corps de requêtes et de réponses qui permettent de faire les opérations suivantes :
Le raisonnement et les conditions requises pour ces opérations sont décrits dans un document annexe intitulé "Conditions nécessaires au protocole d'écriture et de versionnement distribués pour le World Wide Web" [RFC2291].
Les sections ci-dessous forment une introduction détaillée aux propriétés des ressources (section 4), les collections de ressources (section 5), les opérations de verrouillage (section 6). Ces sections introduisent les abstractions manipulées par les méthodes HTTP spécifiques à WebDav décrites à la section section 8, "méthodes HTTP pour l'écriture distribuée".
Dans HTTP/1.1, les paramètres passés aux méthodes étaient exclusivement codés dans les entêtes HTTP. WebDav, au contraire, code ces informations soit dans le corps d'une entité requête en utilisant le format XML (eXtensible Markup Language) [REC-XML], soit dans une entête HTTP. Le choix de l'utilisation de XML pour coder les paramètres d'une méthode a été motivé par la possibilité qu'offre ce langage de pouvoir rajouter des éléments à des structures existantes, apportant ainsi l'extensibilité attendue et par la possibilité qu'offre XML de pouvoir coder l'information en utilisant les jeux de caractères ISO 10646, afin de garantir un support international. Comme règle générique, on retiendra que les paramètres sont codés dans le corps XML des requêtes quand leur longueur est quelconque, ou qu'ils peuvent être vus par un regard humain, ce qui nécessite un codage des caractères en ISO 10646 et qu'ils sont codés à l'intérieur des entêtes HTTP dans les autres cas. La section 9 décrit les nouvelles entêtes HTTP utilisées avec les méthodes WebDAV.
Au delà de son utilisation pour le codage des paramètres des méthodes, XML est utilisé dans WebDav pour coder les réponses aux méthodes, apportant ainsi les avantages de l'extensibilité et de l'internationalisation de XML dans les deux cas de figure.
Les éléments XML utilisés dans cette spécification sont définis dans la section 12.
L'extension de l'espaces de noms XML (Annexe 4) est aussi utilisée dans cette spécification afin d'autoriser l'usage de nouveaux éléments XML sans que ceux-là rentrent en collision avec d'autres.
Bien que les codes d'états fournis par HTTP/1.1 soient suffisants pour prendre en charge la plupart des cas d'erreur des méthodes WebDAV, il existe quelques cas d'erreurs qui ne tombent pas nettement dans les catégories existantes. Les nouveaux codes d'états développés pour les méthodes WebDav sont définis dans la section 10. Comme il existe quelques méthodes WebDav qui peuvent agir sur plusieurs ressources, les réponses de type états multiples ont été introduites pour retourner des informations d'états concernant plusieurs ressources. La réponse d'états multiples est décrite dans la section 11.
WebDAV utilise le mécanisme des propriétés pour renregistrer l'état courant d'une ressource. Par exemple, qaund un verrou est posé sur une ressource, une propriété d'information de verrou permet de connaître l'état courant du verrou. La section 13 définit les propriétés utilisées avec les spécifications WebDAV.
La fin de la spécification contient des sections portant sur la compatibilité (section 15), sur le support de l'internationalisation (section 16), et la sécurité(section 17).
Ce document décrivant un ensemble d'extensions au protocole HTTP/1.1, l'extension de la BNF utilisée ici pour spécifier les éléments du protocole est exactement la même que celle décrite à la section 2.1 de [RFC2068] et s'appuie également sur les règles de production de base fournies à la section 2.2 de [RFC2068].
Les mots clés "DOIT", "NE DOIT PAS", "REQUIS", "DEVRA", "NE DEVRA PAS", "DEVRAIT", NE DEVRAIT PAS", "RECOMMANDÉ", "PEUT" et "OPTIONNEL" utilisés dans ce document doivent être interprétés tel que décrit dans le document RFC 2119 [RFC2119].
URI/URL : respectivement "Identifiant Uniforme de Ressource" (Uniform Resource Identifier) et "Adresse Uniforme de Ressource" (Uniform Resource Locator). Ces termes (et la distinction entre les deux) sont définis dans le document [RFC2396].
Collection : Une collection est une ressource composée d'un ensemble d'URI, celles des membres appelés. Elles identifient les ressources membres et doivent être conformes aux conditions décrites dans la section 5 de cette spécification.
URI membre : Toute URI de l'ensemble d'URI constituant une collection.
URI membre interne : Une URI membre en relation directe avec l'URI de la collection (la définition de ce que signifie "en relation directe" est écrite à la section 5.2).
Propriété : Une paire composée d'un nom et d'une valeur permettant de décrire les caractéristiques de la ressource.
Propriété vivante : Une propriété dont la
sémantique et la syntaxe sont imposées par le serveur. Par exemple,
la valeur de la propriété vivante "getcontentlength",
en l'occurrence la longueur de l'entité retournée par une requête
GET, est calculée dynamiquement par le serveur.
Propriété morte : Une propriété dont la sémantique et la syntaxe ne sont pas imposées par le serveur. Le serveur ne fait qu'en enregistrer la valeur et il revient au poste client d'en garantir la cohérence syntaxique et sémantique.
Resource NULL : Une ressource qui retourne une erreur 404
(message "pas trouvée") en réponse à toute méthode
HTTP/1.1 ou DAV sauf dans le cas des méthodes PUT, MKCOL,
OPTIONS et LOCK. Une ressource NULL NE DOIT
PAS apparaître dans la liste des membres de sa collection parent.
Les propriétés sont une partie des données des la ressource dont elle servent à en décrire l'état. En quelque sorte, les propriétés sont des données qui décrivent des données.
Les propriétés sont utilisées dans les environnements
de rédaction distribuée afin de fournir des moyens efficaces de
recherche et de gestion des ressources. Par exemple, une propriété
qui s'appellerait 'subject' peut permettre de faire une indexation
des ressources par sujet, et une propriété 'author'
offrirait la possibilité de rechercher les documents à partir
des noms de leurs auteurs.
Le modèle des propriétés DAV est formé du couple nom/valeur. Le nom d'une propriété permet d'en connaître la syntaxe et la sémantique, et fournit une adresse par laquelle on peut faire référence à cette syntaxe et cette sémantique.
Il y a deux catégories de propriétés : les propriétés "vivantes" et la propriétés "mortes". Une propriété vivante a sa syntaxe et sa sémantique imposées par le serveur. Les propriétés vivantes comprennent les cas où a) la valeur de la propriété est en lecture seule et elle est maintenue par le serveur, et b) la valeur de la propriété est maintenue par le client et le serveur contrôle la syntaxe des valeurs transmises. Toutes les instances d'une propriété vivante DOIVENT être conformes à la définition qui a été associée au nom de cette propriété. Une propriété morte a sa syntaxe et sa sémantique imposées par le client; le serveur ne fait bien souvent qu'en enregistrer la valeur mot à mot.
Les propriétés ont toujours jouées un rôle très important dans la gestion des grands référentiels de documents, et beaucoup des propositions actuelles intègrent les notions de propriétés, ou sont des discussions relatives au rôle des méta-données sur le Web de manière plus générale. Cela comprend PICS [REC-PICS], PICS-NG, XML, Web Collections, et plusieurs autres propositions concernant la représentation des relations à l'intérieur de HTML. Le travail sur PICS-NG et Web Collections a été poursuivi par le groupe de travail sur RDF (Resource Description Framework) du World Wide Web Consortium. RDF consiste en un modèle de données prévu pour fonctionner en réseau et une représentation XML de ce modèle.
Quelques propositions proviennent des concepts de bibliothèques électroniques. Parmis celles-là se trouve l'ensemble de méta-données Dublin Core [RFC2413] et le Warwick Framework [WF], une structure d'accueil pour différents schémas de méta-données. La littérature contient beaucoup d'exemples de méta-données, par exemple MARC [USMARC], un format de méta-données pour les bibliographies, et le rapport technique sur le format de bibliographie utilisé par le système Dienst [RFC1807]. De plus, les minutes de la première conférence de l'IEEE sur les méta-données fournissent une grande variété d'ensembles de méta-données qui ont été développés pour les besoins spécifiques de communautés particulières.
Les participants à la séance de travail "Metadata II" en 1996 à Warwick, UK [WF], ont pu noter que "de nouveaux ensembles de méta-données se développeront parallèllement à l'évolution de l'infrastructure réseau" et que "différentes communautés proposeront, concevront, et seront responsables de différents types de méta-données". Ces observations peuvent être corrobhorées en notant que plusieurs ensembles de méta-données spécifiques à des communautés particulières existent déjà, et qu'il existe une réelle motivation à développer de nouvelles formes de méta-données au fur et à mesure que le nombre de communautés utilisant des données sous forme numérique augmente, ce qui exige d'avoir un format de méta-données qui permette de les identifier et de les cataloguer.
Des propriétés exsitent déjà, d'une certaine manière, dans les entêtes des messages HTTP. Toutefois, dans les environnements de rédaction distribuée, un nombre relativement élevé de propriétés est nécessaire pour décrire l'état d'une ressource. Les initialiser et les retourner par les seules entêtes HTTP serait inefficace. Aussi, un mécanisme est nécessaire pour permettre à un "principal" d'identifier l'ensemble des propriétés qui le concerne et qu'il a le droit d'initialiser et de lire.
La valeur d'une propriété exprimée en XML DOIT être bien formée.
XML a été retenu parce que c'est un format de données flexible, se décrivant lui-même, structuré, qui supporte des définitions de schémas puissants, et supporte plusieurs jeux de caractères. La nature "auto-descriptive" de XML permet à n'importe quelle valeur de propriété d'être étendue par l'ajout de nouveaux éléments. Des clients plus anciens supporteront les extensions parce qu'ils sauront toujours traiter les données spécifiées dans leur format original et ignorer les éléments rajoutés qu'ils ne comprennent pas. Le support des multiples jeux de caractères en XML permet à toute propriété lisible par l'oeil humain d'être codée et lue dans un jeu de caractères familier à l'utilisateur. Le support par XML de multiples langages humains, par l'utilisation de l'attribut "xml:lang", permet de gérer les cas où un même jeu de caractères est commun à plusieurs langages humains.
Un nom de propriété est un identifiant universel unique associé à un schéma qui fournit l'information quant à la syntaxe et la sémantique de la propriété.
Une conséquence de l'aspect universel et unique des noms de propriétés et que les données reçues par les applications clientes peuvent dépendre de la régularité de comportement d'une propriété en particulier utilisée dans différentes ressources, que ce soit sur le même serveur ou sur des serveurs différents, et particulièrement si cette propriété est "vivante", le résultat dépendra directement de la fidélité de son implémentation par rapport à sa définition.
Le mécanisme des espaces de noms de XML, qui repose sur des URI s [RFC2396], est utilisé pour nommer les propriétés parce qu'il permet d'éviter les collisions de noms et fournit plusieurs niveaux de contrôles au niveau de leur gestion.
La propriété namespace est plate; c'est à
dire qu'elle n'a pas de structure hiérarchique reconnue. C'est à
dire que si deux propriétés qui s'écrivent pour l'une A
et pour l'autre A/B existent sur une ressource, cela ne signifie
qu'il y a une quelconque relation de hiérarchie entre les deux. Une spécification
séparée sera éventuellement réalisée sur
la question de la hiérarchisation des propriétés.
En conclusion, il n'est pas possible de définir deux fois une même propriété s'appliquant à la même ressource car cela provoquerait une collision dans l'espace de noms des propriétés de cette ressource.
Bien que les liens entre ressources soient supportés avec HTML, le Web
a besoin d'un support plus général des liens entre les différents
types de média possible (ces types de média sont connus comme
étant des types MIME ou des types de contenus). WebDav fournit de tels
liens. Un lien WebDav est définit par un type spécifique de propriété,
formellement défini à la section 12.4 (élément XML
Link) , qui permet de définir des liens entre des ressources
de n'importe quel type de média. La valeur de la propriété
est constituée des URI (Uniform Resource Identifiers) des ressources
sources et destinations des liens; le nom de la propriété identifie
le type de lien.
Cette section contient la description d'un nouveau type de ressource Web, le type collection, et discute de ses interactions avec le modèle de l'espace de nom des URL de HTTP. L'objectif d'une ressource de type collection est de modéliser des objets qui sont des regroupements de ressources (par exemple, les répertoires d'un système de fichiers) dans l'espace de noms d'un serveur.
Toutes les ressources compatibles DAV DOIVENT supporter le modèle de l'espace de noms des URL de HTTP comme cela est spécifié comme ci-après.
L'espace de noms d'URL HTTP est un modèle hiérarchique de noms dans lequel la hiérarchie est syntaxiquement représentée par le caractère "/".
Un espace de noms d'URL HTTP est réputé être régulier quand il répond à la condition suivante : pour toute URL de la hiérachie HTTP il existe une collection parente contenant cette URL comme membre interne ; seule la racine, ou collection de plus haut niveau de l'espace de noms, est exempté de la règle précédente.
Ni HTTP/1.1 ni WebDav n'imposent que la totalité de l'espace de noms d'URL HTTP soit régulier. Cependant, cette spécification précise que certaines méthodes WebDav ne sont pas autorisées à produire des résultats qui rendrait l'espace de noms irrégulier.
Bien que cela soit implcite dans [RFC2068] et [RFC2396], toute ressource, y compris les ressources de type collection, PEUVENT être identifiées par plus d'une URI. Par exemple, une ressource peut être identifiée pas plusieurs URL HTTP.
Une collection est une ressource dont l'état est
constitué d'au moins une liste d'URI de membres internes et d'un ensemble
de propriétés ; une collection peut toutefois avoir des états
additionels tel que des corps d'entités retournés suite à
l'exécution d'une méthode GET. Une URI de membre
interne DOIT être en relation directe avec une URI de base de la
collection. Cela étant, l'URI du membre interne d'une collection est
égale à l'URI de la collection auquel on rajout un segment additionel
pour les ressources qui ne sont pas elle-mêmes des collections , ou d'un
segment additionel suivi de "/" pour les ressources internes à
la collection qui sont elle-mêmes des collections, où le segment
est défini dans la section 3.3 du document [RFC2396].
Toute URI qui est un membre interne donné DOIT appartenir à la collection de manière unique, c'est à dire qu'il est interdit d'avoir plusieurs instances de la même URI dans une collection. Les propriétés définies sur des collections ont exactement les mêmes comportement que celles des ressources qui ne sont pas des collections.
Pour toute resource A et B compatible WebDAV, identifiées
par les URI s U et V, où U est
immédiatement relative à V, B DOIT
être une collection ayant U comme URI de membre interne. Ainsi, si les
ressources dont les URL http://foo.com/bar/blah
et http://foo.com/bar/ sont conformes à
WebDav alors la ressource ayant pour URL http://foo.com/bar/
doit être une collection et doit contenir l'URL http://foo.com/bar/blah
comme membre interne.
Dans la hiérarchie des espaces de noms d'URL HTTP, les ressources de type collection PEUVENT contenir comme membres internes les URLs d'enfants non-conformes à WebDav mais cela n'est pas exigé. Par exemple, si la ressource ayant l'URL http://foo.com/bar/blah n'est pas conforme à WebDAV et que l'URL http://foo.com/bar/ est identifiée comme étant une collection alors l'URL http://foo.com/bar/blah peut être ou non un membre interne de la collection http://foo.com/bar/.
Si une ressource conforme à WebDav n'a aucun enfant conforme à WebDav dans l'arborescence de l'espace de noms d'URL HTTP alors WebDav n'exige pas que cette ressource soit une collection.
Il existe une convention établie qui dit que lorsque une collection
est référencée par son nom sans le slash de fin, le slash
de fin est automatiquement rajouté. A cause de cela, une ressource peut
accepter une URI sans "/" de fin pout pointer vers une collection. Dans ce cas,
elle DEVRAIENT retourner dans sa réponse une entête content-location
pointant vers l'URI se finissant par le "/". Par exemple, si un
client invoque une méthode portant sur http://foo.bar/blah
(pas de "/" à la fin), La ressource http://foo.bar/blah/
(avec un "/" de fin) peut répondre comme si la
requête lui avait été appliquée, et en renvoyant
dans ce cas une entête content-location contenant http://foo.bar/blah/.
En général, les clients DEVRAIENT utiliser la forme avec
le "/" pour les noms de collections.
Une ressource PEUT être une collection mais n'être pas conforme
à WEBDAV. Cela étant, la ressource peut être conforme à
toutes les règles définies dans cette spécification quant
à la manière dont doit se comporter une collection sans pour autant
supporter toutes les méthodes qu'une ressource conforme à WebDav
se doit de supporter. Dans ce cas de figure, la ressource peut retourner la
propriété DAV:resourcetype
avec la valeur DAV:collection
mais NE DOIT PAS retourner la valeur "1"
dans l'entête DAV en réponse à la méthode OPTIONS
.
Ce document contient la spécification de la méthode MKCOL
qui sert à créer de nouvelles ressources de type collection, cela
en remplacement des méthodes PUT ou POST d'HTTP/1.1
pour les raisons suivantes :
Dans HTTP/1.1, la définition de la méthode PUT est
l'enregistrement du corps de la requête à l'endroit spécifié
par l'URI requête. Alors qu'un format de description de collections pourrait
tout à fait être conçu à partir de la méthode
PUT, les conséquences de l'envoi d'une telle description
au serveur seraient indésirables. Par exemple, si la description d'une
collection, dans laquelle il manquerait des ressources pourtant bien présentes
sur le serveur, était mise par PUT sur le serveur, cela
pourrait être interprété comme une commande de destruction
des membres correspondant à l'omission. Cela amènerait la méthode
PUT à agir comme la fonction DELETE, ce qui
est un effet indésirable puisque cela changerait la sémantique
de la méthode PUT et rendrait difficile le contrôle
de la fonction DELETE reposant un modèle de gestion des
droits d'accès basé sur des méthodes.
Alors que la méthode POST est suffisamment ouverte pour
qu'une commande POST de type "crée une collection" pourrait
être construite, cela est également indésirable parce qu'il
serait alors difficile de faire la différence entre cette utilisaiton
de la méthode POST et les autres utilisations de POST.
La définition exacte du comportement que les méthodes GET
et PUT doivent avoir quand elles sont appliquées à
des collections est définie ultérieurement dans ce document.
Dans de nombreux cas de ressources, l'entité retournée par une
méthode GET correspond exactement à l'état
persistant de la ressource, c'est le cas, par exemple, d'un fichier GIF stocké
sur un disque. Dans ce cas simple, l'URI à laquelle la ressource est
accédée est identique à l'URI à laquelle la ressource,
dans son état persistent, est stockée. C'est aussi le cas des
fichiers HTML sources qui sont transmis tel quel au client par le serveur (dans
le cas où il n'y a pas de traitement particulier préalable à
l'affichage).
Toutefois, il arrive que le serveur traite les ressources HTML avant leur transmission
au client en tant que corps d'entité. Par exemple, une directive de type
"server-side-include" (SSI) incluse dans un fichier HTML
peut donner l'instruction à un serveur de remplacer la directive elle-même
par une valeur calculée telle que la date courante. Dans ce cas, le fichier
retourné par la méthode GET (le fichier HTML d'origine
avec le résultat du calcul de la date) est différent de l'état
persistent de la ressource (le fichier HTML d'origine contenant la directive
SSI). Il est important de remarquer que dans ce cas typique, il n'y a actuellement
aucun moyen d'accéder la ressource HTML source qui contient la directive
avant traitement.
Parfois, l'entité retournée par la méthode GET
est le résultat d'un programme d'extraction de données décrites
par une ou plusieurs ressources sources (qui peuvent même ne pas avoir
d'emplacement à l'intérieur même de l'espace de noms de
l'URI). Un seul programme d'extraction de données peut, à lui
seul, générer dynamiquement un nombre potentiellement important
de ressources de sortie. Un exemple caractéristique peut être celui
d'un script CGI qui décrit un programme de type passerelle d'indexation
mettant en correspondance une partie de l'espace de nom d'un serveur avec une
demande d'indexation, par exemple http://www.foo.bar.org/finger_gateway/user@host.
Dans le cas où les fonctions de rédaction distribuée ne sont pas supportées, il est acceptable de ne pas établir de correspondance entre les ressources sources et l'espace de nom URI. En faite, cette forme de protection par rapport aux accés à des ressources sources a un réel effet bénéfique sur la sécurité. Toutefois, si l'édition à distance de la ressource source est souhaitée, elle doit avoir un emplacement dans l'espace de noms de l'URI. L'emplacement de la source ne doit pas se trouver au même endroit que celui où la ressource calculée est accessible, puisque, en général, les serveurs sont incapable, dans ce cas, de faire la distinction entre les demandes qui s'adressent aux ressources sources et celles qui concernent les ressources de sortie calculées. Il y a souvent une relation de type n-n entre les ressources sources et les ressources de sortie.
Sur les serveurs conformes à WebDav l'URI de la ressource source peut
être enrégistrée comme un lien vers la ressource de sortie
ayant le type DAV:source (se référer à la
section 13.10 pour une description de la propriété link
de la source). Conserver les URI des sources sous la forme de liens vers les
ressources de sortie revient à faire porter au client la charge de découvrir
l'emplacement où se trouve réellement la source sur lequel se
fait la rédaction. Remarquez qu'il n'est pas garantie que la valeur du
lien source pointe vers la bonne source. Les liens vers les sources peuvent
être rompus ou des erreurs peuvent avoir été commises au
moment de de leur saisie. Remarquez également que tous les serveurs ne
permettront pas aux postes clients de fixer les valeurs des liens vers les sources.
Par exemple un serveur qui génèrerait pour ses fichiers CGI des
liens calculés à la volée (par programme) vers les sources
n'autoriserait probablement pas les clients de le faire à sa place.
La possibilité de verrouiller une ressource est un mécanisme permettant de sérialiser les accès à cette ressource. En utilisant un verrou, un client en rédaction fournit une garantie fiable qu'un autre ne viendra pas modifier une ressource qui serait déjà en cours de modification. En faisant cela, un client est protégé contre le problème de "dernière mise à jour perdue".
Cette spécification permet d'avoir différents types de verrous au moyen de deux paramètres spécifiques aux clients, le nombre de demandeurs impliqués (exclusif vs. partagé) et le type d'accés à leur accorder. Ce document définit le verrouillage pour un seul type d'accès : celui en écriture. Toutefois, la syntaxe est extensible et permet la spécification éventuelle de verrouillage pour d'autres types d'accès.
La forme de verrou la plus élémentaire est le verrou exclusif. Il s'agit d'un verrou par lequel le droit d'accès fourni est accordé à un seul demandeur. La raison de cet arbitrage vient du désir de ne pas avoir à résoudre le problème de la fusion des modifications faites sur les sources.
Toutefois, il y a des cas où le but d'un verrou n'est pas d'en empêcher d'autres d'exercer leur droit d'accès mais plutôt de fournir un mécanisme par lequel les demandeurs peuvent signaler leur intention d'exercer leur droit d'accès. Les verrous partagés ont été défini précisément pour ce cas de figure. Un verrou partagé permet à plusieurs demandeurs de recevoir un verrou. Dès lors, tout demandeur ayant un droit d'accès approprié peut obtenir le verrou.
Avec les verrous partagés, il y a deux ensembles d'autorisations pouvant toucher une ressource. Le premier est celui des droits d'accès. Les demandeurs qui sont autorisés peuvent avoir, par exemple, le droit en écriture dans la ressource. Parmi eux, ceux qui ont obtenu un verrou partagé DOIVENT aussi s'autoriser mutuellement : ils constituent alors un sous-ensemble de l'ensemble des droits d'accès.
En considérant tous les demandeurs possible d'Internet, la grande majorité d'entre eux n'auront, dans la pluplart des cas, aucun droit d'accès à une ressource donnée. Parmi le petit nombre qui aura un droit d'accès en écriture, quelques demandeurs voudront s'assurer que leurs éditions seront dégagées de tout risque d'écrasement de données et utiliseront les verrous d'écriture exclusifs. D'autres pourront décider qu'ils ont confiance que leurs collègues n'écraseront pas leur travail (l'ensemble potentiel des collègues étant l'ensemble des demandeurs qui ont les droits en écriture) et utiliseront un verrou partagé, qui permet d'informer les collègues qu'un demandeur est peut être déjà en train de travailler sur la ressource.
Les extensions WebDav de HTTP n'ont pas besoin de fournir tous les moyens de communication nécessaires aux demandeurs pour coordonner leur activité. Quand on utilise des verrous partagés, les demandeurs ont le droit d'utiliser n'importe quel moyen de communication pour coordoner leurs travaux (par exemple, des notes écrites, des réunions, des post-it collés sur les écrans, des conversations téléphoniques, des courriels, etc.). Le but d'un verrou partagé est d'offrir aux collaborateurs la possibilité de connaître l'identité de celui qui travaille déjà sur la ressource.
Les verrous partagés font partie de cette spécification parce que les expériences passées sur les environnements de rédaction collaborative sur le WEB ont montré que les verrous exclusifs sont trop souvent rigides. Un verrou exclusif est utilisé pour imposer un processus rédactionnel particulier : pose d'un verrou exclusif, lecture de la ressource, modification du contenu, écriture de la ressource, libération du verrou. Mais les verrous ne sont pas toujours correctement libérés, par exemple, quand un programme "se plante", ou quand le propriétaire d'un verrou abandonne son travail en cours de route sans déverrouiller la ressource. Alors que l'utilisation de contrôle de temps limite (timeout) et l'intervention humaine d'un administrateur sont les moyens pour supprimer le verrou indésirable, il peut se trouver qu'aucun de ces deux mécanismes ne soit disponible au moment où on en a justement besoin; le contrôle de dépassement de temps peut être long et l'administrateur indisponible.
Il n'est pas exigé que le serveur soit conforme à WebDav pour qu'il sache supporter le verrouillage, quelque en soit la forme. Si le serveur supporte les mécanismes de verrouillage, il peut choisir de supporter n'importe quelle combinaison des formes exclusives et partagées des verrous et pour n'importe quel type d'accès.
La raison de cette souplesse est que les politiques de verrouillage sont intégrées au coeur même des systèmes de gestion et de versionnement des ressources utilisés par différents référentiels de stockage. Ces référentiels ont besoin d'avoir le contrôle sur les types de verrous qui seront disponibles. Par exemple, certains référentiels ne supportent que les verrous d'écriture partagés tandis que d'autres ne supportent que les verrous d'écriture exclusifs et d'autres encore n'en utilisent aucun. Comme chacun de ces systèmes est suffisamment différent pour pouvoir se satisfaire de l'absence de certaines fonctions de verrouillage, cette spécification laisse la question du verrouillage comme étant la seule négotiation possible à l'intérieur de WebDAV.
Un marqueur de verrou est un type de marqueur d'état, représenté
comme une URI, qui identifie un verrou particulier. Un marqueur de verrou est
retourné, après toute opération de verrouillage réussie,
dans la propriété lockdiscovery du corps de la réponse.
Il peut également être retrouvée en lançant une recherche
de verrou sur la ressource.
Les URI s de marqueurs de verrous DOIVENT être uniques à jamais pour toutes les resources. Cette contrainte d'unicité permet aux marqueurs de verrous d'être utilisés pour toutes les ressources et les serveurs sans crainte de confusion.
Cette spécification fournit un modèle d'URI de marqueur de verrou
appelé opaquelocktoken conforme à la contrainte d'unicité.
Toutefois, les ressources restent libres de retourner n'importe quel modèle
d'URI tant que cellle-là reste conforme à la contrainte d'unicité.
Le fait de pouvoir acccéder aux marqueurs de verrous ne signifie pas pour autant que le demandeur dispose de droits d'accès privilégiés. Tout le monde peut trouver le marqueur de verrou de n'importe quelle autre personne en exécutant simplement une recherche de marqueur. Les verrous DOIVENT être appliqués en fonction des mécanismes d'authentification disponibles sur le serveur, mais qui ne doit pas reposer sur une politique de secret des valeurs des marqueurs.
opaquelocktokenLe modèle d'URI opaquelocktoken est conçu pour être
unique, dans le temps, à travers toutes les ressources. Grâce à
cette unicité, un client peut soumettre un marqueur de verrou opaque
dans une entête If sur une ressource différente de
celle qui l'a retourné initialement.
Toutes les ressources DOIVENT reconnaître le modèle opaquelocktoken
et, au minimum, reconnaître que le marqueur de verrou ne fait pas référence
à un verrou en suspens de la ressource.
Afin de garantir l'unicité temporelle pour toutes les ressources, le
verrou opaquelocktoken nécessite l'utilisation d'un mécanisme
reposant sur le principe des identifiants universels uniques (Universal Unique
Identifier - UUID-), tel qu'il est décrit dans [ISO-11578].
Les générateurs de verrous Opaquelocktoken , toutefois,
ont le choix dans la manière dont ils créent les marqueurs. Ils
peuvent soit générer un nouvel UUID pour chaque marqueur de verrou
qu'ils créent soit créer un seul UUID puis lui ajouter des caractères
d'extension. Si la deuxième méthode est choisie alors le programme
de génération des extensions DOIT garantir que la même
extension ne sera jamais utilisée deux fois sur le même UUID.
La règle de production de l'UUID est la représentation sous forme de chaîne de caractères d'un UUID, tel que défini dans [ISO-11578]. Notez que l'espace blanc (LWS) n'est pas autorisé entre les éléments de cette règle de production.
OpaqueLockToken-URI = "opaquelocktoken:" UUID [Extension]
Extension = path
"path" est défini dans la section 3.2.1 de RFC 2068 [RFC2068]
Les UUIDs, tels que défini dans [ISO-11578], contiennent un champ "noeud" qui contient une des adresses IEEE 802 du serveur. Comme il est dit dans la section 17.8, il y a plusieurs risques relatifs à la sécurité inhérents à l'exposition des adresses IEEE 802 des machines. Cette section fournit un mécanisme alternatif qui permet de générer le champ "noeud" d'un UUID sans utiliser l'adresse IEEE 802. Les serveurs WebDav PEUVENT utiliser cet algorithme pour la création du champ noeud au moment de la génération des UUIDs. Le texte de cette section est issu d'un brouillon sur Internet de Paul Leach et Rich Salz, dont les noms sont rappelés ici afin que leurs travaux soient reconnus comme il se doit.
La solution idéale est d'obtenir un nombre aléatoire de 47 bits de qualité cryptographique, et de l'utiliser comme formant les 47 bits basses de l'ID du noeud, avec le bit de poids fort du premier octet de l'ID du noeud égal à 1. Ce bit est celui réservé au typage unicast/multicast, jamais utilisé dans les adresses IEEE 802 pas les cartes réseaux ; par conséquent, il ne pourra jamais y avoir de conflit entre les UUIDs générés par les machines, qu'elles soient équipées ou non d'une carte réseau.
Si un système n'a pas de fonction de base pour générer des nombres alétoire de cryptage, alors il y a, la plupart du temps, un grand nombre de de possibilités pour trouver une séquence aléatoire permettant de générer une valeur. Les types de données sources listées ci-après dépendent bien sûr du système, mais très souvent on trouve :
(Remarquez que c'est précisément le type de ressources aléatoires mentionnées ci-dessus qui sont utilisées pour alimenter les générateurs de nombres alétoires de qualité cryptographique sur des systèmes dont le matériel n'est pas équipé de fonctions spécifiques pour les générer.)
De plus, des données tels que le nom de l'ordinateur et le nom du système d'exploiation, bien que ne pouvant être qualifiées d'alétoire à proprement parler, pourront aider à faire la diffférence avec les nombres aléatoires produits par d'autres systèmes.
L'algorithme exact de génération d'un identifiant de noeud utilisant ces données est spécifique au système, parce que les données disponibles et les fonctions pour les obtenir sont à la fois et souvent très spécifiques au système. Toutefois, en acceptant que l'on pourrait concaténer toutes les valeurs des sources aléatoires dans un buffer, et qu'une fonction de hachage cryptographique telle que MD5 soit disponible, alors tout mot de 6 octets du buffer de hachage de MD5, ayant le bit multicast initialisé (le bit de poids fort du premier octet) pourra être un identifiant de noeud alétoire acceptable.
D'autres fonctions de hachage, telle que par exemple SHA-1, peuvent aussi être utilisées. La seule obligation est que le résultat soit un nombre aléatoire adapté, c'est à dire qu'à un ensemble d'entrées uniformément distribué produise un ensemble de sorties elles-mêmes uniformément distribuées, et que la modification d'un seul bit en entrée provoque le changement de plus de la moitié des bits de sortie.
Puisque le support des verrous au niveau du serveur est optionnel, un client
essayant de bloquer une ressource sur un serveur peut soit essayer le verrouillage
et espérer que cela marche, soit exécuter une sorte d'exploration
pour savoir quelles sont les capacités du serveur à supporter
le verrouillage. Cela est connu sous le nom d'exploration
des possibilités de verrouillage. Cela est différent de la recherche
des types de contrôles d'accès supportés puisque il peut
y avoir des types de contrôles d'accès sans verrou correspondant.
Un client peut déterminer quels sont les types de verrous supportés
par le serveur en récupérant cette information par la propriété
supportedlock .
Toute ressource conforme à DAV qui supporte la méthode LOCK DOIT
supporter la propriété supportedlock .
Si un demandeur verrouille la ressource qu'un autre demandeur espère
accéder, il est pratique pour le deuxième d'être capable
de trouver qui est le premier. Pour cela, il existe la propriété
lockdiscovery. Elle liste tous les verrous en suspens, décrit
leur type, et, quand ils sont disponibles, fourni les marqueur de verrous qui
s'y appliquent.
Toute ressource conforme à DAV qui supporte la méthode LOCK DOIT
supporter la propriété lockdiscovery .
Bien que les mécanismes de verrouillage spécifiés dans ce document fournissent une certaine garantie contre le problème de la dernière mise à jour perdue pour cause d'écrasement, ils ne peuvent cependant pas garantir à 100% que les mises à jour ne seront jamais perdues. Imaginez le scénario suivant :
Deux clients A et B souhaitent éditer la même
ressource "index.html". Le client A utilise
le protocole HTTP plutôt que WebDav , et donc, ne sait pas gérer
les verrous.
Le client A ne verrouille pas le document, exécute un GET
puis commence l'édition.
Le client B fait un LOCK , exécute un GET
et commence l'édition.
Le client B termine l'édition, exécute un PUT
, puis un UNLOCK . Le client A exécute un PUT
, écrase le fichier et fait perdre à B ses mises
à jour.
Il y a plusieurs raisons pour lesquelles le protocole WebDav lui-même
ne peut pas anticiper cette situation. La première est qu'il ne peut
pas obliger tous les clients à utiliser le verrouillage parce qu'il doit
rester compatible avec les clients HTTP qui, eux, ne comprennent pas le verrouillage.
Deuxièmement, il ne peut pas exiger des serveurs qu'ils supportent le
verrouillage à cause de la variété des implémentations
des référentiels, les uns s'appuyant plutôt sur des mécanismes
de réservation et de fusion que sur des verrous. Finallement, parce que
le protocole est de type "sans gestion d'état" (stateless),
il ne peut obliger le client à exécuter une séquence d'opération
pré-définie telle que LOCK / GET / PUT / UNLOCK .
Les serveurs WebDav qui supportent le verrouillage réduisent le risque d'avoir des clients écrasant mutuellement et par accident leurs modifications respectives en exigeant d'eux qu'ils bloquent les ressources avant de les modifier. De tels serveurs protègeront effectivement les clients HTTP 1.0 et HTTP 1.1 des modifications indésirables des ressources.
Les clients WebDav peuvent être de bons citoyens utilisant la séquence
d'opérations lock / retrieve / write /unlock (au moins par
défaut) chaque fois qu'ils interagiront avec un serveur WebDav qui supportera
le verouillage.
Les clients HTTP 1.1 peuvent être de bons citoyens, c'est à dire
en évitant d'écraser les changements faits par d'autres clients,
en utilisant des balises d'entités dans les entêtes If-Match
dans toute entête de requête de modification des ressources.
Les gestionnaires d'information peuvent essayer de contrôler les écrasements en implémentant des procédures du côté client exigeant le verrouillage avant de modifier des ressources WebDav .
Cette section décrit la sémantique propre au verrou d'écriture. Le verrou d'écriture est une instance spécifique du type verrou ; il est le seul type de verrou décrit dans cette sépcification.
Un verrou d'écriture DOIT contrôler qu'un demandeur n'ayant
pas le verrou ne peut exécuter avec succès aucune des méthodes
PUT, POST, PROPPATCH, LOCK, UNLOCK, MOVE, DELETE , ou MKCOL
sur la ressource verrouillée. Toutes les autres méthodes courantes,
en particulier GET , fonctionnent indépendamment de ce verrou.
Remarquez, toutefois, que lorsque des nouvelles méthodes seront créées il sera nécessaire de spécifier comment elles devront se comporter vis à vis du verrou d'écriture.
Une demande réussie pour obtenir un verrou d'écriture DOIT se traduire par la génération d'un marqueur de verrou unique associé au demandeur. Aussi, si cinq demandeurs ont un verrou d'écriture partagé sur la même ressource il y aura cinq marqueurs de verrous, un par demandeur.
Alors que ceux qui n'ont pas posé de verrou d'écriture ne peuvent pas modifier les propriétés d'une ressource, il est cependant toujours possible que les valeurs des propriétés vivantes soient changées, même quand elles sont verrouillées, à cause des exigences de leurs modèles.
Seules les propriétés mortes et vivantes dont les spécifications les soumettent au contrôle des verrous sont garanties de ne pas changer quand un verrou d'écriture est posé.
Il est possible de positionner un verrou d'écriture sur une ressource nulle afin d'en bloquer le nom.
Une ressource nulle bloquée en écriture, connue sous le nom de
ressource nulle verrouillée, DOIT retourner une erreur type 404
(Pas trouvée) ou 405 (méthode interdite) à
toute méthode HTTP/1.1 ou DAV à l'exception des méthodes
PUT, MKCOL, OPTIONS, PROPFIND, LOCK , et UNLOCK .
Une ressource nulle verrouillée DOIT apparaître comme un
membre de la collection parente dont elle fait partie. De plus, la ressource
nulle verrouillée DOIT être équipée de toutes
les propriétés obligatoires de DAV . La plupart de
ces propriétés, comme par exemple toutes les propriétés
de type get* , n'auront aucune valeur puisqu'une ressource nulle
verrouillée ne supporte pas la méthode GET . Les
ressources nulles verrouillées DOIVENT être équipées
des propriétés lockdiscovery et supportedlock
.
Jusqu'au moment où l'une des méthodes PUT ou MKCOL
est exécutée avec succès sur la ressource nulle verrouillée,
celle-là DOIT rester dans son état de ressource nulle verrouillée.
Toutefois, dès qu'une des méthodes PUT ou MKCOL
est exécutée avec succès, alors la ressource nulle verrouillée
cesse d'être dans l'état nul-verrouillé.
Si la ressource est déverrouillée, quelque en soit la raison,
sans qu'un PUT, MKCOL , ou toute méthode similaire n'ait
été exécutée avec succès, alors la ressource
DOIT retourner à son état nul.
Un verrou d'ériture sur une collection, qu'il ait été
créé par une requête de verrouillage de type "Depth:
0 " ou "Depth: infinity ", empêche le rajout ou le
retrait d'URI membres de la collection par d'autres demandeurs que les propritaires
des verrous. En conséquence, quand un demandeur réalise une requête
PUT ou POST pour créer une nouvelle ressource
sous une URI qui se trouve être un membre interne d'une collection verrouillée
en écriture et pour maintenir la cohérence de l'espace de noms
HTTP , ou qu'il souhaite réaliser un DELETE pour retirer
une ressource dont l'URI est une URI d'un membre interne d'une collection protégée
en écriture, alors cette requête DOIT échouer si
le demandeur n'est pas propriétaire d'un verrou d'écriture au
niveau de la collection.
Toutefois, si une demande de verrou d'écriture est faite sur une collection
contenant des URI membres qui s'appliquent à des ressources en cours
de verrouillage et d'une manière qui soit conflictuelle avec le verrou
d'écriture, alors la demande DOIT échouer et retourner
le code d'état 423 (Verrouillé).
Si le propriétaire d'un verrou rajoute l'URI d'une ressource en tant
que membre interne d'une collection verrouillée alors cette nouvelle
ressource DOIT être automatiquement rajoutée au verrou.
Cela est le seul mécanisme qui permet de rajouter une ressource à
un verrou d'écriture. Aussi, par exemple, si la collection /a/b/
est verrouillée en écriture est que la ressource /c
est déplacée pour devenir /a/b/c alors la ressource
/a/b/c sera rajoutée au verrou d'écriture.
IfSi il n'est pas obligatoire d'avoir un agent utilisateur pour connaître
l'existence d'un verrou quand on demande l'exécution d'une opération
sur une ressource verrouillée, le scénario suivant peut se produire.
Un programme A, exécuté par un utilisateur A,
pose un verrou d'écriture sur une ressource. Un programme B,
également exécuté par l'utilisateur A, n'a
pas la connaissance du verrou posé par le programme A, exécute
un PUT sur la ressource verrouillée. Dans ce scénario,
le PUT est réalisé avec succès parce que les
verrous sont associés à un même demandeur, pas un programme.
Et donc le programme B, parce qu'il est activé par le même
certificat de demandeur que A, est autorisé à faire
le PUT . Toutefois, si le programme B avait eu connaissance
du verrou, il n'aurait pas écrasé la ressource, préférant
à la place présenter une boîte de dialogue annonçant
le conflit à l'utilisateur. A cause de ce scénario, on a besoin
d'un mécanisme pour empêcher que des programmes différents
ignorent accidentellement les verrous posés par d'autres programmes ayant
les mêmes privilèges.
Afin d'empêcher ces collisions, un marqueur de verrou DOIT être
posé par un demandeur autorisé dans l'entête If
de toute ressource verrouillée pouvant réagir à des méthodes
ou sinon la méthode DOIT échouer. Par exemple, si une ressource
doit être déplacée et que la source et la destination sont
toutes les deux verrouillées alors deux marqueurs de verrous doivent
être soumis, l'un pour la source et l'autre pour la destination.
>>Requête
COPY /~fielding/index.html HTTP/1.1
Host: www.ics.uci.edu
Destination: http://www.ics.uci.edu/users/f/fielding/index.html
If: <http://www.ics.uci.edu/users/f/fielding/index.html>
(<opaquelocktoken:f81d4fae-7dec-11d0-a765-00a0c91e6bf6>)
>>Réponse
HTTP/1.1 204 No Content
Dans cet exemple, même si la source et la destination sont toutes les
deux verrouillées, un seul marqueur de verrou doit être soumis,
celui pour le verrou sur la destination. Cela parce que la source n'est pas
modifiée par l'ordre COPY , et par conséquent, n'est
pas concernée par le verrou d'écriture. Dans cet exemple, l'authentification
de l'agent utilisateur est déjà intervenue via un mécanisme
en dehors du périmètre concerné par le protocole HTTP ,
c'est à dire dans la couche de transport sous-jacente.
COPY/MOVE L'exécution de la méthode COPY NE DOIT
PAS dupliquer les verrous d'écriture actifs sur la source. Toutefois,
comme il a été noté précédemment, si l'ordre
COPY copie la ressource dans une collection qui, elle, est verrouillée
avec l'option "Depth: infinity ", alors la ressource sera ajoutée
au verrou.
Une requête MOVE appliquée avec succès sur
une ressource ayant un verrou d'écriture NE DOIT PAS déplacer
le verrou d'écriture avec la ressource. Toutefois, la ressource est sujette
à être rajoutée à un verrou déjà existant
au niveau de la destination, comme cela est spécifié dans la section
7. Par exemple, si le MOVE fait que la ressource devient un enfant
d'une collection qui est verrouillée avec l'option "Depth: infinity",
alors la ressource sera ajoutée au verrou déjà existant
au niveau de la collection. De plus, si une ressource verrouillée avec
l'option "Depth: infinity " est déplacée vers une
destination qui se trouve a l'intérieur de la portée de ce même
verrou (par exemple, à l'intérieur de l'arbre d'espace de noms
couvert par le verrou), la ressource déplacée sera à nouveau
rajoutée au verrou. Dans ces deux exemples, et comme il est spécifié
dans la section 7.6, une entête If contenant un marqueur
de verrou doit être soumise tant pour la source que pour la destination.
Un client N'A PAS A soumettre deux fois de suite une même requête
d'écriture. Remarquez qu'un client sait toujours qu'il est en train de
soumettre un même verrou pour la deuxième fois puisqu'il doit inclure
le marqueur de verrou dans l'entête If de sa requête
afin de pouvoir soumettre sa requête sur une ressource qu'il sait être
déjà vérouillée.
Toutefois, un client peut soumettre une méthode LOCK avec
une entête If mais sans corps. Cette forme de LOCK
DOIT être uniquement utilisée pour "rafraichir"
un verrou. Cela signifie, au minimum, que tout système de temporisation
associé au verrou DOIT être réinitialisé.
Un serveur peut très bien retourner une entête de dépassement de temps (timeout) avec un rafraîchissement de verrou différent de l'entête de dépassement de temps retournée quand le verrou fut initialement créé. De plus, des clients peuvent soumettre des entêtes de dépassement de temps de valeur arbitraire dans leurs requêtes de rafraîchissement de verrou.Les serveurs, comme toujours, peuvent ignorer les entêtes de dépassement de temps soumises par leurs clients.
Si une erreur est reçue en réponse à une requêtre
de rafraîchissement de LOCK le client DOIT garantir
que le verrou n'a pas déjà été rafraichi.
Les nouvelles méthodes HTTP décrites ci-après utilisent
XML comme format de requête et de réponse. Tous les clients et
les ressources conformes à DAV DOIVENT utiliser des parsers XML
conformes à la norme [REC-XML]. Tout le XML utilisé que ce soit
dans les requêtes ou dans les réponses DOIT être,
au minimum, bien formé. Si un serveur reçoit dans une requête
des données XML pas bien formées il DOIT rejeter la totalité
de la requête avec un code 400 (mauvaise requête).
Si un client reçoit dans une réponse des données XML mal
formées, il NE DOIT PAS supposer quoi que ce soit concernant
le résultat à retourner par la méthode et DOIT se
contenter de considérer que le serveur ne fonctionne pas bien.
PROPFINDLa méthode PROPFIND permet de récupérer
tant les propriétés de la ressource identifiée par l'URI
requête si la ressource n'a aucun membre interne, que celles de la ressource
identifiée par l'URI requête et ses ressources membres internes
si la ressource est une collection qui a des URIs de membres internes.
Toutes les ressources conformes à DAV DOIVENT supporter la méthode
PROPFIND et l'élément XML propfind (section
12.14) ainsi que tous les éléments XML définis pour être
utilisés avec cet élément.
Un client peut soumettre une entête Depth qualifiée
par une des valeurs "0 ", "1 "
ou "infinity " quand la méthode PROPFIND
est appliquée à une ressource de type collection contenant des
URI de membres internes. Les serveurs conformes à DAV DOIVENT
supporter les comportements correspondant aux valeurs "0 ", "1
" et "infinity ". Par défaut, une méthode PROPFIND
n'ayant pas entête Depth DOIT agir comme si la valeur
"Depth: infinity " avait été utilisée.
Un client peut utiliser l'élément XML propfind dans
le corps de la méthode request pour préciser l'information
recherchée. Il est ainsi possible de ne demander à obtenir soit
que les valeurs de certaines propriétés particulières,
soit toutes les valeurs d'une propriété, ou encore une liste de
noms de propriétés de la ressource. Un client peut choisir de
ne soumettre qu'une requête sans corps. Une requête de type PROPFIND
avec un corps vide DOIT être traitée comme une demande de
récupération de tous les noms et de toutes les valeurs de toutes
les propriétés de la ressource.
Tous les serveurs DOIVENT être capable de retourner une réponse
dont le contenu soit de type text/xml ou application/xml
et dans laquelle l'élément XML multistatus sera utilisé
pour y décrire les résultats obtenus dnas la recherche des différentes
propriétés.
Si un problème survient dans la lecture d'une propriété,
alors une erreur spécifique DOIT être incluse dans la réponse.
Une requête qui porte sur l'obtention de la valeur d'une propriété
qui n'existe pas est un cas d'erreur qui DOIT être relevé.
Si la réponse est fournie sous la forme de l'élément XML
multistatus , il faut générer un élément
XML response contenant le code d'état 404 (Pas
Trouvé).
En conséquence, l'élément XML multistatus
d'une ressource de type collection ayant des URI membres DOIT avoir,
en fonction de la profondeur depth spécifiée, un
élément XML response pour chacune des URI membres
de la collection. Chaque élément XML response DOIT
contenir l'élément XML href qui donne l'URI de la
resource à laquelle se rapporte les propriétés de l'élément
XML prop. Les résultats de la méthode PROPFIND
appliquée à une ressource de type collection ayant des URI de
membres internes sont retournés sous la forme d'une liste plate dont
l'ordre des entrées n'est pas significative.
Dans les cas allprop et propname , si un demandeur
n'est pas autorisé à savoir si une propriété particulière
existe alors elle DOIT être exclue de la réponse en la rendant
invisible.
Les résultats de cette méthode NE DOIVENT PAS être mis dans le cache.
>>Requête
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>
>>Réponse
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: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>
Dans cette exemple, la méthode PROPFIND est appliquée
à une ressource qui n'est pas une collection, à savoir le fichier
http://www.foo.bar/file. L'élément
XML propfind précise le nom de quatre propriétés
dont on cherche à obtenir les valeurs. Dans ce cas, seulement deux des
valeurs sont retournées, puisque le demandeur qui émet cette requête
n'a pas les droits d'accès suffisants pour voir les troisième
et quatrième propriétés.
allprop
pour obtenir toutes les propriétés>>Requête
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>
>>Réponse
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: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>
exemple collection
</D:displayname>
<D:resourcetype><D:collection/></D:resourcetype>
<D:supportedlock>
<D:lockentry>
<D:lockscope><D:exclusive/></D:lockscope>
<D:locktype><D:write/></D:locktype>
</D:lockentry>
<D:lockentry>
<D:lockscope><D:shared/></D:lockscope>
<D:locktype><D:write/></D:locktype>
</D:lockentry>
</D:supportedlock>
</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: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>
exemple 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:resourcetype/>
<D:supportedlock>
<D:lockentry>
<D:lockscope><D:exclusive/></D:lockscope>
<D:locktype><D:write/></D:locktype>
</D:lockentry>
<D:lockentry>
<D:lockscope><D:shared/></D:lockscope>
<D:locktype><D:write/></D:locktype>
</D:lockentry>
</D:supportedlock>
</D:prop>
<D:status>HTTP/1.1 200 OK</D:status>
</D:propstat>
</D:response>
</D:multistatus>
Dans cette exemple, la méthode PROPFIND a été
invoquée sur la ressource http://www.foo.bar/container/
avec une entête Depth de 1 , signifiant que
la requête s'applique à la ressource et ses enfants de premier
niveau, et l'élément XML propfind contient l'élément
XML allprop , ce qui signifie que la requête doit retourner
le nom et la valeur de toutes les propriétés de chaque ressource.
La ressource http://www.foo.bar/container/ possède les six propriétés suivantes :
DAV:creationdate ,DAV:displayname, DAV:resourcetype ,DAV:supportedlock . Les quatre dernières sont spécifiques à WebDAV, et sont
définies dans la section 13. Comme la méthode GET
n'est pas supportée par cette ressource, les propriétés
get* (comme par exemple getcontentlength ) ne sont
pas utilisables sur cette ressource. Les propriétés spécifiques
à DAV attestent que "container " fut créé
le 1er décembre 1997, à 5:42:21 de l'après midi, dans un
fuseau horaire à 8 heures ouest de GMT (creationdate), a
le nom "exemple collection " (displayname ), un type
de ressource collection (resourcetype ), et supports les verrous
d'écriture exclusifs et partagés (supportedlock ).
La ressource http://www.foo.bar/container/front.html possède les neuf propriétés suivantes :
bigbox
"),DAV:creationdate,DAV:displayname,DAV:getcontentlength,DAV:getcontenttype,DAV:getetag,DAV:getlastmodified,DAV:resourcetype ,DAV:supportedlock . Les propriétés spécifiques à DAV attestent que
"front.html " fut créé le 1er décembre 1997,
à 6:27:21 de l'après-midi, dans un fuseau horaire de 8 heures
à l'ouest de GMT (creationdate ), a le nom de "exemple
HTML resource " (displayname ), a un contenu de 4525 octets
de long (getcontentlength ), a le type MIME "text/html
" (getcontenttype ), a une balise d'entité "zzyzx
" (getetag ), fut modifié en dernier le lundi 12 janvier
1998 à 09:25:56 GMT (getlastmodified ), a un type de ressource
vide, signifiant qu'il ne s'agit pas d'une collection (resourcetype
), et accepte les deux types de verrous d'écriture : exclusif et partagé
(supportedlock ).
propname
pour obtenir les noms de toutes les propriétés>>Requête
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>
>>Réponse
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/>
<propstat>
<prop xmlns:R="http://www.foo.bar/boxschema/">
<R:bigbox/>
<R:author/>
<creationdate/>
<displayname/>
<resourcetype/>
<supportedlock/>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<response>
<href>http://www.foo.bar/container/front.html>
<propstat>
<prop xmlns:R="http://www.foo.bar/boxschema/">
<R:bigbox/>
<creationdate/>
<displayname/>
<getcontentlength/>
<getcontenttype/>
<getetag/>
<getlastmodified/>
<resourcetype/>
<supportedlock/>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
</multistatus>
Dans cette exemple, PROPFIND est appliquée à la
ressource collection http://www.foo.bar/container/,
et l'élément XML propfind contient l'élément
XML propname , signifiant que les noms de toutes les propriétés
doivent être retournés. Puisqu'il n'y a aucune précision
de Depth dans l'entête, la valeur par défaut "infinity
" est appliquée et tous les noms des propriétés de la collection
mais également de tous ses descendants doivent être retournés.
Ainsi, on trouve que dans l'exemple précédent, la ressource http://www.foo.bar/container/ possède six propriétés :
DAV:creationdate, DAV:displayname, DAV:resourcetype ,DAV:supportedlock . La ressource http://www.foo.bar/container/index.html, membre de la collection "enveloppe", possède neuf propriétés,
DAV:creationdate, DAV:displayname, DAV:getcontentlength, DAV:getcontenttype, DAV:getetag, DAV:getlastmodified, DAV:resourcetype ,DAV:supportedlock . Cette exemple montre également l'utilisation de la portée des
espaces de noms de XML, et de l'espace de noms par défaut. Puisque l'attribut
"xmlns" n'a pas de lettre de raccourci (préfixe) explicite,
l'espace de nom par défaut s'applique à tous les éléments
englobés. Par conséquent, tous les éléments qui
ne font pas explicitement état de l'espace de noms auquel ils appartiennent
sont membres du schéma de données de l'espace de noms "DAV:
".
PROPFIND La méthode PROPPATCH traite des instructions spécifiées
dans le corps de la requête pour assigner et/ou supprimer des propriétés
définies sur la ressource identifiée par l'URI requête.
Toutes les ressources conformes à DAV DOIVENT supporter la méthode
PROPPATCH et DOIVENT traiter des instructions qui sont spécifiées
par les éléments XML propertyupdate, set , et remove
du schéma de données de DAV. L'exécution des consignes
dans cette méthode est, bien sûr, soumise aux restrictions des
contrôles d'accès. Les ressources conformes à DAV DOIVENT
supporter l'initialisation de n'importe quelle propriété potentiellement
morte.
La corps du message de requête d'une méthode PROPPATCH
DOIT contenir l'élément XML propertyupdate
. Le traitement des instructions DOIT se faire dans l'ordre des instructions
reçues (c'est à dire de haut en bas). Les instructions DOIVENT
être soit toutes exécutées soit ne pas être exécutées
du tout. Ainsi, si une erreur survient pendant le traitement alors toutes les
instructions déjà exécutées DOIVENT être
annulées et un code d'erreur approprié doit être retourné.
Le traitement détaillé des instructions peut être trouvé
dans la définition des instructions set et remove
dans la section 12.13.
207Les exemples suivant sont des codes de réponses qu'on s'attend à
recevoir dans les réponses aux méthodes de type 207
(états multiples). Remarquez toutefois, que tant que cela n'est pas explicitement
prohibé, toute code de retour des séries 2/3/4/5xx peuvent être
utilisés dans une réponse de type 207 (états
multiples).
200 (OK) - La commande a réussi.Comme il peut y avoir une
série de commandes set et remove dans un corps
de requête, un code de retour 201 (Créé) semble
inaproprié.
403 (Interdit) - Le client, pour une raison que le serveur choisit
de na pas dévoiler, ne peut pas modifier l'une des propriétés.
409 (Conflit) - Le client a transmis une valeur dont la sémantique
est inappropriée pour la propriété visée. Cela comprend
par exemple les tentatives d'initialisation des propriétés qui
sont en lecture seule.
423 (Verrouillé) - La ressource spécifiée
est verrouillée et le client, soit n'est pas le propriétaire du
verrou, soit le type de verrou requiert qu'un marqueur de verrou soit soumis
et que cela n'a pas été fait par le client.
507 (Mémoire insuffisante) - Le serveur n'a pas assez de
mémoire pour enregistrer la propriété.
PROPPATCH >>Requête
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>
>>Réponse
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: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>