mod_rewrite, mod_perl, Mason : que la force soit dans Apache

Alexandre SIMON

CIRIL - Centre Interuniversitaire de Ressources Informatiques de Lorraine

Rue du Doyen Roubault

54500 VANDOEUVRE-LÈS-NANCY - FRANCE



Vincent DELOVE

CIRIL - Centre Interuniversitaire de Ressources Informatiques de Lorraine

Rue du Doyen Roubault

54500 VANDOEUVRE-LÈS-NANCY - FRANCE



Résumé

Le Web est sans doute la facette la plus visible et la plus incontournable de l'Internet. Ces dernières années les protocoles, les technologies et les frameworks ont énormément évolués pour faire changer les contenus et les méthodes de programmation d'un mode statique à un mode dynamique. On parle aujourd'hui du Web 2.0. Le serveur web Apache a su évoluer dans ce sens en proposant de nombreux modules. Parmi ces modules il y a la réécriture d'URL avec mod_rewrite et le module d'exécution et d'interprétation « embarquée » Perl mod_perl. Avec ces deux modules un développeur a à sa disposition deux outils extrêmement puissants lui permettant d'agir dynamiquement sur la visibilité de son site et sur la publication des contenus. mod_rewrite permet de faire quasiment toutes les manipulations sur les URL demandées ce qui entraine le développeur, en quelques lignes RewriteRule, à répondre à de complexes problèmes ou besoins d'accès à son site. Avec mod_perl, il peut aller encore plus loin en surchargeant et en modifiant le mode de fonctionnement « normal » d'Apache en l'adaptant à ses besoins. Le développeur va pouvoir en quelques lignes de Perl réécrire ou compléter les modules « de base » d'Apache et ainsi obtenir des fonctionnalités difficilement réalisables avec de simples scripts CGI. Enfin côté contenu, le module Perl HTML::Mason offre un système de template simple et complet. Très lié à mod_perl, HTML::Mason hérite de ses possibilités et dépasse le simple système de template en allant plus loin dans la publication des contenus. Cet article fera le point sur ces technologies en les présentant de manière pragmatique et en les illustrant par des exemples concrets.


Mots clefs

Apache, Perl, mod_rewrite, mod_perl, Mason, Web 2.0, REST



1Introduction

Parmi les standards à l'origine de l'Internet, le Web et les protocoles associés sont certainement ceux qui ont subi les évolutions les plus importantes de ces dernières années. Apache, pour prendre en compte ces nouveaux usages, s'appuie sur une architecture interne originale et flexible qui permet une extension modulaire de ses fonctionnalités. L'accessibilité des différentes étapes du processus de traitement des requêtes à travers ces modules fait d'Apache un modèle de conception. Pour le développeur web, la connaissance de ces mécanismes internes permet de révéler les possibilités étendues qui sont accessibles à travers l'utilisation ou la conception de nouveaux modules. Le module de réécriture des URL, « mod_rewrite », est un exemple parfait pour illustrer l'avantage que constitue le choix de cette architecture pour, par exemple, modifier dynamiquement la visibilité de son site. Ce module qui intervient très tôt dans la chaine de traitement, redéfinit profondément le comportement par défaut d'Apache en permettant par exemple de découpler la gestion des URL du système de fichiers sur disque. Cet article présente également comment certains modules comme « mod_perl » ne s'attachent pas simplement à une phase particulière mais comment ils constituent en fait une réelle API d'extension à Apache. Contrairement à ce que son nom pourrait faire penser, ce module n'est en aucun cas l'adaptation de mod_php pour Perl. Il offre la possibilité au programmeur Perl d'enrichir et de personnaliser le serveur à tous les niveaux. Cette introduction à « mod_perl » servira finalement de préambule à la présentation du module HTML::Mason et de ses concepts en terme de gestion de contenus.



2Apache : bien plus qu'un serveur web

2.1Contexte

Pour bien appréhender la présentation des modules mod_rewrite, mod_perl et Mason il est nécessaire de faire un approfondissement sur leur point commun : Apache. La compréhension de chacun de ces modules pourrait se suffire à elle-même, mais une présentation d'Apache permet de les replacer dans le contexte de fonctionnement du serveur et d'approfondir les mécanismes associés. L'idée n'est pas simplement de comprendre ce que « font » ces modules, mais surtout « pourquoi » et « comment » ils le font.

