Catégorie : apache

Zeemoz : créer un nouveau module C pour Apache

Aller dans le répertoire des sources, et taper :

/opt/httpd-2.2.4/bin/apxs -g -n modulenouveau

Il va créer un répertoire ./modulenouveau et à l’intérieur les fichiers Makefile et mod_modulenouveau.c, qui contient le squelette du code tel qu’attendu par Apache.
Ensuite il ne reste qu’à remplir.
Pour le script d’installation, il n’y a qu’à copier /usr/bin/modsearch_install.sh en modmodulenouveau_install.sh et modifier uniquement les variables $SOURCES et $MOD.

Les filtres Apache

Il existe plusieurs filtres, qui sont passés dans l’ordre lorsqu’ils arrivent au serveur, puis sont passés exactement dans l’ordre inverse lorsqu’ils repartent vers le client (un seul m’intéresse, le premier : à l’arrivé ce sont les filtre d’entrée, et lorsque cela repart ce sont les filtres de sortie) :

  1. AP_FTYPE_RESOURCE
    Pour les filtres de contenu : cela englobe tous les types de filtres qui peuvent modifier le contenu, cela va de la décomposition de pages XML qui arrivent, à la transformation d’images ou encore à l’assemblage de contenu qui arrive en plusieurs fois. Ce type de filtre peut changer complètement la nature du contenu de la requête. Par exemple, un filtre XSLT peut transformer le contenu d’une page XML en une page HTML ou en un fichier PDF ;
  2. AP_FTYPE_CONTENT_SET
    C’est la seconde étape du filtrage du contenu, qui est principalement destinée à empaqueter le contenu, par exemple le module mod_deflate (qui applique une compression de type gzip) ;
  3. AP_FTYPE_PROTOCOL
    Le troisième filtre, : le filtre habituel a pour fonction d’insérer les entêtes HTTP au début des données qui ressortent des filtres de contenu. C’est réalisé par un filtre intégré nativement à Apache : le filtre HTTP_HEADER(la fonction ap_http_header_filter exactement), donc les applications, en général, l’ignorent.
  4. AP_FTYPE_TRANSCODE
    On s’en tape, ça ne sert pratiquement jamais.
  5. AP_FTYPE_CONNECTION
    On s’en tape, ça ne sert pratiquement jamais.
  6. AP_FTYPE_NETWORK
    On s’en tape, ça ne sert pratiquement jamais.

Le redirection interne

Il est possible dans Apache, lors de la gestion de la requête, de faire une redirection interne, c’est à dire de faire croire qu’il y a eu une redirection, mais au lieu de la renvoyer au client, et que le client demande la nouvelle URL, elle est faite en interne. Pour pouvoir faire cela, deux possibilités :

  1. Location: http://olivier.pons.free.fr/apache/
  2. Location: /apache/

La première est basée sur la nature double de l’entête Location d’un script CGI : elle force à envoyer une redirection au client, alors que la seconde fait une redirection en interne, sans envoyer quelque chose au client.

Seule la seconde possibilité nous intéresse. Il est possible de le faire de deux façons dans un module :

  1. void ap_internal_redirect(
      const char *new_uri, request_rec *r)
    .

    Cette forme de redirection interne est le mécanisme à utiliser dans tous les cas à de rares exceptions près. Cette fonction crée un nouvel objet requête pour l’URL passée en paramètre, et lance la nouvelle requête comme si new_uri avait été demandée en premier lieu.

  2. void ap_internal_fast_redirect(
      request_rec *new_req, request_rec *r)

    Cette fonction clone une structure existante new_req dans la requête en cours afin de pouvoir mettre en place une nouvelle requête et simuler le fait qu’on lui passe le contrôle. Ce mécanisme est parfois utilisé pour promouvoir une sous-requête en requête principale. Ce qui est important de noter c’est qu’on ne repart pas de zéro, donc on ne refait pas complètement la requête.

Dix façons de devenir un meilleur développeur PHP

Les 5 premiers conseils viennent d’ici

Les 5 conseils suivants venaient de ce lien d’http://www.hackingajax.com/2008/02/13/5-more-ways-to-be-a-better-php-developer/ mais il est mort…

