Expresso

Ceci est une ARCHIVE, peut-être périmée. Vérifiez bien les compatibilités !

Ce plugin permet d’accélérer votre site SPIP a l’aide d’un percolateur constitué d’un cache statique de second niveau servi directement par le serveur Apache

Fonctionnement

Pour être percolée, une page doit contenir la directive
#HTTP_HEADER{X-Expresso: true}

Le plugin fabrique un cache statique de toutes les pages percolées, qu’il stocke dans un repertoire « tmp/cache/apache », et maintient une liste de correspondance (url,fichier).

Pour initialiser l’expresso, il faut ajouter la chaine XXXEXPRESSOXXX dans le fichier .htaccess situé à la racine du site. A cet endroit du .htacess, Expresso intègrera les directives de RewriteRules qui dirigeront l’appel de la page soit vers la page ellemême de temps en temps pour recalculer le cache, soit vers le cache statique correspondant à la page.

A priori, c’est plutôt à la fin du .htaccess qu’il faut insérer ce marqueur, mais pas nécessairement tout à la fin...
Si vous avez les url_standard (canal historique), il faut mettre le marqueur #XXXEXPRESSOXXX juste avant la ligne

RewriteRule ^(rubrique|article|breve|mot|auteur|site|agenda|backend|backend-breves|distrib|forum|ical|plan|recherche|resume|sommaire_texte)\.php3?$	spip.php?page=$1 [QSA,L]

En effet, si des régles expresso pour des articles par exemple, étaient positionnées après ce bloc, elles ne serait jamais utilisées puisque ledit bloc transforme les requêtes ?article.php en requêtes ?spip.php

Les rewriterules intègrent une condition temporelle afin de répartir le service entre Apache et SPIP : c’est le percolateur qui appele les fichiers du cache, mais laisse tout de même passer une petite partie des requêtes à SPIP pour assurer la mise à jour des pages expirées.

Cette proportion de requêtes qui va vers le cache peut être spécifiée entre 0 et 60. Il faut pour cela modifier le fichier « expresso_pipeline » à la racine du plugin. Pour une valeur de 0, le cache statique est désactivé, pour 60, tous les appels renvoient la page en cache : il n’y a plus aucun appel à PHP, mais la page n’est plus jamais raffraichie !

La gestion de ce poursoixantage se fait quasi-aléatoirement sur la base de la valeur de la seconde à laquelle la page est appelée (d’où l’intervalle 0-60), et donc la proportion est approximative. Mais pour une page qui est beaucoup appelée (cas le plus intéressant pour un cache statique), statistiquement, ça doit être vite très approchant de la proportion ciblée.

Ce qu’on peut vérifier quand ça marche :

Le cache statique n’est jamais servie à un admin. Pour tester, il faut donc supprimer le cookie de liaison et vous déconnecter de la partie privée, et charger les pages jusqu’à ce que le délais de recalcul soit atteint et provoque l’écriture dans le htaccess... Ou alors attendre que les utilisateurs aient eux même provoqué cela !

On voit, dés les premiers appels des pages, les fichiers caches se fabriquer dans /local/apache

Par ailleurs, le fichier de log /tmp/boost.log mémorise les derniers caches statiques créés.

Après un certain temps dépendant de la valeur de la directive #CACHE spécifié dans vos squelettes, le htaccess est modifié et intègre la rewriterule qui appelle le cache.

Ensuite, on peut consulter les headers http des pages, par exemple avec l’option du plugin webdeveloper de Firefox. Ces headers sont différents sur les pages sans expresso, sur les pages percolées mais servi par le php, et sur les pages percolées servies à partir du cache statique :

-  le header des pages non percolées contient notamment : X-Spip-Cache: 86400 (par exemple). Elle contient également l’indication du php : X-Powered-By: PHP/4.4.7 par exemple, ainsi que, si le service est gzipé : Content-Encoding: gzip.

-  le header des pages percolées mais servies par php (par exemple parceque vous êtes admin, ou parceque c’est un moment de recacul du cache) contient en plus :
X-Expresso: true. (et, autre différence : il n’y a plus de gzip )

-  le header d’une page percolée et servie directement à partir du cache statique est différente : il n’y a plus l’indication que la page est servie par php, et il n’y a plus le header x-expresso.

Ces petites différences permettent de tester et vérifier si ça marche...