Dans ce cadre, la présentation d'Apache est ciblée et seuls les aspects du fonctionnement interne seront abordés. Les aspects généraux sur le serveur web, la configuration ou l'exploitation quotidienne ne seront pas traités. Certains concepts et explications seront raccourcis et simplifiés pour converger rapidement au coeur du fonctionnement d'Apache tout en restant le plus précis possible afin d'introduire au mieux la présentation des modules mod_rewrite, mod_perl et Mason.



2.2Architecture et plateforme de développement

Apache est sans doute le serveur web le plus connu et le plus répandu dans le monde du logiciel libre. Ses fonctionnalités et ses performances en tant que « serveur web » sont reconnues de tous. Mais ce n'est pas tout... Apache offre également une facette moins connue des administrateurs : une architecture interne originale faisant de lui une plateforme de développement pour compléter et modifier son fonctionnement « de base ». En effet, plus particulièrement depuis sa version 2.0, Apache propose une architecture interne modulaire, portable et extensible faisant penser, au premier abord, plus à une bibliothèque de développement qu'à un simple serveur web. Le noyau d'Apache (Apache core) est le point de départ et la base du développement du serveur lui-même mais également de tous les modules Apache disponibles (mod_...). Cette plateforme de développement propose une API de programmation : la librairie APR (Apache Portable Runtime) mais c'est surtout les concepts et l'architecture interne d'Apache qui font sa pertinence et son originalité.

Avec cette subtile combinaison de l'API de programmation et des concepts fondamentaux, il est possible de développer facilement et rapidement des modules et des fonctions complémentaires. Ces développements spécifiques sont, de fait, cohérents avec le reste du serveur. En suivant quelques règles de codage, ils bénéficient des fonctionnalités existantes et peuvent également être « prestataires de fonctions pour le reste ».



2.3Cycle de vie du serveur et des requêtes

Les possibilités de développement avec Apache sont directement liées à son fonctionnement et à l'architecture utilisée pour le traitement des requêtes et pour la génération des réponses.



Une vue naïve et simpliste du fonctionnement d'un serveur web peut être résumée par la Figure 1. En effet, du point de vue client, le cycle « requête – contenu – réponse » résume bien l'interface proposée par un serveur web. T



Figure 1: Vue simpliste du fonctionnement d'Apache

out le fonctionnement interne du serveur est caché et c'est ce sujet qui va être approfondi.



Le fonctionnement d'Apache se décompose en deux parties distinctes :



Le synoptique complet de ce fonctionnement est illustré par la Figure 2.



Figure 2: "The big picture" - Cycles de vie du serveur et des requêtes





Sur cette figure on distingue les deux blocs fonctionnels :



Le processus père a en charge :



De leur côté, les processus fils se chargent :















2.3.1Apache Hooks

Deux types d'appels de fonctions apparaissent sur la Figure 2 :



L'originalité du code d'Apache est d'avoir prévu « ces points de branchement » accessibles par les modules de base (Apache Core) mais également par tous les autres modules (modules fournis par Apache ou contributions extérieures).

Le principe d'utilisation des hooks est simple : un module peut à son initialisation enregistrer (ie. attacher) sur les crochets disponibles une fonction qui lui est propre. Durant le cycle de vie, au passage de chaque crochet, le processus exécute les fonctions (handlers) attachées à ces crochets selon la configuration du serveur et la requête en cours.





Figure 3: Exemple d'exécution des handlers sur le hook translate_name

La Figure 3 propose l'exemple d'enregistrements des modules mod_perl, mod_rewrite, mod_alias et mod_core au hook translate_name.

Le processus fils, au passage sur ce crochet, exécute les fonctions enregistrées par mod_perl puis mod_rewrite puis mod_alias et enfin mod_core. Cette série d'exécutions est conditionnelle et fonction de la configuration du serveur, de la requête en cours et du retour de l'appel à chacune de ces fonctions.















Le principe est donc posé : Apache propose en standard des « points de branchements » pour chainer l'exécution de fonctions enregistrées par les modules activés au démarrage du serveur. Cette notion de crochet n'est pas figée et il ne serait pas surprenant de voir apparaître des nouveaux hooks dans la prochaine version d'Apache, comme cela a été le cas lors du passage de la version 2.0 à la version 2.2 (test_config et monitor). D'autre part, la déclaration de nouveaux hooks ne se limite pas au coeur d'Apache et un module peut proposer lors de son exécution un point de branchement qui pourrait être utilisé à son tour par d'autres modules.