Souvent, un développeur PHP inexperimenté va sauter sur IRC et poser une question sur Freenode##php. Et si la question est facile, il aura une réponse rapidement. Au début. Parce que par la suite, il va être bombardé de réponses du style « LOL », « ROFL », « Va apprendre PHP et reviens », « Vas te documenter un minimum », « On n’est pas ton prof personnel », etc. Donc, comment devenir un meilleur développeur PHP ? Dans ce post, je vais mettre en avant cinq façons d’être un meilleur développeur, d’être plus productif, d’écrire moins de code et de faire ainsi plus de choses avec vos applications web. Il y a toujours quelque chose de nouveau à apprendre quand on parle de développement PHP. Nouvelles fonctions internes, nouveaux frameworks, nouveaux design patterns, nouveau styles de documentation. Ci-suivent quelques-unes des façons les plus efficaces pour vous aider à être un meilleur développeur PHP.

  1. Lisez le manuel
    Je ne le dirai jamais assez : c’est là qu’il faut regarder en premier et il y a des tonnes de choses à apprendre simplement en lisant le manuel. Les problèmes les plus courants sont déjà résolus si vous lisez ce qui concerne les chaines de caractères (string), et les tableaux (array). Il y a plein d’exemples qui fonctionnent directement accessibles, et souvent, rien qu’en parcourant le manuel vous allez vous rendre compte que vous êtes en train de ré-inventer la roue, parce qu’une fonction que vous voulez faire existe déjà et, mieux, elle est directement d’origine dans PHP ! Le manuel PHP est votre ami. Note d’Olivier : une petite astuce supplémentaire : si vous voulez chercher quelque chose, il vous suffit de taper : php.net/[mot à chercher] et même si PHP ne le connait pas il vous donnera une liste de mots approchants ! Génial non ?
  2. Balladez vous dans le code d’autres personnes
    PHP a plein de code open source. Pourquoi ne pas apprendre grâce à ça ? Récupérez une application PHP open source et jetez un coup d’oeil dans le code. Les plus gros projets sont sûrement meilleurs, car, même s’ils auront des structures plus complexes, ils auront des systèmes fonctionnels mais derrière tout ça une documentation détaillée qui explique tout. Visitez SourceForge.net si vous n’arrivez pas à trouver un point de départ.
  3. Apprenez un nouveau framework
    Il y a plus de frameworks PHP que vous n’avez eu de diners galants qui se sont bien terminés (!) ; la plupart sont open source et disponibles en ligne si vous savez où regarder. Essayez les principale, par exemple phpframeworks.com a une excellente liste. Votre framework ne peut jamais être entièrement complet, votre prochain travail, ou projet, aura besoin de telle ou telle fonctionnalité, ou s’appuiera sur un framework différent et vous trouverez certainement que des idées des autres sont très utiles pour l’un de vos projets.
  4. Recherchez
    Vous avez probablement entendu plein de choses et de mots dans le contexte d’un développement Internet en PHP. En allant de OOP à MVC, en passant par KISS, DRY, YAML, INI, REST, XML-RPC, etc, il y a des centaines de termes techniques et de concepts ici qui pourraient être directement reliés à vos travaux. Peut-être avez-vous déjà une compréhension basique, ou grossière d’eux, mais est-ce que vous savez vraiment en profondeur ce qu’ils signifient pour vous ? Passez un peu de temps à faire de la vraie recherche, apprenez, formez vous un peu dessus. Wikipedia est un bon endroit pour commencer. Vous allez inévitablement apprendre des choses que vous ne connaissez pas, et ça ne peut que vous être profitable.
  5. Apprenez la programmation orientée objet
    C’est un peu lié au point précédent, mais la programmation orientée objet (POO, ou en Anglais, Object Oriented Programming, OOP), est beaucoup plus importante que vous ne pouvez l’imaginer : est-ce que vous connaissez vraiment la POO sur PHP 5 ? Par exemple, est-ce que vous manipulez facilement les classes abstraites, les interfaces, le mot clé implements, les méthodes et propriétés statiques, et les propriétés protected ? Beaucoup de développeurs PHP expérimentés ne sont pas compétents dans ce domaine, et pourtant, si vous utilisez ce genre de caractéristiques propres à la POO, vous construirez certainement des architecture beaucoup plus souples, évolutives, et vous gagnerez par là même beaucoup de temps de développement.
  6. Commencez un projet que d’autres personnes (développeurs et utilisateurs finaux) vont utiliser.
    Vous ne gagnerez jamais autant de respect (ou de dédain) plus rapidement qu’en écrivant un programme pour des étrangers qui doivent se servir de votre code. Que ce soit une application web pour des utilisateurs finaux, ou une extension PEAR pour les développeurs, ou un plugin WordPress pour le bloggeurs, le fait de mettre un logiciel, ou du code entre les mains d’autres personnes de manière à ce qu’elles puissent y réagir est la chose la plus efficace que vous puissiez faire pour devenir un meilleur développeur. Être mis dans la position de devoir répondre aux demandes des uns et des autres est aussi important et valorisant que le lien entre un journaliste et le journal publié. Tous ceux qui l’ont fait vous le diront, ce n’est pas facile mais une fois que vous arrivez à gérer ça, vous saurez écrire en étant sous pression, avec des délais à tenir, et éventuellement sous le feu d’une opinion publique qui peut ne pas être facile. D’ailleurs, écrire un programme en entier de bout en bout n’est pas si différent. Faites votre travail, donnez-le et attendez le retour. C’est cette boucle d’échanges qui fait les bons programmes et les bons développeurs. En fin de compte, c’est peut-être ce fameux feedback qui a principalement de la valeur.
  7. Apprenez un autre langage.
    Si vous commencez à peine avec PHP, ce n’est peut-être pas le moment de vous plonger dans quelque chose de nouveau, mais si vous connaissez le langage et que vous voulez amélorier vos compétences, vous verrez qu’il y a des avantages à ne pas être spécialisé uniquement dans un seul langage. Par exemple : Java vous oblige à comprendre la programmation orientée objet (P.O.O., en Anglais : O.O.P.), Ruby on Rails vous oblige à apprendre le principe Modèle – Vue – Conteneur (M.V.C.), C# vous oblige à apprendre ce qu’est la dépendance à l’autocomplétion (je blague, C# ne sert à rien, apprenez Java c’est déjà une excellente chose). Le fait d’élargir vos horizons vous offre la possibilité de comprendre comment d’autres langages ont résolu certains problèmes qui ne le sont pas encore, ou pas correctement, en PHP, ou bien qui ne sont pas évidents à résoudre, tout simplement. Par exemple, je vous certifie que je suis devenu un développeur PHP nettement plus compétent depuis que j’ai écrit un peu plus de 7,500 lignes de code pour Ruby on Rails. Apparemment, je ne suis pas le seul.
  8. Apprenez un autre langage à quelqu’un.
    Rien ne vous fait mieux apprendre que d’apprendre à quelqu’un d’autre. N’importe quelle personne qui est vraiment intéressée par ce que vous apprenez va inévitablement vous posez des questions sérieuses, des questions précises, des colles que vous aurez du mal à surmonter au début, mais qui vont vous amener à un degré de connaissance du langage insoupçonnable. Et puis au moins vous aurez un autre angle de vision sur ce qu’est la patience, lorsque vous aurez à répondre pour la vingtième fois à « Au fait, vous pourriez ré-expliquer ce qu’est une variable ? ». J’ai appris le langage Python à mon fils, récemment, après n’y avoir pas touché pendant 5 ans. C’était une expérience très intéressante pas uniquement dans le sens où j’ai réalisé à quel point j’avais tout oublié de Python mais surtout dans la manière de programmer qui est différente. Quand vous réussissez à apprendre à des jeunes de 13 ans pourquoi vous devez transformer des entiers avant de pouvoir les concaténer à des chaines de caractères en Python et pourquoi ce n’est pas nécessaire en PHP — et qu’il le comprennent — vous aurez d’ici là appris énormément de choses et vous serez forcément devenu un meilleur développeur.
  9. Demandez des suggestions et des solutions
    Si jamais vous n’arrivez pas à vous décoller d’IRC, assurez vous que vous avez vraiment recherché dans tous les sens la résolution d’un problème avant de demander de l’aide. Et lorsque vous demandez, montrez votre code. Si vous montrez que vous avez essayé quelque chose et que vous avez fait déjà un bon paquet d’efforts, croyez moi, vous aurez beaucoup plus facilement des réponses à vos questions.
    Vos question devraient ressembler plutôt à « je pense qu’ici je fais quelque chose qu’il ne faut pas, pouvez-vous m’aider » plutôt que « pourriez vous faire le travail pour moi. »
  10. Utilisez ce que vous lisez.
    Que dire de plus que cette loi de programmation simple, cardinale et fondamentale :
    C’est toujours plus dur de lire du code que de l’écrire. (Joel Spolsky) ?
    Après ces deux conseils de Lisez le manuel et Balladez vous dans le code d’autres personnes, vous allez apprendre beaucoup de choses, mais il ne suffit pas que de lire. Il faut aussi écrire. Vous ne pouvez pas lire 100 livres faits par des gens talentueux et pondre juste après Le Seigneur des Anneaux en une nuit. Ne faites pas que parcourir le code, utilisez le aussi dans le votre. Eventrez CakePHP et regardez comment ils gèrent la validation des formulaires. Ecartelez HTML_QuickForm2 et utilisez sa création d’éléments. Comprenez comment WordPress gère les transactions de sa base de données, et comparez avec Drupal. Ce sont toutes les choses que votre application, à un moment ou à un autre, devra pouvoir réaliser, donc vous devriez vraiment jeter un coup d’oeil et essayer de voir comment les autres ont résolu les problèmes auxquels vous êtes confronté. Et quand c’est adéquat, et légal, utilisez leur code. Vous apprendrez incroyablement plus si vous devez prendre un morceau de code, et le modifier afin qu’il fonctionne dans votre application que si vous ne faite que lire les branches SVN du projet.

