web-dev-qa-db-fra.com

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

Préface

Je suis vraiment un néophyte en ce qui concerne les serveurs Web. J'installe un serveur Apache2 et étudie actuellement la documentation.

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

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

Curieusement, les directives non-Match peuvent également recevoir une expression régulière comme argument si elles sont précédées par 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 existe ou non des différences subtiles ou essentielles à prendre en compte docs core d'Apache ne le mentionnez pas. La section _<DirectoryMatch>_ mentionne une différence subtile:

Compatibilité

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

Au-delà, j'aimerais savoir:

  • Existe-t-il d'autres différences entre les directives Match et Non-Match?
  • Quelle directive est préférable si une expression régulière est requise?
  • Toute autre information que vous jugez pertinente?

Remarques

  • _<DirectoryMatch>_ et _<Directory "~">_ sont sur le même niveau de fusion
  • Bien que cela ne soit pas explicitement mentionné, _<Directory "~">_ peut utiliser des groupes nommés et des références arrières, tout comme _<DirectoryMatch>_.
8
ZeroKnight

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

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

contre

<DirectoryMatch regex> ... </DirectoryMatch>

DirectoryMatch est un sur-ensemble, car vous pourrez coder n'importe quel chemin en regex. Le contraire n'est pas vrai.

Directory ~ est probablement un ajout tardif. Sur la base d'un commit trouvé dans le référentiel (commit 07b82419b59d1bb7ba8860b86a2d381d5d1090bc de novembre 1996), ce cas a été ajouté dans Apache 1.2.

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

Et la documentation mise à jour dans ce commit indiquait clairement que vous devriez privilégier la version de correspondance lorsque vous utilisiez 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 ultérieurement dans un commit en août 1997)

DirectoryMatch est toujours supérieur car Directory ~ n'est traité qu'après des instructions "normales" Directory et DirectoryMatch vous permet de capturer des données que vous pourrez utiliser par la suite.

Lorsque vous utilisez une expression rationnelle, je privilégie la variante Match, car elle indique plus clairement que vous utilisez une expression régulière et non un cas spécifique de la variante sans correspondance. Outre les petites différences ci-dessus, cela ne ferait toutefois pas une énorme différence.

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

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";
        }
    }

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

2
Patrick Mevzek

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

Il ne s’agit pas vraiment d’une différence entre les deux versions de regex (<Directory ~ et <DirectoryMatch), mais certaines directives, telles que AllowOverride et AllowOverrideList, ne sont autorisées que dans un langage ordinaire. regex) <Directory> conteneur. Donc, cela exclut à la fois <Directory ~ et <DirectoryMatch.

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

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

1
MrWhite