Cette présentation des Apache Hooks n'est pas exhaustive mais le concept doit être maintenant bien maitrisé. Pour approfondir ce mécanisme, le lecteur pourra étudier de plus prés les notions suivantes :



Le lecteur se reportera à la section 4.2 pour une description plus détaillée du rôle de chaque hooks dans le contexte de mod_perl.



2.3.2mod_info : consultation des hooks et des modules attachés

Depuis la version 2.2 d'Apache, le module mod_info permet de visualiser les hooks, les modules qui les utilisent et l'ordre d'enregistrement. Le lecteur pourra se reporter à la documentation http://httpd.apache.org/docs/2.2/mod/mod_info.html pour la mise en oeuvre de ce module. Il lui sera alors possible d'observer et de comprendre le comportement de son serveur au travers des informations de hooks ↔ modules enregistrés.

Dans la distribution d'Apache il existe également un script Perl qui fournit la liste des hooks disponibles dans le code : httpd-2.x.y/support/list_hooks.pl.



2.4Les filtres Apache

Après les hooks, la deuxième notion fondamentale d'Apache sont les filtres. Cette notion de filtre est déjà perceptible par les administrateurs qui ont certainement déjà manipulé des directives de configuration telles que AddOutputFilter, SetOutputFilter, AddOutputFilterByType... mais les filtres ne s'arrêtent pas là. En réalité dans Apache « tout est filtre » et les mécanismes associés sont transversaux et présents dans tous les autres concepts du serveur. Cette transversalité empêche de faire apparaître les filtres sur le synoptique des cycles de vie du serveur et des requêtes Figure 2, néanmoins les filtres sont omniprésents.



Il existe trois types de filtres qui opèrent à différents niveaux (cf. Figure 4).



Figure 4: Les filtres dans Apache

Transversalement aux opérations appliquées lors du passage dans les hooks, le flux de données entre le client et le serveur peut être filtré à différents niveaux :





Figure 5: Exemple d'application des filtres

Il faut bien comprendre que les filtres sont « partout » dans Apache et que toutes les opérations d'entrée/sortie passent par ces mécanismes de chainage. Pour illustrer ce concept prenons l'exemple d'une requête HTTPS depuis un client qui accepte la compression « à la volée » et qui consulte une page .shtml où sont présentes des directives SSI (Server Side Includes). Le flux de données traversant le serveur passe par les filtres indiqués sur la Figure 5.



Qui aurait pu croire que la fonctionnalité d'encodage/décodage SSL était implémentée à l'aide d'un « simple » filtre ? Pour se convaincre de l'omniprésence des filtres dans Apache il suffit de lancer un grep sur ap_register_output et ap_register_output dans les sources du serveur...



2.5Perspectives

Avec ces concepts de hooks et de filtres, Apache propose une architecture interne originale, modulaire et facilement extensible. Ce sont les fonctionnalités des modules proposés par Apache qui ont fait son succès auprès des administrateurs. C'est son architecture interne qui a séduit les développeurs et qui a permis l'ajout des fonctionnalités que l'on connait aujourd'hui.

Apache est donc bien plus qu'un « simple serveur web » car il propose une vraie plateforme de développement pour ses besoins propres et pour son évolution. Mais cette plateforme peut être également utilisée pour développer des serveurs qui n'ont rien à voir avec le protocole HTTP... pourquoi pas un serveur FTP... ou encore mieux un serveur SMTP ! C'est possible et cela existe déjà : http://httpd.apache.org/modules/.



3mod_rewrite : le couteau suisse pour la manipulation des URL

3.1Contexte

Le temps où les sites web vus des navigateurs étaient le reflet du système de fichiers du serveur est révolu et le module mod_rewrite y participe grandement ! Par défaut le serveur Apache fait une correspondance directe entre l'URL demandée et les fichiers disponibles sous sa portée (sous l'arborescence du DocumentRoot). Bien sûr les directives telles que Alias et ScriptAlias permettent de modifier cette correspondance et même de sortir des objets de la portée du serveur. Mais les possibilités de réécriture restent très basiques et lorsque les limites sont atteintes il faut utiliser un outil plus puissant : mod_rewrite.