Directive directory

<Directory [répertoire]> et </Directory> sont utilisées pour encadrer un groupe d’instructions qui vont être appliquées sur le répertoire et les sous-répertoires de ce répertoire.

On peut mettre n’importe quelle instruction tant que c’est une instruction « pour répertoire ». Dans tous les cas, [répertoire] est :

  • soit le nom complet du répertoire concerné (sans le slash final) ;
  • soit une expression régulière simple (que des ?, * ou []) (je n’entrerai pas en détail ici).

Exemple :

<Directory "/var/www/cgi-bin">
  AllowOverride None
  Options None
  Order allow,deny
  Allow from all
</Directory>

AllowOverride : All|None|directive-type [directive-type] ..

On précise quelles sont les directives autorisées dans le fichier .htaccess.

Voici en fonction de ce que l’on met, le résultat :

  • None : Les fichiers .htaccess sont complètement ignorés
  • All : Toutes les directives possibles dans un contexte .htaccess sont prises en compte
  • AuthConfig : Autorise les directives d’autorisation (!) à des utilisateurs (AuthDBMGroupFile, AuthDBMUserFile, AuthGroupFile, AuthName, AuthType, AuthUserFile, Require, etc.).
  • FileInfo : Autorise les directives qui controllent les types des documents (DefaultType, ErrorDocument, ForceType, LanguagePriority, SetHandler, SetInputFilter, SetOutputFilter, et les directives du mod_mime Add* et Remove*, etc.), données méta de document (Header, RequestHeader, SetEnvIf, SetEnvIfNoCase, BrowserMatch, CookieExpires, CookieDomain, CookieStyle, CookieTracking, CookieName), directives mod_rewrite RewriteEngine, RewriteOptions, RewriteBase, RewriteCond, RewriteRule) et Action du module mod_actions.
  • Indexes : Autorise les directives qui controllent l’indexation de répertoire (AddDescription, AddIcon, AddIconByEncoding, AddIconByType, DefaultIcon, DirectoryIndex, FancyIndexing, HeaderName, IndexIgnore, IndexOptions, ReadmeName, etc.).
  • Limit : Autorise les directives qui controllent les accès « hôtes » (Allow, Deny et Order).
  • Options[=Option,...] : Autorise les directives qui controllent des particularités des répertoires (Options et XBitHack).