Statistiques de fréquentation

Les statistiques SPIP d’une page percolée ne sont pas du tout valables puisque SPIP n’en voit passer qu’une faible part.

Par contre, les statistiques utilisant des marqueurs externes, comme Xiti ou GoogleAnalytics, continuent à marcher.

Exemples d’appel

Il est possible d’appeler Expresso sur toutes les pages d’un site, mais si vous en avez beaucoup, cela va encombrer le .htaccess. Alors il est préférable de ne l’appeler que pour les pages les plus appelées.

Si vous voulez percoler la page sommaire, il suffit de rajouter la balise en début du squelette sommaire.

Si vous voulez percoler certains articles, vous pourrez vous servir d’un mot clé à usage technique qui sera testé dans une boucle :

<BOUCLE_percole(ARTICLES){id_mot=19}{id_article}> 
#HTTP_HEADER{X-Expresso: true}
</BOUCLE_percole>

Cela aura cependant l’inconvénient que non seulement l’appel à la page sera percolée, mais aussi tous les appels secondaires qui passent par ce même squelette (par exemple : les paginations suivantes, les appels de forums ou de document, ...). Pour ne pas encombrer le .htaccess par ces pages secondaires peu visitées, il est souhaitable de les éliminer en testant les paramétres de l’url :

<BOUCLE_percole(ARTICLES){id_mot=19}{id_article}> 
    [(#EVAL{_request('debut_forums')}|?{'',' '}) 
        [(#EVAL{_request('id_document')}|?{'',' '}) #HTTP_HEADER{X-Expresso: true} ] ]
</BOUCLE_percole>

Pour le squelette des pages rubriques, il faudra en plus tester la pagination des breves, des articles et des sites ... (debut_breves, debut_articles, debut_sites... )

Si les conditions à tester sont trop nombreuses, il faudra définir un filtre pour les tester, car la grammaire spip ne permet pas les imbrications d’une trop grande complexité.

Un autre mécanisme de test pourrait être défini pour non pas exclure les pages parasites, mais ne retenir que LA page souhaitée. C’est d’autant plus souhaitable que des tas de programmes ou de sites sur internet appellent des pages de votre site, avec des paramétres dont vous avez vraiment pas idée... et que chacun de ces appels encombre inutilement le .htaccess

Pour ne retenir donc que les bonnes pages, vous pourrez utilement utiliser ce filtre qui teste le nombre de variables passées dans l’url :

function isgetokexpresso($texte, $cool=2)
{
//  count ($_GET) vaut basiquement 2 car après les redirections url_propre, on se trouve dans une page appelée par spip.php avec 2 parms : le nom de la page (article ou rubrique) et la valeur id_article ou id_rubrique
  return (count ($_GET)==$cool ? " " : "");
};

et l’appel donne quelquechose comme ça :

<BOUCLE_expresso(ARTICLES){id_mot=19}> 
    [(#NOOP|isgetokexpresso) #HTTP_HEADER{X-Expresso: true} ]
</BOUCLE_expresso>

Pour la page d’accueil (squelette : sommaire.html), il n’y a pas d’autres parametre que le nom de la page (=sommaire), donc l’appel se fera différemment :

[(#NOOP|isgetokexpresso{1}) #HTTP_HEADER{X-Expresso: true} ]

Attention

Les statistiques spip des articles percolés sont très très sousévaluées puisque seule une faible partie des pages appelées passent par spip. Les mesures statistiques sont donc fausses, ainsi que signalé précédemment.

On ne pourra donc pas utilement passer par une boucle SPIP testant la popularité des pages pour sélectionner automatiquement les pages percolées...

Test d’usage

-  test en situation de crise :

Expresso a déjà démontré ses capacités sur un pic d’audience, cf. spip-blog.net/SPIP-tient-la-route

Sur le graphe, les vides signalent que le serveur était tellement chargé que le monitoring, non prioritaire, n’a pu avoir lieu. Mais le site a tenu le coup et servi les pages demandées.

-  mesures :

Selon les mesures réalisées par l’hébergeur Lixium pour le site Passerelle Eco , la ressource CPU mobilisée pour le service d’une page percolée est de 100 fois inférieure
à celle requise pour une page non percolée. Sur ce site, les 30 pages les plus consultées, générant 70% du traffic sont percolées au moyen de boucles qui les sélectionnent en utilisant le filtre isgetokexpresso ci dessus. L’économie pour le CPU est significative.

Auteurs

Auteur du plugin : Cédric Morin http://www.yterium.net/
© 2007 - Distribué sous licence GNU/LGPL

Discussion

7 discussions

  • 5

    il faut bien recopier XXXEXPRESSOXXX tel quel,
    au bon endroit dans le htaccess.

    • et alors en ce cas, quel est le bon endroit lorsque l’on utilise les URL propres ?

      Parce qu’en le plaçant tout à la fin je suis toujours en erreur sur l’ensemble du site ???

      Merci de vos retours.

      Etienne.

    • Bonjour
      Tout ça a l’air très chouette... le site que je rénove tourne chez APINC avec spip2.0.10 et php5.
      Je voudrais vous poser des questions à propos du rafraichissement des pages.
      ... suis-je petit joueur dans la cour des grands... ;-)
      pour 40 à 80 visites par jour, le jeu en vaut la chandelle ? si on ajoute un article, combien d’heures, de jours ? de visites ? pour qu’il apparaisse en ligne ?
      J’ai pas bien compris le poursoixantage par rapport aux 60 secondes. La page serait-elle rafraichie à la 10e visite par seconde si on a mis 10 poursoixante ?
      le plug-in est-il compatible avec spip2.0.10 ?
      à part pour les versions de spip, je suis pas sure de faire la distinction entre les trois solutions techniques proposées ici (cache cool, fastcache et expresso)
      merci d’avance, si le temps ne vous est pas trop compté...

      http://www.theatrecroquemitaine.com

    • Cache Cool est la solution la plus simple à déployer et qui suffit largement pour le trafic que vous avez à gérer. Par ailleurs Expresso n’a pas été mis à jour pour SPIP 2.0.

      A noter que les trafics dont on parle ici sont de l’ordre de plusieurs dizaines de millier de visiteurs par jour.

    • > A noter que les trafics dont on parle ici sont de l’ordre de plusieurs dizaines de millier de visiteurs par jour.

      ooops... mais merci du conseil !

    • Pour info, sur un site qui n’avait que 3 à 5 milliers de visiteurs, EXPRESSO ciblé sur les 40 pages les plus fréquentées a été TRES apprécié par l’hébergeur (mutu), en son temps. Maintenant cache-cool fait le boulot tout pareil et sans les soucis occasionnels de corruption du htaccess.

    Répondre à ce message

  • 1

    En plaçant XXXEXPRESSOXXX dans la page .htaccess, arrive aussitôt la page « Erreur 500 » sur mon site. D’où vient le souci ?
    D’ailleurs, quels sont les paramètres pour le .htaccess : 775 ou autre ? et quel .htaccess doit être paramétré si on a placé l’admin spip dans un sous dossier du site ? à la racine ou dans ce sous-dossier.
    -  NB : pour avoir testé les 2, le résultat est le même : Erreur 500…
    -  NB2 : Les #HTTP_HEADERX-Expresso : true sont bien placés sur certaines pages, le plugin installé, la version de Spip 1.9.2.d…
    -  NB3 : L’objet est de diminuer la consommation du CPU après plusieurs suspensions par site5.com et avant de me faire exclure définitivement…

    Christophe / www.seasailsurf.com

    • Erreur 500, j’ai la même à la maison et je ne sais pas d’où cela vient.

      Mais la syntaxe du XXXEXPRESSOXXX me laisse perplexe... pour une directive de .htaccess. Faut-il vraiment le copier/coller tel quel ou bien doit-on remplacer quelque chose genre XXX par ... ???

      Quelqu’un peut m’éclairer ?

      Merci.

    Répondre à ce message

  • 7

    Quele est la différence avec le Fastcache ?

    • Expresso confie le service des pages html en cache à Apache uniquement (sans php), mais necessite pour cela un droit d’écriture sur le .htaccess et le droit d’utiliser les RewriteRules.

      Il est théoriquement mieux adapté aux hebergements pour lesquels php n’est pas rapide.

    • Si je comprends bien, l’utilisation de ce plugin (on le télécharge où, d’ailleurs ?) dépend du serveur sur le quel on pose le site. Cela serait-il possible de savoir avec quels serveurs d’hébergement il peut fonctionner ? OVH ? Céléonet ? 1&1 ?...

      Merci beaucoup !

    • Cedric ? Qu’entends tu par « php pas rapide » ? Quels sont les critères à observer ? Comment déterminer qu’expresso sera bien la meilleure méthode face à fastcache ?

      Sinon point de vue perso, mais je n’ai rien compris à la doc :)

    • Je crois qu’on ne le télécharge pas. Comme la plupart des plugs en dev, ou en test, on le récupère, soit via SVN soit en allant copier/coller les fichiers dispos sur le trac de spip-zone : http://trac.spip.org/trac/spip-zone/wiki/LesPlugins

    • Pardon ! erreur sur l’adresse, c’est bien là http://zone.spip.org/trac/spip-zone/ que ca se passe et pas ailleurs ;)

      PS : Crayon déconne sur les forums ou c’est mon FF3/linux qui n’a rien compris à la vie ???

    • je pense qu’il y a un problème avec crayon sous ff3

      à+
      joz

    • Ben en fait, pas sûr. Je l’utilise quotidiennement sur d’autre sites sans que ca pose problème.

      Mais là on est peut être face à une version du plugin un peu hybride (à cheval entre spip1.9.2 et Spip 2.0) et qui plus est, se trouve implémenté dans un cadre (l’édition de forum) qui est loin de lui être natif pour les dernières versions que j’en connais donc... ;)

    Répondre à ce message

  • Il me semble qu’on peut optimiser le htaccess généré en rassemblant au début du ###EXPRESSO### les rewriteconds constantes qu’il est alors inutile de répéter pour chaque page.

    Pas testé mais dans ce cas, c’est quelquechose dans le genre qu’il faudrait écrire une seule fois au début :

    RewriteCond %{HTTP_HOST} !^www.monsite.info$
    RewriteRule .* - [L]
    
    RewriteCond %{REQUEST_METHOD} POST
    RewriteRule .* - [L]
    
    RewriteCond %{HTTP_COOKIE} ^.*spip_(admin|session)=.*$
    RewriteRule .* - [L]

    Bonne idée à coder ou mauvaise idée à jeter ?

    Répondre à ce message

  • 5

    Bonjour,

    J’ai mis le header sur le squelette sommaire, en 2e ligne juste après le cache. (la position dans le squelette ne semble pas avoir d’importance selon l’article).

    Les droits sur .htaccess sont corrects a priori.

    Je me suis connecté avec un autre navigateur sur lequel je ne suis pas admin (car il me semble que expresso ne fait rien pour les admins, non ?), et j’ai visualisé plusieurs fois la page.

    Un répertoire local/apache a bien été créé, et un fichier cache dedans avec un nom à la md5dehors dedans. Cela indiquerait que Expresso fait son boulot, mais le htaccess est inchangé... (sans ###expresso### et donc a priori la page statique n’est pas appelée)

    Y a t il quelquechose que j’ai oublié de faire ?
    Y a t il un moyen d’affiner le diagnostic ?

    • J’ai continué à explorer le plugin et son code ... ce qui m’a donné l’idée qu’il fallait peut être « initialiser » le plugin en ajoutant

      ###EXPRESSO###
      ###/EXPRESSO###

      à l’endroit où devaient être insérées les rewriterules dans le .htaccess.

      Puis je suis passé à autre chose, et quand je suis revenu, le htaccess avait été modifé
      et intégrait cette fois les rewrites rules attendues.

      Donc !

      Il est donc possible, mais pas sur non plus (car sait-on jamais c’est peut être juste qu’il faut du temps pour qu’il se passe quelquechose ?), qu’il faille initialiser ainsi le plugin.

      Si on me dit que c’est bien ça je l’ajouterai volontier à la doc !

      En tout cas, à ce moment, je remarque qu’il n’y a plus x-expresso true dans les headers de la page servie. C’est un bon indice que ça marche !!

      A part ça, rien que pour le sommaire, il y a 9 rewrite rules générées (2 pour index.php ; 2 pour index.php3, 1 seule pour sommaire.php qui regroupe les 2, 2 pour sommaire.php3 et 2 pour le ndd sec sans fichier demandé. Chacune avec ses 5 rewrite conds, (6 pour celle qui regroupe les 2).
      genre ça donne :

      RewriteCond %{HTTP_HOST} ^www.monsite.info$
      RewriteCond %{REQUEST_METHOD} !POST
      RewriteCond %{HTTP_COOKIE} !^.*spip_(admin|session)=.*$
      RewriteCond %{QUERY_STRING} ^$
      RewriteCond %{TIME_SEC} >57
      RewriteRule ^index\.php3$ local/apache/89d3dcb5cc4703d915b6214366bfd71b.html [L]

      Et ça fait 5 fichiers caches générés correspondants aux différents appels possible du sommaire et à chaque groupe de rewriterule.

      Cette surabondance est liée au fait que le site utilise les urls historiques (« url_standard » je crois).

      Je pense qu’il est possible d’optimiser cela et j’envisage 2 pistes :
      -  en ramenant toutes les urls appelées à un seul modèle ou 2 (vérifier dans le source comment c’est appelé)
      -  peut être en déplaçant l’insertion de ###EXPRESSO### plus loin dans le htaccess, pour qu’il ne soit plus sollicité qu’une fois les redirections faites...

      Les conseils du concepteur et autres retours d’expérience sont bienvenus !

    • J’ai maintenant réécrit presque complètement le htaccess avec plus de [R=301] pour rediriger vers les adresses canoniques en php (en général), et index.php et sommaire.php vers / tout court (« une seule adresse par page » !).

      Et j’ai mis le ###EXPRESSO### après tout cela (ça suffit, pas la peine d’ajouter ###/EXPRESSO### en fait !).

      Un seul fichier cache se recrée maintenant dans local/apache. Ce fichier, c’est bien la page d’accueil, avec un « expresso » xx-small ajouté tout à la fin avant le </body> mais qui n’apparait pas à l’écran.

      A partir de là, il se passe rien pendant un certain temps. Je comprend pas cette latence. J’appelle la page sous tous ses noms, il se passe rien, et puis à un moment le site se fige, tout ralentis, peut être un hasard ? en tout cas après, le .htaccess est finalement modifié, et il y a un ensemble de 5 fois 2 rewrite rules accompagnées de leurs conds (index.php et php3, sommaire.php et php3, et ^$). Chacun de ces groupes de 2 a son propre fichier cache, mais seul réellement appelé existe : pour ^$. La manip de tout ramener à une seule adresse a bien réussi en ce qui concerne les apparence mais ça ne simplifie pas le htaccess de expresso...

      A part ça ya un fichier de log boost.log

      Et enfin, quand la page affiche le fichier caché, le gzip n’a pas l’air appliqué car ça n’apparait pas dans les entêtes (contrairement à quand ça passe pas par le cache).
      c’est un peu dommage ça non ?

      enfin, c’est mon hébergeur qui va être content ! Il disait en gros que ça divisait par 2 la consommation CPU sur les sites qui l’utilisent !!!

    • La mise en cache expresso ne se fait qu’au calcul de la page, c’est à dire lorsque le cache spip est expiré. La latence doit venir de cela.

      Il faut bien le ###EXPRESSO### dans le htaccess, cela permet de maitriser ou insèrer les rewrite rules.

      Si ton hébergeur connait des sites qui l’utilisent cela serait sympa de les signaler, car à part toi, je n’ai eu aucun retour d’essai du plugin, et des gains en fonction des configs serveurs.

    • ok je te tiendrai au courant.

      là, j’ai donné un corps à l’article.

      En ce qui concerne mon site, j’ai mis expresso sur une vingtaine de pages, en ajoutant le header de manière conditionnelle dans le squelette. J’espèrais que cela fasse 200 lignes ajoutées au .htaccess, mais en pratique, il y en a bien plus car il y a toutes les variations de la page (notamment avec la pagination sur les forums).

      Ce serait bien que expresso ne cache que la page principale et pas les variantes avec « &debut_forums » dans la query ce qui fait des groupes de régles avec des lignes comme ça dans le htaccess :RewriteCond %{QUERY_STRING} ^id_article=101&amp;debut_forums=20$
      alors que je veux pas nécessairement que ces variantes des pages soit percolées...

      Comme cela dépend de chaque squelette, il faudrait pouvoir paramétrer les chaines à détecter dans l’url pour décider de ne pas mettre en cache... Je peux aussi le faire en modifiant les conditions d’insertion du header dans le squelette. Je sais pas ce qui serait le mieux.

      Actuellement, sans ce paramétrage plus fin, au lieu des 200 lignes, ce sont 700 lignes qui ont été ajoutées dans le htaccess (pour le sommaire, 12 articles et environ 8 rubriques). Je me demande quel est le surcout serveur d’un htaccess de 700 lignes ?

      Et ça invite à optimiser les rewriteconds ajoutées :

      ordre actuel :

      RewriteCond %{HTTP_HOST} ^www.monsite.info$
      RewriteCond %{REQUEST_METHOD} !POST
      RewriteCond %{HTTP_COOKIE} !^.*spip_(admin|session)=.*$
      RewriteCond %{QUERY_STRING} ^id_article=101&amp;debut_forums=20$
      RewriteCond %{TIME_SEC} >15
      RewriteRule ^article\.php$ local/apache/f35e6a550e7ad92c56d4744b8532f841.html [L]

      Notamment : est-ce l’ordre suivant ne serait pas plus efficace : voici une proposition où je met les conditions les plus restrictives en premier :

      RewriteCond %{QUERY_STRING} ^id_article=101&amp;debut_forums=20$
      RewriteCond %{TIME_SEC} >15
      RewriteCond %{HTTP_HOST} ^www.monsite.info$
      RewriteCond %{REQUEST_METHOD} !POST
      RewriteCond %{HTTP_COOKIE} !^.*spip_(admin|session)=.*$
      RewriteRule ^article\.php$ local/apache/f35e6a550e7ad92c56d4744b8532f841.html [L]

      et puis j’ai l’impression que dans mon cas on peut supprimer la

      RewriteCond %{HTTP_HOST} ^www.monsite.info$

      peut être même assez souvent, non ?

    • de temps en temps ya un chti bug dans les calculs de création du htaccess
      car il y inscrit :

      RewriteCond %{TIME_SEC} >-1
      RewriteCond %{TIME_SEC} <51

    Répondre à ce message

  • Les stats de spip sont elles actualisées pour une page expressoée ou bien les pages expresso sont elles invisibles des stats spip ?
    et qu’en est-il des marqueurs xiti ou googleanalytics ?

    Répondre à ce message

  • 2
    Jean-Michel

    Bonjour,

    Je ne trouve pas de lien pour télécharger « Expresso », où puis-je télécharger ce plugin stp ?

    • Gilles Vincent

      Expresso est dans cette archive des plugins en cours de développement :
      http://miroirspip.ventre.name/build...

      (mise à jour quotidiennement)

    • Certes, mais sous quel nom Expresso se trouve-t-il dans cette archive ? Car, sur ton lien, une fois décompressée, je trouve plein de plugins dans l’archive, mais pas Expresso...

    Répondre à ce message

Ajouter un commentaire

Avant de faire part d’un problème sur un plugin X, merci de lire ce qui suit :

  • Désactiver tous les plugins que vous ne voulez pas tester afin de vous assurer que le bug vient bien du plugin X. Cela vous évitera d’écrire sur le forum d’une contribution qui n’est finalement pas en cause.
  • Cherchez et notez les numéros de version de tout ce qui est en place au moment du test :
    • version de SPIP, en bas de la partie privée
    • version du plugin testé et des éventuels plugins nécessités
    • version de PHP (exec=info en partie privée)
    • version de MySQL / SQLite
  • Si votre problème concerne la partie publique de votre site, donnez une URL où le bug est visible, pour que les gens puissent voir par eux-mêmes.
  • En cas de page blanche, merci d’activer l’affichage des erreurs, et d’indiquer ensuite l’erreur qui apparaît.

Merci d’avance pour les personnes qui vous aideront !

Par ailleurs, n’oubliez pas que les contributeurs et contributrices ont une vie en dehors de SPIP.

Qui êtes-vous ?
[Se connecter]

Pour afficher votre trombine avec votre message, enregistrez-la d’abord sur gravatar.com (gratuit et indolore) et n’oubliez pas d’indiquer votre adresse e-mail ici.

Ajoutez votre commentaire ici

Ce champ accepte les raccourcis SPIP {{gras}} {italique} -*liste [texte->url] <quote> <code> et le code HTML <q> <del> <ins>. Pour créer des paragraphes, laissez simplement des lignes vides.

Ajouter un document

Suivre les commentaires : RSS 2.0 | Atom