Les détails des mécanismes utilisés par Apache pour faire la correspondance entre l'URL demandée et l'emplacement sur le système de fichiers sont présentés dans le document : http://httpd.apache.org/docs/2.2/urlmapping.html.

mod_rewrite est un outil très utile pour le développement d'applications web « modernes », car celles-ci ne sont pas toujours bien placées pour un traitement spécifique des URL. Il est souvent plus simple et pertinent d'écrire quelques règles de réécriture (RewriteRule) que de se lancer dans un codage applicatif trop spécifique.

Il faut préciser que mod_rewrite s'enregistre et intervient sur les hooks translate_name, fixups et handler du cycle de vie d'une requête HTTP (Figure 2).



3.2Evaluation des règles de réécriture

Rappelons que les règles de réécriture sont du type :

RewriteRule Pattern Substitution [flags]

Le Pattern est évalué par rapport à l'URL demandée par le client. La sous-chaine utilisée est extraite juste après le nom du serveur (hostname) et le port, et juste avant la chaîne des paramètres. Par exemple, pour l'URL http://vhost.ciril.fr/foo/bar/page.html?param=zoo&test=yes c'est la sous-chaine /foo/bar/page.html qui sera évaluée.

Si l'évaluation du Pattern est positive, alors la Substitution pourra être appliquée, et c'est cette nouvelle URL qui sera traitée dans le reste du cycle de vie de la requête. Les réécritures peuvent être de quatre types différents :



Il est possible d'utiliser des variables propres au contexte de réécriture pour compléter les substitutions précédentes, comme par exemple :



Des tests additionnels à l'aide de la directive RewriteCond peuvent compléter les règles de réécriture. Cette directive permet également des tests sur des éléments non disponibles au niveau de la directive RewriteRule. Dans l'exemple précédent, la règle RewriteRule ne peut évaluer le nom du serveur (vhost.ciril.fr) ni les paramètres passés dans l'URL (param=zoo&test=yes). RewriteCond a accès, entre autre, à ces valeurs et permet de les évaluer. Les règles de réécriture sont également de la forme :

RewriteCond TestString1 CondPattern1 [flags]
RewriteCond TestString2 CondPattern2 [flags]
RewriteRule Pattern0 Substitution [flags]

La Figure 6 illustre l'évaluation et l'enchainement de règles RewriteRule et RewriteCond.



3.3Références arrières $ et %



Figure 7: Références arrières $ et %

Lors de l'écriture des Pattern des directives RewriteRule et RewriteCond il est possible de « parenthéser » les expressions régulières afin d'utiliser le contenu qui aura été évalué dans les règles de substitutions et dans les règles conditionnelles. Ce mécanisme s'appelle « référence arrière » (back-reference).



La Figure 7, ci-contre, illustre le « parenthésage » des Pattern et la création automatique des références arrières associées. Il est également précisé où sont utilisables les différentes références arrières.











3.4Exemples d'utilisations

Cet article n'ira pas plus loin dans les explications des réécritures Apache. Le lecteur pourra se reporter aux excellentes documentations sur le sujet : http://httpd.apache.org/docs/2.2/rewrite/. Pour illustrer la puissance de mod_rewrite rien ne vaut quelques exemples concrets.



Comment remettre dans la portée du site web une page qui a bougé sur le système de fichier ?

RewriteRule /doc/doc.html /chemin/ancien/site/vieille-doc.html

Comment cacher un script ou le passage de paramètres derrière une « belle » URL ?

RewriteRule /graph-renater /cgi-bin/graph-rrd.cgi?file=renater.rrd
RewriteRule /([edit|view])/article([0-9]+) /cgi-bin/wiki.php?action=$1&article=$2

Comment servir une page spéciale en fonction du navigateur du client ?

RewriteCond %{HTTP_USER_AGENT} (Firefox) [OR]
RewriteCond %{HTTP_USER_AGENT} (Safari)
RewriteRule /foo.html /navigateurs-OK/%1/foo.html [L]

RewriteRule /foo.html /navigateurs-indesirables/foo.html

Comment faire une redirection (code HTTP 3xx) vers un site web extérieur ?

RewriteRule /vers-google http://www.google.fr [R]