Order : Allow,Deny / Deny,Allow

La directive Order, lorsqu’elle est accompagnée des directives Allow et Deny, sert pour un système de contrôle en 3 passes.

  1. On passe au travers d’une des deux directives (Allow ou Deny)
  2. On passe ensuite l’autre directive (Deny ou Allow)
  3. Enfin on applique la 3ème passe pour toutes les requêtes qui n’ont correspondu ni à la première ni à la seconde

Notez bien que toutes les directives Allow et Deny sont appliquées, à l’inverse d’un pare-feu où, dès qu’il y a correspondance, on s’arrête. La troisième passe aussi est appliquée. En conséquence, l’ordre dans lequel les lignes de configuration apparaissent importe peu : toutes les directives Allow sont mises en un seul groupe, et toutes les directives Deny dans un autre. Les ordres possibles sont :

  1. Allow,Deny
    1. Toutes les directives Allow sont appliquées. Au moins l’une doit correspondre sinon la requête est rejetée.
    2. Ensuite, toutes les directives Deny sont appliquées. Si l’une d’elles correspond, la requête est rejetée.
    3. Enfin, toutes les requêtes qui ne sont validées ni par Allow ni par Deny sont considérées comme Deny
  2. Deny,Allow
    1. Toutes les directives Deny sont appliquées. Si l’une d’elles correspond, la requête est rejetée à moins qu’à la passe suivante, il y ait correspondance.
    2. Toutes les directives Allow sont appliquées.
    3. Toutes les requêtes qui ne sont validées ni par Allow ni par Deny sont considérées comme Allow
