WebDav¶
Introduction¶
Ewt intègre un servlet WebDav au travers duquel une application Ewt peut offrir des fonctionnalités WebDav, notamment :
- la navigation au sein d'un système de fichier
- l'édition inline de documents (l'édition inline permet d'éditer un document via un client local (Word, LibreOffice, etc.) sans nécessité de download/upload manuel)
Principe de fonctionnement¶
Le servlet WebDav en lui-même n'intègre aucune logique métier. Il sert uniquement de relai entre un client WebDav et un script Ewt chargé de traiter la requête. De ce point de vue, le servlet WebDav de Ewt fonctionne de façon analogue au servlet Rest : il reçoit une requête, analyse l'URL pour en extraire le nom d'application, le nom de script et les éventuels éléments supplémentaires. Il passe ensuite ces éléments à un script chargé de faire le traitement, puis construit une réponse conforme à la spécification WebDav. L'analogie avec Rest s'arrête là car l'implémentation d'un script Ewt destiné à WebDav est très différente de celle d'un script destiné à Rest.
En effet, le script invoqué par WebDav doit respecter certaines règles afin d'implémenter la logique d'un magasin de données WebDav. On appelle ici "magasin de données" la couche qui se charge de traiter les commandes passées via le servlet WebDav (p.ex: "récupérer la ressource X", "créer un dossier", "énumérer le contenu de Y", etc.). Ces commandes sont implémentées sous la forme de fonctions dans un script Ewt.
flowchart LR
C[Client] <-->|request| A[WebDav Servlet]
A <--> S[Script]
S <--> F[Database]
Voici un exemple fonction implémentant une méthode d'un magasin de donnée :
1 2 3 4 | |
Toutes les fonctions du magasin de données doivent satisfaire deux conditions:
- Elles doivent se trouver à la racine du script
- Elles doivent être annotées avec l'annotation
@webdav
La fonction en soi peut avoir n'importe quel nom. C'est l'annotation
@webdav qui indique à Ewt quel rôle (où plutôt quelle méthode) joue la
fonction dans le magasin de donnée implémenté par le script. L'annotation
doit avoir la forme suivante:
@webdav(method = NOM_COMMANDE [ , independent = BOOLEEN ])
Une même fonction peut jouer plusieurs rôles et peut par conséquent recevoir plusieurs annotations. Un exemple est donné plus bas.
L'annotation attend obligatoirement un paramètre method qui indique le nom
de la méthode qu'implémente la fonction. Les noms de méthodes reconnues sont
donnés plus bas. La valeur NOM_COMMANDE est une chaîne de caractères
délimitée par ", ' ou `.
Un second paramètre independent est optionnel et vaut false par défaut.
Il indique au servlet WebDav comment la fonction doit être invoquée. Nous
revenons plus bas sur ce paramètre.
L'exemple donnée plus haut montre une fonction implémentant la méthode
getStoredObject. Cette méthode a pour rôle de fournir au servlet des
informations concernant une ressource. Ainsi l'annotation permet d'attribuer
un rôle (une méthode) à une fonction du script.
L'annotation @webdav permet de déclarer les méthodes suivantes:
checkAuthenticationgetChildrenNamesgetStoredObjectcreateFoldercreateResourcedeleteObjectgetResourceLengthgetResourceContentsetResourceContentcommitTransactionrollbackTransaction
Servlet¶
Le servlet ch.epilogic.ewt.webdav.WebdavServlet doit être déclaré et mappé
dans le fichier web.xml de la webapp Ewt. Le servlet reconnaît un certain
nombre de paramètres d'initialisation:
enabled-methods-
Liste des méthodes WebDav HTTP acceptées par le servlet. Les valeurs doivent être séparées par une virgule, sans espace.
Les méthodes reconnues sont les méthodes standard de la norme WebDav:
GET,HEAD,DELETE,COPY,LOCK,UNLOCK,MOVE,MKCOL,OPTIONS,PUT,PROPFIND,PROPPATCHSi le paramètre n'est pas spécifié ou s'il vaut "*", toutes les méthodes sont activées.
Notez que certaines méthodes dépendent des autres. Par exemple la méthode
MOVEdépend deCOPYetDELETE. La méthodeCOPYdépend deDELETE. Certaines fonctionnalités nécessitent plusieurs méthodes. L'édition en ligne par exemple nécessite les méthodesOPTIONS,PROPFIND,HEAD,GET,LOCK,UNLOCKet PUT`.
instead-of-404
URI d'une ressource à retourner à la place de la ressource demandée
lorsque cette dernière n'exite pas. Si non définie, le servlet retourne
la page 404 standard.
no-content-length-headers
Valeur du header Content-Length à retourner dans le cas où une
ressource demandée n'existe pas. La valeur par défaut est -1.
lazy-folder-creation-on-put
Flag true/false indiquant si le dépôt d'une ressource dans un
dossier qui n'existe pas via la méthode PUT est autorisé à créer
automatiquement le dossier en question.
La valeur par défaut est `false`.
Paramètre independent¶
Par défaut le paramètre independent est false. Dans ce cas, lorsque le
servlet doit invoquer une méthode, il procède en deux temps :
- Il évalue tout le script : cette étape a pour but d'évaluer toutes les variables ou déclarations de fonctions qu'offre le script. Le servlet est obligé de passer par cette étape pour construire un scope qui sera réutilisé par la méthode.
- Il invoque la méthode dans le scope construit à l'étape précédente
Lorsque le paramètre independent est activé, cela indique au servlet
que la fonction peut être invoquée indépendamment du reste du script,
c'est-à-dire sans tenir compte des éventuelles autres fonctions ou
déclarations de variables. Dans ce cas, l'étape 1 mentionnée ci-dessus est
ignorée. L'étape 2 est alors réalisé avec un scope vide.
En clair, lorsqu'une fonction est annotée avec le paramètre
independent = true, cela indique au servlet qu'il peut invoquer la méthode,
et seulement la méthode. Le fait de déclarer une fonction indépendante offre
deux avantages:
- une sécurité accrue : seule la méthode est invoquée et non le reste
- une meilleure performance : le script n'a pas besoin d'être intégralement évalué, seule la fonction l'est
En contrepartie, une fonction indépendante ne peut pas bénéficier des variables ou fonctions voisines. Le fait d'y faire référence provoquerait une erreur à l'exécution. Pour illustrer cela, prenons l'exemple ci-dessous.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |
Ici toutes les fonctions sont déclarées independent. Lorsque le servlet
WebDav doit invoquer l'une des méthodes ci-dessus, il ignorera tout le reste
du script. Ainsi la trace de fin de script ne sera jamais affichée.
Cela a une incidence très importante sur le fonctionnement des méthodes WebDav implémentées au sein d'un script Ewt et marquées comme indépendantes. Ces méthodes n'ont pas connaissance du scope qui les entoure. Pour comprendre cela, prenons un nouvel exemple:
1 2 3 4 5 6 7 8 9 | |
Ici la fonction bar est déclarée comme méthode WebDav
indépendante implémentant checkAuthentication. La fonction foo est une
fonction quelconque invoquée par bar.
À l'exécution, le code ci-dessus provoquera une erreur car la fonction
foo n'existe pas (elle ne figure pas dans scope) au moment où bar est
invoquée. Cela vient du fait que le servlet invoque la méthode bar
indépendamment du scope qui l'entoure.
Fonction inline
Comment faire alors si l'on souhaite conserver une méthode indépendante, mais structurer le code et utiliser des méthodes ? La solution est de déclarer la fonction inline :
1 2 3 4 5 6 7 8 9 | |