Comment donner accès automatiquement à une page sous arborescence du type AAAA-MM-JJ depuis une URL invariable ?

RewriteRule /doc-du-jour /vers/arbo/%{TIME_YEAR}-%{TIME_MON}-%{TIME_DAY}/doc

Comment afficher une image spéciale sur le site est accédé en IPv6 ?

RewriteCond %{SERVER_ADDR} [:]+
RewriteRule /images/proto.png /images/proto-ipv6.png [L]
RewriteRule /images/proto.png /images/proto-ipv4.png

Comment servir des pages différentes en fonction de l'heure de consultation du site ?

RewriteCond %{TIME_HOUR}%{TIME_MIN} >0800
RewriteCond %{TIME_HOUR}%{TIME_MIN} <1800
RewriteRule /dispo /on-travaille.html [L]
RewriteRule /dispo /on-travaille-pas.html

Comment refuser l'accès à certaines ressources si le client n'est pas authentifié ?

RewriteCond %{REMOTE_USER} ![a-z0-9]+ [nocase]
RewriteRule /doc-interne - [forbidden]

De nombreux autres exemples très utiles sont documentés sur les pages :

4mod_perl : la puissance n'est rien sans la maitrise

4.1Description

Se lancer dans mod_perl peut, au début, être très déroutant. En effet, il n'est pas toujours évident de comprendre l'utilité et le fonctionnement de ce module qui est très différent des modules « classiques » disponibles avec Apache. Pour bien appréhender le sujet, un développeur devrait déjà se pencher sur le fonctionnement interne d'Apache. Il lui sera plus facile de faire le parallèle avec les possibilités de mod_perl. La suite de cet article s'appuie sur le chapitre 2 qui a traité en détails du fonctionnement interne d'Apache.

La réponse à la question « c'est quoi mod_perl ? » pourrait être :

« mod_perl est une subtile association de la flexibilité et de la simplicité du langage Perl avec la puissance du serveur web Apache. Ce module permet de faire énormément de choses, mais le plus intéressant est sa capacité à s'intégrer à l'architecture d'Apache en ayant accès à toutes les phases du cycle de vie d'une requête pour pouvoir dérouter et modifier le fonctionnement « normal » d'Apache. Avec mod_perl, il est possible d'écrire des modules « Apache en Perl » qui compléteront ou remplaceront les modules standards. Une fois que le développeur a compris où il est possible d'interagir, il n'y a plus de limite à l'imagination pour reprogrammer le comportement d'Apache. »1



4.2Hooking the hooks



Figure 8: Exemple de handler mod_perl

Le chapitre 2.3.1 présentait les hooks d'Apache, véritables « points de branchement » pour l'appel de fonctions auxiliaires. Alors que les modules « classiques » sont généralement conçus pour s'enregistrer à des points biens définis, mod_perl permet d'enregistrer une section de code Perl sur les hooks via le fichier de configuration httpd.conf. Cette fonction Perl (sub handler()) sera exécutée par le serveur Apache lors de l'itération d'appels des fonctions enregistrés sur le hook en question.

La Figure 8 illustre ce fonctionnement avec l'exemple d'une fonction Perl qui force la réécriture en minuscule de l'URL demandée. L'attachement de cette fonction sur le hook translate_name se fait dans le fichier de configuration httpd.conf via la directive PerlTransHandler MyApache::lcURI.



Figure 9: mod_perl et hooks cycle de vie serveur



La Figure 9 détaille l'utilisation par mod_perl des hooks du cycle de vie du serveur. A ce niveau seuls les hooks open_logs et post_config sont utilisés. Dans open_logs les tâches les plus communes sont l'initialisation et l'ouverture des fichiers de traces. C'est à cet endroit qu'une fonction ad'hoc devra être attachée si le développement mod_perl nécessite un fichier de trace spécifique. Le hook post_config est quant à lui placé juste après la lecture de la configuration et juste avant la création des fils Apache. C'est dans ce hook que le développeur va pouvoir initialiser un environnement qui sera disponible et partagé par l'ensemble des processus fils créés plus tard.













Figure 10: mod_perl et hooks cycle de vie requête






mod_perl dévoile toutes ses possibilités dans le cycle de vie des processus fils et du traitement des requêtes. Quasiment la totalité des hooks proposés par Apache sont utilisés par mod_perl (Figure 10) ce qui permet d'intervenir à n'importe quelle étape de traitement des requêtes. Voici le détail de chaque hook et les possibilités d'extensions en Perl :