Validation : Résultat sur Allow,Deny Résultat sur Deny,Allow
Seul Allow valide Requête autorisée Requête autorisée
Seul Deny valide Requête refusée Requête refusée
Allow et Deny pas valides Seconde directive appliquée = refusée Seconde directive appliquée = autorisée
A la fois Allow & Deny valides Dernier contrôle valide appliqué = refusée Dernier contrôle valide appliqué = autorisée

Allow from all|host|env=env-variable [host|env=env-variable] ...

La directive Allow spécifie qui peut accéder à une zone du serveur.

L’accès peut être contrôlé par nom d’hôte, adresse IP, plage d’adresses IP ou encore d’autres caractéristiques de la requête du client qui ont été capturées dans des variables d’environnement.

Le premier argument est toujours from. Les arguments suivants peuvent prendre 3 formes différentes :

  • Si Allow from all est spécifié, alors tout le monde est autorisé, dans le cadre de la directive Allow, c’est à dire qu’il faudra prendre en compte la directive Deny et l’ordre spécifié par Order, mais ceci est expliqué plus haut.
  • Pour autoriser l’accès au serveur à des hôtes ou à des groupes d’hôtes on peut le faire en utilisant différents formats qui sont décrits en détail (en Anglais) ici.
  • Le dernier format possible est celui qui se base sur les variables d’environnement. C’est aussi expliqué en détail (en Anglais) ici.

Deny from all|host|env=env-variable [host|env=env-variable] ...

La directive Deny spécifie qui peut accéder à une zone du serveur.

L’accès peut être contrôlé par nom d’hôte, adresse IP, plage d’adresses IP ou encore d’autres caractéristiques de la requête du client qui ont été capturées dans des variables d’environnement.

Les arguments sont identiques à ceux décrit pour la directive Allow.

Pour plus de détails, vous pouvez le lire en Anglais ici.

Options [+|-]option [[+|-]option] ...

La directive Option décrit quelles sont les possibilités offertes au serveur pour un répertoire donné.

Option peut être mis à :

  • None : dans ce cas, aucune des possibilités supplémentaires n’est activée
  • All : toutes les possibilités supplémentaires sont actives sauf MultiViews. C’est la configuration par défaut.
  • ExecCGI : L’éxécution des scripts CGI (en utilisant le module mod_cgi) est autorisée. Le serveur suivra les liens symboliques de ce répertoire. Malgré le fait que le serveur suivra les liens symboliques de ce répertoire, cela ne change pas le nom du répertoire utilisé pour appliquer les directives dans les sections <Directory>.
    Notez que cette option est ignorée si elle est dans une section <Location> (mais c’est un peu hors sujet ici).
  • Includes : les inclusions côté serveur (en utilisant le module mod_include) sont autorisées.
  • IncludesNOEXEC : les inclusions côté serveur (en utilisant le module mod_include) sont autorisées, mais les commandes #exec et #exec cgi sont interdites.
    Il est toujours possible d’inclure en utilisant #include, des scripts virtuels CGI à partir de répertoires ScriptAliased (mais c’est un peu hors sujet ici).
  • Indexes : Si l’URL de la requête correspond à un répertoire, et qu’il n’y a aucun DirectoryIndex (par exemple ni de index.html, ni de index.php) dans ce répertoire, alors le module mod_autoindex renverra un listing formatté du répertoire.
  • MultiViews : Les contenus negotiés "MultiViews" sont autorisés en utilisant le module mod_negotiation.
  • SymLinksIfOwnerMatch : Le serveur ne suivra les liens symboliques que si l’id de l’utilisateur qui possède le répertoire – ou fichier – destination est le même que celui du lien.
    Notez que cette option est ignorée si elle est dans une section <Location> (mais c’est un peu hors sujet ici).

