Différences explicites entre <Directory> et <DirectoryMatch> (et d'autres directives <* Match>)


8

Préface

Je suis très néophyte des serveurs Web. J'installe un serveur Apache2 et examine actuellement la documentation.

J'ai remarqué que la <Directory>, <Location>et les <Files>directives ont chacune une correspondante <*Match>directive: <DirectoryMatch>, <LocationMatch>et <FilesMatch>respectivement. La différence en surface est assez apparente:

  • <*Match> les directives prennent une expression régulière comme argument
  • Les directives non-Match prennent comme argument une chaîne simple ou un glob de style shell.

Curieusement, les directives non-Match peuvent également recevoir une expression régulière comme argument si elle est précédée d'un '~'. Ainsi, les deux lignes suivantes doivent être identiques:

# From the Apache2 docs
<Directory ~ "^/www/[0-9]{3}"> ... </Directory>
<DirectoryMatch "^/www/[0-9]{3}"> ... </DirectoryMatch>

Des questions

Ce que j'aimerais savoir, c'est s'il y a ou non des différences subtiles ou clés à savoir que les coredocuments d'Apache ne mentionnent pas. La <DirectoryMatch>section mentionne une différence subtile:

Compatibilité

Avant la 2.3.9 , cette directive s'appliquait implicitement aux sous-répertoires (comme <Directory>) et ne pouvait pas correspondre au symbole de fin de ligne ($). Dans 2.3.9 et versions ultérieures , seuls les répertoires qui correspondent à l'expression sont affectés par les directives jointes.

Au-delà, j'aimerais savoir:

  • Existe-t-il d'autres différences entre les directives Match et non-Match?
  • Quelle directive est plus préférable lorsqu'une expression régulière est requise?
  • Avez-vous d'autres informations pertinentes?

Remarques

  • <DirectoryMatch>et <Directory "~">sont au même niveau de fusion
  • Bien qu'il ne soit pas explicitement mentionné, il <Directory "~">peut utiliser des groupes nommés et des références arrières, tout comme <DirectoryMatch>.

Réponses:


2

La différence réside dans le type de paramètre autorisé:

<Directory directory-path> ... </Directory>

contre

<DirectoryMatch regex> ... </DirectoryMatch>

DirectoryMatchest un sur-ensemble, en ce qui concerne les fonctionnalités, car vous pourrez coder n'importe quel chemin en tant que regex. L'inverse n'est pas vrai.

Directory ~est probablement un ajout tardif. Basé sur un commit trouvé dans le référentiel (commit 07b82419b59d1bb7ba8860b86a2d381d5d1090bc en novembre 1996), ce cas a été ajouté dans Apache 1.2

DirectoryMatch a ensuite été ajouté dans Apache 1.3 (commit a318749e61fda612e883a9ea594459a4517166b8 en juillet 1997) avec un ensemble de fonctionnalités plus riche.

Et la documentation mise à jour dans ce commit indique clairement que vous devriez privilégier la version de correspondance lorsque vous utilisez une expression régulière:

    &lt;Directory ~ &quot;^/www/.*/[0-9]{3}&quot;&gt;
 </pre>

-would match directories in /www/ that consisted of three numbers.<p>
+would match directories in /www/ that consisted of three numbers. In
+Apache 1.3 and later, it is reccomended to use
+<a href="#directorymatch">&lt;DirectoryMatch&gt;</a> instead.<p>

(cette instruction "il est recommandé d'utiliser DirectoryMatch" a été supprimée plus tard dans un commit en août 1997)

DirectoryMatchest toujours supérieur car Directory ~ils ne sont traités qu'après des Directoryinstructions "normales" et DirectoryMatchvous permet de capturer des données que vous pourrez ensuite utiliser.

Lorsque vous utilisez une Matchexpression régulière , je privilégierais la variante car elle rend plus clair que vous utilisez une expression régulière, et non un cas spécifique de la variante non concordante. Outre les petites différences ci-dessus, cela ne ferait cependant pas une énorme différence.

UPDATE en fait probablement aucun changement de résultat puisque le code fait de même:

static const char *dirsection(cmd_parms *cmd, void *mconfig, const char *arg)
{

...

    if (!strcmp(cmd->path, "~")) {
        cmd->path = ap_getword_conf(cmd->pool, &arg);
        if (!cmd->path)
            return "<Directory ~ > block must specify a path";
        r = ap_pregcomp(cmd->pool, cmd->path, AP_REG_EXTENDED|USE_ICASE);
        if (!r) {
            return "Regex could not be compiled";
        }
    }
    else if (thiscmd->cmd_data) { /* <DirectoryMatch> */
        r = ap_pregcomp(cmd->pool, cmd->path, AP_REG_EXTENDED|USE_ICASE);
        if (!r) {
            return "Regex could not be compiled";
        }
    }

Exactement le même appel à r = ap_pregcomp(cmd->pool, cmd->path, AP_REG_EXTENDED|USE_ICASE);dans les deux cas.


2
"DirectoryMatch est un sur-ensemble" - bien que l'OP compare spécifiquement <Directory ~et <DirectoryMatchnon <Directory. Jusqu'à Apache 2.3.9, <Directory ~était sans doute le sur-ensemble car il supportait l' $ancre regex, alors <DirectoryMatchque non. (C'est peut-être aussi la raison pour laquelle la recommandation d'utilisation a DirectoryMatchété supprimée dans les documents précédents?)
MrWhite

2
" DirectoryMatchest toujours supérieur car il Directory ~n'est géré qu'après des Directoryinstructions " normales " et DirectoryMatchvous permet de capturer des données que vous pourrez ensuite utiliser." - mais comme le relève le PO, ces directives sont les mêmes à ces deux égards.
MrWhite

1
Je suis d'accord que DirectoryMatchc'est plus facile à lire et donc préférable (sur Directory ~). Bien que les documents ne le disent pas explicitement, il DirectoryMatchest utilisé dans tous les exemples récents (par exemple sur la page des sections de configuration ) et Directory ~ne reçoit jamais de mention. Cependant, les documents indiquent explicitement que le même nom LocationMatchet FilesMatchsont préférables à la ~version correspondante de ces directives.
MrWhite

@MrWhite DirectoryMatchne supportait pas l' $ancre avant Apache 2.3.9? Les commits que j'ai trouvés sont liés à Apache 1.2 / 1.3, jusqu'ici.
Patrick Mevzek

1
Oui, comme indiqué par l'OP (à partir de la documentation 2.4 ), alors que les premiers exemples de <Directory ~même inclus l'ancre de fin de chaîne. Oui, je vois que ces commits sont de 1.2 / 1.3 - bon creusage! :) Il est également indiqué dans les documents Apache 1.3 lors de DirectoryMatchson introduction. Il y a également eu des changements dans Apache 1.3 (par rapport à 1.2) en ce qui concerne la façon dont les conteneurs d'expressions régulières (c'est-à-dire <Directory ~et les nouvellement introduits <DirectoryMatch) ont été fusionnés.
MrWhite

1

Existe-t-il d'autres différences entre les directives Match et non-Match?

Pas strictement une différence entre les deux versions regex ( <Directory ~et <DirectoryMatch), mais certaines directives, telles que AllowOverrideet AllowOverrideList, ne sont autorisées que dans un <Directory>conteneur simple (non regex) . Donc, cela exclut les deux <Directory ~et <DirectoryMatch.

Référence:
https://httpd.apache.org/docs/2.4/mod/core.html#allowoverride

Uniquement disponible dans les <Directory>sections
AllowOverride n'est valide que dans les <Directory>sections spécifiées sans expressions régulières, pas dans <Location>, <DirectoryMatch>ni dans les <Files>sections.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.