4.3Les filtres Apache et mod_perl



Figure 11: mod_perl et filtres Apache

Les filtres sont, avec les hooks, le fondement du fonctionnement interne d'Apache et mod_perl propose, bien évidemment, une interface Perl à ce mécanisme.

La Figure 11 détaille l'implémentation mod_perl des filtres Apache. Les filtres disponibles ne peuvent s'appliquer qu'aux niveaux suivants :



Le code suivant présente un exemple de filtre de contenu (FilterRequestHandler) en sortie de traitement de la requête (PerlOutputFilterHandler). La totalité des données de la réponse passe par ce filtre qui va, au fil de l'eau, transformer tous les caractères en minuscule.

/* httpd.conf /

PerlOutputFilterHandler MyFilter::lowercase_all


/* MyFilter::lowercase_all */
sub handler :
FilterRequestHandler {

my $f = shift;

unless ($f->ctx) {
$f->r->headers_out->unset('Content-Length');
$f->ctx(1);
}

while ($f->read(my $data)) {
my $lowercase = lc( $data );
$f->print( $lowercase );
}

return Apache2::Const::OK;

}

L'utilisation des filtres est extrêmement puissante mais l'implémentation nécessite une bonne compréhension de quelques autres concepts (les Bucket Brigade, l'enchainement des filtres, …) et une convention d'écriture pour s'intégrer aux autres filtres disponibles en standard dans Apache. Le document suivant détaille ces points : http://perl.apache.org/docs/2.0/user/handlers/filters.html.



4.4Perspectives

La transposition par mod_perl des possibilités offertes par Apache doit être maintenant comprise. Cet article est loin d'être exhaustif sur le sujet mais les bases du fonctionnement ont toutes été présentées ici. Un développeur Perl a maintenant à sa disposition un ensemble d'outils lui permettant d'interagir avec le fonctionnement « normal » d'Apache pour l'adapter à ses besoins. Avec mod_perl, la résolution d'un problème peut trouver plusieurs solutions. Le plus important est que le développeur sache que «tout est possible » et qu'en suivant quelques « recettes de cuisine » il peut arriver rapidement et facilement à ses fins.

mod_perl est à la fois un complément très utile pour l'extension et l'administration d'Apache mais il est également une base de développement solide pour des plateformes de développement (par exemple HTML::Mason, Catalyst, …) ou des applications complexes (Request Tracker, OTRS, …).

5Génération de contenu avec HTML::Mason

5.1Contexte

Pendant longtemps, la façon la plus simple et la plus répandue de générer du contenu dynamique à travers un serveur web consistait en l'écriture de scripts CGI (Common Gateway Interface). Cette méthode réalise l'exécution d'un programme pour chaque requête et retourne le résultat (sortie standard) comme contenu. Ce mode de fonctionnement, qui convient encore parfaitement pour le traitement ponctuel de formulaires, présente des inconvénients majeurs pour le développement d'interface web dynamiques complexes (exécution systématique d'une nouvelle occurrence du script CGI, multiplications des scripts à écrire, intégration très faible avec le serveur, …).

Dans ce contexte et au vu des évolutions des technologies et frameworks du Web ces dernières années, le développement d'applications conséquentes nécessitait de nouveaux outils plus flexibles et mieux adaptés à ces nouveaux besoins.



5.2Composants

A l'heure où la notoriété des langages est principalement évaluée à travers leur utilisation dans les technologies du Web, Perl a su proposer un grand nombre de librairies pour s'adapter à ces nouveaux usages. L'environnement de développement HTML::Mason est une illustration parfaite des possibilités offertes par l'intégration de Perl dans Apache au niveau de la gestion des contenus dynamiques.



Figure 12: Composants Mason

A la manière de mod_php, l'activation de Mason permet l'utilisation de séquences Perl dans le contenu des documents servis par le serveur. L'ajout de code Perl dans une page existante ne nécessitent alors plus aucun effort d'adaptation. La première originalité de Mason réside dans la possibilité de décomposer une page en éléments de base appelés « composants ». Chaque composant s'exécute en fonction de paramètres, génère un résultat (sortie de texte) et a la possibilité d'appeler d'autres composants durant son exécution. L'intérêt consiste à décomposer l'ensemble de ces pages en éléments réutilisables afin de faciliter la maintenance (séparation du contenu et du contenant) et d'accroître la modularité de son site. Une page est également un composant Mason au même titre que les éléments qui la composent (Figure 12).



Ce concept peut paraître primaire et il pourrait être assimilé à de simples inclusions si il n'intégrait pas des fonctions avancées permettant au programmeur de contrôler de manière originale le flux d'exécution des composants.





5.3Héritage et gestion dynamique des URL

Le notion d'héritage désigne ici la possibilité pour chaque élément de spécifier un composant « père ». Ce dernier sera systématiquement exécuté lors de l'appel du ou des composants qui en héritent. Lors d'une requête, Mason détermine le composant de base à appeler ainsi que l'ensemble de ses pères pour former la chaine d'exécution. Chaque composant hérite d'un père par défaut nommé « autohandler » se matérialisant par un composant du même nom situé dans le répertoire courant ou l'un des répertoires supérieurs. Ces inclusions automatiques peuvent permettre de gérer le rendu global d'un site mais aussi des phases d'initialisation communes à un sous ensemble de pages. Voici un exemple d'organisation illustrant ce principe d'héritage :



/ # répertoire racine de Mason

/comps/ # répertoire des composants internes (appelés par les composants externes)

/pages/ # répertoires des composants externes => pages accessibles

/pages/autohandler # handler par défaut de toutes les pages

# => rendu global + initialisation (db, ...)

/pages/private/ # répertoire avec restriction d'accès

/pages/private/autohandler # vérification des droits

# => @Ips, User, Horaires d'accès, ...

Parallèlement à cette notion d'héritage, Mason intègre un mécanisme nommé « dhandler » pour la gestion d'URL virtuelles qui ne correspondent pas directement à des composants présents sur le système de fichiers. Avec l'avènement d'AJAX et des interfaces REST (Representational State Transfer), la nécessité d'avoir un contrôle total sur les URL s'avère indispensable. Mason, à travers le concept de « default handler », offre une réponse simple et efficace qui peut servir de point de départ pour une réflexion de gestion dynamique des URL. Dés lors, on se rend compte que Mason n'est pas un simple moteur de « template » mais peut servir de base à la mise en oeuvre d'un framework de développement d'applications web. A titre d'exemple, l'ensemble des frameworks MVC reposent tous sur un système d'aiguillage des requêtes permettant de s'abstraire totalement de la structure physique des répertoires. Un service d'accès aux articles des JRES 2009 pourrait être imaginé comme décrit ci-dessous :

2009.jres.org/articles # Accès au listing complet des articles


2009.jres.org/articles/id_article # Présentation du résumé + liens vers vidéo,publication, ...


2009.jres.org/articles/pres/id_article # Accés aux diapositives de présentation

2009.jres.org/articles/videos/id_article # Accés à la vidéo de la présentation

2009.jres.org/articles/paper/id_article # Accès à la publication de l'article



Une autre solution consisterait évidemment à gérer l'ensemble de ces accès à travers une seule URL associée à des variables passées en paramètres comme cela serait le cas avec un script CGI (ex : 2009.jres.org/articles?id_article=85&type=paper). L'utilisation de ces paramètres peut s'avérer quelquefois complexe et nuit à la navigation.

La première solution, présentée ci-dessus, est en fait la base du principe des applications REST qui repose en partie sur l'utilisation d'URL distinctes pour l'adressage des ressources. REST va encore plus loin en proposant l'utilisation des méthodes standard du protocole HTTP (GET/POST/PUT/DELETE) pour implémenter les fonctions de manipulations des ressources (CRUD : Create/Read/Update/Delete). Beaucoup d'outils de développement répondent aujourd'hui directement à cette problématique. Mason permet, quant à lui, une réponse simple en comparaison de frameworks plus lourds à mettre en oeuvre :

/pages/articles/dhandler # 2009.jres.org/articles

# 2009.jres.org/articles/id_article

/pages/articles/pres/dhandler # 2009.jres.org/articles/pres/id_article



5.4L'environnement Mason

Dans l'environnement mod_perl, la variable globale « $r » est disponible partout dans le code. Cette variable fournit une API d'accès à la requête courante. L'environnement Mason met à disposition une seconde variable globale « $m », permettant entre autre, un contrôle avancé du flux d'exécution des composants. Les appels inter-composants illustrés par la Figure 12 peuvent également être réalisés en utilisant la méthode $m->comp(comp, args...).

La notion d'héritage dans Mason utilise la méthode $m->call_next pour permettre à un père de poursuivre le flux d'exécution à travers ses fils. L'exemple, déjà évoqué, d'un composant vérifiant des droits d'accès en fonction d'expressions régulières sur les fichiers accédés pourrait se traduire ainsi :



%# /pages/private/autohandler

<%perl>

my %authz = ( # Définition des autorisations

login1 => “/[paper|videos]/“,

login2 => “/[pres]/“,

);



my $user = $r->user(); # Récupération du login

if((not defined $user)||(not exists $authz{$user}){ # Vérif. authentification et existence droits

$m->clear_and_abort(401) # NOK => return code 401

}



$expr = $authz{$user}; # Récupération droits (expression régulière)

$rel_path = $r->path_info(); # Récupération du chemin

$m->clear_and_abort(403) if (not $rel_path =~ /$expr/); # Accès non autorisés => code 403

$m->call_next(); # Permet l'exécution du fils

</%perl>

Le flux d'exécution des composants présenté dans la Figure 13 illustre les capacités de Mason à répondre de manière simple et astucieuse à des problématiques variées. Ce schéma reprend les exemples précédents et met en évidence l'utilisation couplée des mécanismes d'héritage et de manipulation dynamique des URL pour la gestion d'accès restreints à des ressources.

Figure 13: Flux d'exécution de composants Mason




Cette brève présentation des concepts forts de Mason n'a pour but que de montrer son intérêt pour le développement d'applications web. Request Tracker (http://bestpractical.com/) est un des nombreux exemples qui témoigne de son utilisation dans des projets de grande envergure. Pour une présentation plus complète le lecteur se référera aux sites suivants : http://www.masonhq.com/, http://www.masonbook.com/.

6Conclusion et notes personnelles

Cet article vient de faire le point sur Apache, mod_rewrite, mod_perl et Mason qui constituent un ensemble d'outils très utiles et complémentaires pour le développement d'applications web « modernes » dans les modèles Web 2.0 et REST.

Dans le cadre de cet article, ces sujets n'ont malheureusement pas pu être plus approfondis (nous reviendrons ! 2). Néanmoins nous espérons que les bases du fonctionnement ont, elles, été correctement détaillées. Ceci est une invitation pour le lecteur à regarder maintenant de plus près tous ces outils pour le développement de ses sites web.

L'équipe réseau LOTHAIRE3 du CIRIL4, qui a en charge l'exploitation, l'administration et la supervision des réseaux lorrains, développe depuis de nombreuses années des interfaces et des applications web à destination de ses correspondants de sites. Les choix et les stratégies sont maintenant clairs et unifiés : toutes les applications doivent être accessibles depuis un navigateur web et elles doivent être implémentées à l'aide des technologies Web 2.0 et REST. Dans ce cadre, les outils utilisés sont bien évidement ceux (entre autres) présentés dans cet article. Après maintenant quelques années d'expériences et de recul, nous sommes de plus en plus convaincus de la pérennité de ces choix. La migration progressive des « anciennes » applications vers ces modèles « plus modernes » simplifie la compréhension du code et des architectures tout en facilitant le développement courant et à venir : « plus on avance, plus c'est facile d'avancer... ».

Depuis maintenant plus de deux ans, l'équipe réseau propose un portail web de réseaux lorrains et des services disponibles : http://reseau.ciril.fr. Ce portail qui unifie l'ensemble des interfaces web (non visibles par un visiteur n'ayant pas de compte CIRIL) est le résultat des migrations et des développements Apache/Perl/... de ces dernières années. Selon nous, la mise à disposition d'un tel portail aurait été très difficile, voir impossible, sans les outils et les concepts présentés dans cet article.

Merci Apache, merci Perl !



1Citation d'Alex, sous sa douche, le mardi 27 octobre 2009 vers 7h12, en pensant à la rédaction de cet article.

2 « I'll Be Back » - Terminator 1 - 1984.

3 http://www.lothaire.net

4 http://www.ciril.fr

13/13 JRES 2009