Normalement, si on applique plusieurs Options dans un répertoire, c’est la directive qui est la plus spécifique au répertoire qui est appliquée. Les autres Options sont ignorées. Les autres Options ne sont pas fusionnées.

Néanmoins, si, dans une directive Options, toutes les options qui suivent sont précédées par un signe + ou -, les deux Options sont fusionnées. Dans ce cas, n’importe quelle option précédée par un + est ajoutée aux options actives, et n’importe quelle option précédée par un – est retirée des options actives.

Regardez l’exemple (en Anglais) ici.

Notez bien encore une fois que si on ne précise pas la directive Options, la valeur All est appliquée.

Authname : à quoi ça sert ?

Domaine d’autorisation à utiliser lors de l’authentification HTTP. Cette directive applique le domaine d’autorisation à utiliser pour un répertoire donné.

Le domaine d’autorisation est affiché au client pour qu’il sache quel identifiant et quel mot de passe envoyer. AuthName prend un seul argument.

Si le domaine contient des espaces il doit être entouré par des guillemets.

Pour fonctionner, il doit être obligatoirement accompagné par les directives AuthType et Require, et éventuellement d’autres directives telles que AuthUserFile et AuthGroupFile.

Par exemple:

AuthName "Top Secret"

La chaine donnée par AuthName est ce qui va apparaître dans la fenêtre demandant le mot de passe de la plupart des browsers Internet.

Attention !

Si jamais vous ne mettez pas d’espaces dans la directive AuthName, alors il ne faut pas mettre de guillemets.

Par exemple:

AuthName "Top Secret"

Et :

AuthName Secret

sont des exemples corrects.

Mais ceci ne fonctionnera pas :

AuthName "Secret"

… cela peut, comme cela me l’a fait, faire perdre des heures entières…

Le module mod_rewrite

Apache se souvient des modèles, ou groupes passés dans les règles de réécriture, et on peut les rappeler grâce à la directive $N, avec (0 <= N <= 9).

Apache se souvient aussi des derniers ordres passés dans les conditions de réécriture, et on peut les rappeler grâce à la directive %N, avec (0 <= N <= 9).

Un exemple concret :

  1. RewriteCond %{HTTP_HOST} ^(www\.)+mamemeamoi\.(com|fr) [NC]
  2. RewriteCond %{REQUEST_URI} ^(.*)\.php$ [NC]
  3. RewriteRule ^/(.*) /$1?IDP=mameme [PT,QSA,S=4]

Traduit en clair, cela signifie :

  1. Si on vient ici à partir d’une adresse telles que www.mamemeamoi.com ou encore www.mamemeamoi.fr voire mamemeamoi.fr alors c’est bon on continue les conditions pour la règle à venir
  2. Si on demande à voir une page qui se termine par php alors c’est bon on continue les conditions pour la règle à venir
  3. Si on est arrivé jusqu’ici c’est que toutes les conditions ont été validées => on applique la règle qui est, traduite en Français :
    1. ^/(.*) /$1?IDP=mameme : on ajoute à l’URI, quelle qu’elle soit, les paramètres IDP=mameme ;
    2. Directive [PT] : on applique cette URI en interne de manière à faire croire à tout ce qui suit, y compris une fois que les règles de réécriture sont terminées, que c’est vraiment cette adresse qui a été demandée, donc les autres modules agiront aussi en conséquence ;
    3. Directive [QSA] : sur l’URI appliquée, on y fait suivre les paramètres qui se trouvaient après le ?, les paramètres _GET en php. Par exemple si on a demandé /t.php?i=3, on se retrouve avec l’URI finale /t.php?i=3&IDP=meme, alors que sans la directive QSA, on se retrouve avec l’URL finale /t.php?IDP=meme ;
    4. Directive [S=4] : on demande de sauter les 4 règles de réécriture qui suivent, et on appliquera celles qu’il y a après (s’il y en a).

Maintenant, voyons si on avait changé la règle de réécriture par :

  1. RewriteCond %{HTTP_HOST} ^(www\.)+mamemeamoi\.(com|fr) [NC]
  2. RewriteCond %{REQUEST_URI} ^(.*)\.php$ [NC]
  3. RewriteRule ^/(.*) /%1%2/$1

