Diferencias explícitas entre <Directory> y <DirectoryMatch> (y otras directivas <* Match>)

8

Prefacio

Soy muy neófito con respecto a los servidores web. Estoy configurando un servidor Apache2 y actualmente revisando detenidamente la documentación.

Me di cuenta de que el <Directory>, <Location>y <Files>las directivas de cada una correspondiente <*Match>Directiva: <DirectoryMatch>, <LocationMatch>y <FilesMatch>respectivamente. La diferencia en la superficie es bastante evidente:

  • <*Match> las directivas toman una expresión regular como argumento
  • Las directivas que no coinciden toman una cadena simple o un globo de estilo shell como argumento.

Curiosamente, las directivas que no coinciden también pueden recibir una expresión regular como argumento si está precedido por un '~'. Por lo tanto, las siguientes dos líneas deberían ser idénticas:

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

Preguntas

Lo que me gustaría saber es si hay o no diferencias sutiles o clave para tener en cuenta que los coredocumentos de Apache no mencionan. La <DirectoryMatch>sección menciona una sutil diferencia:

Compatibilidad

Antes de 2.3.9 , esta directiva se aplicaba implícitamente a subdirectorios (como <Directory>) y no podía coincidir con el símbolo de fin de línea ($). En 2.3.9 y posteriores , solo los directorios que coinciden con la expresión se ven afectados por las directivas adjuntas.

Más allá de eso, me gustaría saber:

  • ¿Hay alguna otra diferencia entre las directivas Match y no Match?
  • ¿Qué directiva es más preferible cuando se requiere una expresión regular?
  • ¿Alguna otra información que considere pertinente?

Notas

  • <DirectoryMatch>y <Directory "~">están en el mismo nivel de fusión
  • Si bien no se menciona explícitamente, <Directory "~">puede usar grupos con nombre y referencias posteriores, al igual que <DirectoryMatch>.
ZeroKnight
fuente

Respuestas:

2

La diferencia está en el tipo de parámetro permitido:

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

vs

<DirectoryMatch regex> ... </DirectoryMatch>

DirectoryMatches un superconjunto, en función de las características, ya que podrá codificar cualquier ruta como una expresión regular. Lo contrario no es verdad.

Directory ~Es probablemente una adición tardía. Basado en un commit encontrado en el repositorio (commit 07b82419b59d1bb7ba8860b86a2d381d5d1090bc en noviembre de 1996), este caso se agregó en Apache 1.2

DirectoryMatch Luego se agregó en Apache 1.3 (commit a318749e61fda612e883a9ea594459a4517166b8 en julio de 1997) con un conjunto más rico de características.

Y la documentación actualizada en esa confirmación dice claramente que debe favorecer la versión de coincidencia al usar una expresión regular:

    &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>

(esta declaración "se recomienda usar DirectoryMatch" se eliminó más adelante en una confirmación en agosto de 1997)

DirectoryMatchsigue siendo superior porque Directory ~se maneja solo después de Directorydeclaraciones "normales" y le DirectoryMatchpermite capturar datos que puede usar posteriormente.

Cuando use una expresión regular, preferiría la Matchvariante, ya que aclara que está usando una expresión regular, y no un caso específico de la variante no coincidente. Además de las pequeñas diferencias anteriores, sin embargo, no haría una gran diferencia.

ACTUALIZACIÓN, de hecho, probablemente no haya cambios en el resultado ya que el código hace lo mismo:

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

Entonces, exactamente la misma llamada a r = ap_pregcomp(cmd->pool, cmd->path, AP_REG_EXTENDED|USE_ICASE);en ambos casos.

Patrick Mevzek
fuente
2
"DirectoryMatch es un superconjunto", aunque el OP está comparando específicamente <Directory ~y <DirectoryMatchno <Directory. Hasta Apache 2.3.9, <Directory ~era posiblemente el superconjunto porque soportaba el $anclaje regex, mientras <DirectoryMatchque no. (Esto también puede haber sido por qué la recomendación de usar DirectoryMatchse eliminó en los documentos anteriores?)
MrWhite
2
" DirectoryMatchsigue siendo superior porque Directory ~se maneja solo después de Directorydeclaraciones " normales " y le DirectoryMatchpermite capturar datos que puede usar posteriormente". - pero como señaló el OP, estas directivas son las mismas en ambos aspectos.
MrWhite
1
Estoy de acuerdo en que DirectoryMatches más fácil de leer y, por lo tanto, preferible (terminar Directory ~). Si bien los documentos no indican explícitamente esto, DirectoryMatchse usa en todos los ejemplos recientes (por ejemplo, en la página de Secciones de configuración ) y Directory ~nunca se menciona. Los documentos, sin embargo, afirman explícitamente que los nombres similares LocationMatchy FilesMatchson preferibles a la ~versión correspondiente de estas directivas.
MrWhite
@MrWhite DirectoryMatchno era compatible con el $ancla antes de Apache 2.3.9? Los commits que encontré están relacionados con Apache 1.2 / 1.3, hasta ahora.
Patrick Mevzek
1
Sí, como lo indica el OP (de los documentos 2.4 ), mientras que los primeros ejemplos de <Directory ~incluso incluyeron el ancla de fin de cadena. Sí, veo que esos commits son de 1.2 / 1.3 - ¡buena excavación! :) También se indica en los documentos de Apache 1.3 cuando DirectoryMatchse introdujo. También hubo cambios en Apache 1.3 (desde 1.2) con respecto a cómo se fusionaron los contenedores regex (es decir, <Directory ~y los recién introducidos <DirectoryMatch).
MrWhite
1

¿Hay alguna otra diferencia entre las directivas Match y no Match?

No es estrictamente una diferencia entre las dos versiones de expresiones regulares ( <Directory ~y <DirectoryMatch), pero algunas directivas, como AllowOverridey AllowOverrideList, solo se permiten en un <Directory>contenedor simple (sin expresiones regulares) . Entonces, eso excluye ambos <Directory ~y <DirectoryMatch.

Referencia:
https://httpd.apache.org/docs/2.4/mod/core.html#allowoverride

Sólo disponible en <Directory>secciones
AllowOverride es válida sólo en <Directory>secciones especificadas sin expresiones regulares, no en <Location>, <DirectoryMatch>o <Files>secciones.

Señor White
fuente