Regardez bien : il y a le sigle %1 mais aussi le sigle $1. En réalité le %1 est remplacé par ce qu’il y a dans les parenthèses rencontrées dans la condition de réécriture. Et en partant de la première condition ! A l’inverse, le $1 est remplacé par ce qu’il y a dans les parenthèses rencontrées dans la règle de réécriture. Ainsi si on demande l’URI http://www.mamemeamoi.com/popo.php, elle sera transformée en http://www.com/popo.php, et si on demande l’URI http://mamemeamoi.com/popo.php, elle sera transformée en http://com/popo.php. Ce qui ne sert à rien d’autre que de montrer un exemple. Mais imaginez ce que vous pouvez faire !

Zeemoz : mémo Apache

  1. Tuer les sémaphores d’Apache
    /opt/httpd/erase_semaphores.sh
  2. Fuites mémoires Apache
    Pour vérifier si Apache a des fuites mémoire, il suffit juste de le faire tourner comme n’importe quel éxécutable, via valgrind :
    valgrind --leak-check=full --log-file=./valgrind.log /opt/httpd/bin/httpd

MPM : Multi-Processing-Modules

A la fin de la phase de démarrage, après que la configuration ait été lue, le contrôle général d’Apache est passé à un module de gestion de processus, le Multi-Processing-Module.

Un MPM est une interface entre le serveur Apache qui tourne et l’OS sous-jacent. Son rôle principal est d’optimiser Apache en fonction de la plateforme sur laquelle le serveur tourne. Comme indiqué dans le titre, le MPM est lui-même un module. C’est, à l’inverse de tous les autres, modules, un module au niveau système et non pas un module au niveau applicatif.

Il exite plusieurs MPM‘s.

  • MPM Prefork : c’est un modèle non orienté thread, ressemblant fortement aux mode de fonctionnement des serveurs Apache 1.x
  • MPM Worker : modèle orienté thread. Il a une plus grande souplesse et s’adapte beaucoup mieux en fonction de la demande. Il est particulièrement plus performant que le modèle précédent, notamment avec certains types d’applications.

Tous les deux souffrent d’une limite qui affecte tous les serveurs très demandés. Alors que le HTTP Keepalive est nécéssaire pour réduite le nombre de connexions TCP et la surcharge réseau, il « ligotte » le processus ou le thread d’un serveur pendant toute la durée de la connexion, tant que le Keepalive est actif.

Le nombre de threads disponibles est une ressource critique pour la plateforme sur laquelle est le serveur. Par exemple, un serveur basé sur le module MPM Worker est réellement occupé s’il doit se charger de gérer plusieurs dizaines de milliers de demandes simultanément. L’OS sous-jacent peut parfois arriver à court de threads.

C’est pourquoi un nouveau MPM est en cours de développement. Il en est à un stade avancé, mais pas encore au stade de production, stade qu’ont atteint les deux modules cités précédemment. C’est le MPM basé sur des événements, le Event MPM. Notez bien que ce type de module ne fonctionnera pas en mode sécurisé (https). Par contre, il aura la possiblité de gérer un nombre nettement plus important de hits que les autres modules.

Apache : le lancement du processus

Le démarrage d’Apache se décompose en deux temps :

  1. démarrage ;
  2. mode opérationnel.

C’est à dire que quelque chose peut porter à confusion, mais c’est normal : le code de configuration est appelé deux fois.

La première fois c’est uniquement pour vérifier si toute la configuration est valide, et la seconde fois, c’est pour le démarrage réel, la phase « opérationnelle ».

La plupart des modules peuvent ignorer ce comportement, mais il possible que, par exemple, si votre module charge du code dynamiquement au démarrage, il n’ait pas besoin de le faire deux fois. Les modules qui veulent faire cela peuvent, par exemple, déclarer un drapeau statique et, vérifier lors de l’appel, s’il est déjà initialisé. Si ce n’est pas le cas, le mettre à vrai, et charger tout ce qu’il faut. Dans les autres cas, ne rien faire.

Notez bien qu’au démarrage, Apache n’a qu’un seul thread actif et est root, ce qui signifie qu’il est possible de faire tout et n’importe quoi, mais après le démarrage, il ne sera plus jamais root, par mesure de sécurité.