Differenze esplicite tra <Directory> e <DirectoryMatch> (e altre direttive <* Match>)


8

Prefazione

Sono un neofita per quanto riguarda i server web. Sto configurando un server Apache2 e attualmente sto esaminando la documentazione.

Ho notato che il <Directory>, <Location>e <Files>direttive hanno ciascuno un corrispondente <*Match>direttiva: <DirectoryMatch>, <LocationMatch>e <FilesMatch>rispettivamente. La differenza sulla superficie è abbastanza evidente:

  • <*Match> le direttive assumono un'espressione regolare come argomento
  • Le direttive non match prendono come argomento una stringa semplice o un glob in stile shell.

Curiosamente, le direttive non-Match possono anche essere date come espressione regolare come argomento se precedute da un '~'. Pertanto, le seguenti due righe dovrebbero essere identiche:

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

Domande

Quello che mi piacerebbe sapere è se ci sono o meno differenze sottili o chiave da tenere presente che i coredocumenti di Apache non menzionano. La <DirectoryMatch>sezione menziona una sottile differenza:

Compatibilità

Prima della 2.3.9 , questa direttiva si applicava implicitamente alle sottodirectory (come <Directory>) e non poteva corrispondere al simbolo di fine riga ($). In 2.3.9 e versioni successive , solo le directory che corrispondono all'espressione sono interessate dalle direttive allegate.

Oltre a ciò, vorrei sapere:

  • Ci sono altre differenze tra le direttive Match e non Match?
  • Quale direttiva è più preferibile quando è richiesta un'espressione regolare?
  • Altre informazioni che ritieni pertinenti?

Appunti

  • <DirectoryMatch>e <Directory "~">sono allo stesso livello di unione
  • Sebbene non esplicitamente menzionato, è <Directory "~">possibile utilizzare gruppi denominati e riferimenti secondari, proprio come <DirectoryMatch>.

Risposte:


2

La differenza sta nel tipo di parametro consentito:

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

vs

<DirectoryMatch regex> ... </DirectoryMatch>

DirectoryMatchè un superset, per quanto riguarda le funzionalità in quanto sarai in grado di codificare qualsiasi percorso come regex. Non è vero il contrario.

Directory ~è probabilmente un'aggiunta tardiva. Basato su un commit trovato nel repository (commit 07b82419b59d1bb7ba8860b86a2d381d5d1090bc nel novembre 1996), questo caso è stato aggiunto in Apache 1.2

DirectoryMatch è stato quindi aggiunto in Apache 1.3 (commit a318749e61fda612e883a9ea594459a4517166b8 nel luglio 1997) con un set più ricco di funzionalità.

E la documentazione aggiornata in tale commit diceva chiaramente che dovresti favorire la versione della partita quando usi un regex:

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

(questa istruzione "si consiglia di utilizzare DirectoryMatch" è stata rimossa in seguito in un commit dell'agosto 1997)

DirectoryMatchè comunque superiore perché Directory ~vengono gestiti solo dopo Directoryistruzioni "normali" e DirectoryMatchconsente di acquisire dati che è possibile utilizzare successivamente.

Quando stai usando una regex, preferirei la Matchvariante in quanto rende più chiaro che stai usando un'espressione regolare e non un caso specifico della variante non corrispondente. Oltre alle piccole differenze sopra, non farebbe comunque una differenza enorme.

L'aggiornamento infatti probabilmente non ha comportato modifiche poiché il codice fa lo stesso:

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

Quindi la stessa identica chiamata r = ap_pregcomp(cmd->pool, cmd->path, AP_REG_EXTENDED|USE_ICASE);in entrambi i casi.


2
"DirectoryMatch è un superset" - sebbene l'OP stia confrontando in modo specifico <Directory ~e <DirectoryMatchnon <Directory. Fino ad Apache 2.3.9, <Directory ~era probabilmente il superset perché supportava l' $ancoraggio regex, mentre <DirectoryMatchnon lo era. (Questo potrebbe anche essere stato il motivo per cui la raccomandazione di utilizzare è DirectoryMatchstata rimossa nei documenti precedenti?)
MrWhite

2
" DirectoryMatchè ancora superiore perché Directory ~vengono gestiti solo dopo Directoryistruzioni " normali " e DirectoryMatchconsente di acquisire dati che è possibile utilizzare successivamente." - ma come rilevato dal PO, queste direttive sono le stesse in entrambi questi aspetti.
MrWhite,

1
Sono d'accordo che DirectoryMatchè più facile da leggere e quindi preferibile (oltre Directory ~). Sebbene i documenti non lo dichiarino esplicitamente, DirectoryMatchvengono utilizzati in tutti gli esempi recenti (ad es. Nella pagina Sezioni di configurazione ) e Directory ~non vengono mai menzionati. La documentazione, tuttavia, esplicitamente affermano che il nome simile LocationMatche FilesMatchsono preferibili sopra la corrispondente ~versione di queste direttive.
MrWhite,

@MrWhite DirectoryMatchnon supportava l' $ancora prima di Apache 2.3.9? I commit che ho trovato sono relativi ad Apache 1.2 / 1.3, finora.
Patrick Mevzek,

1
Sì, come affermato dall'OP (dai documenti 2.4 ), mentre i primi esempi <Directory ~includevano persino l'ancoraggio di fine stringa. Sì, vedo che i commit sono da 1.2 / 1.3 - buona scavatura! :) È anche indicato nei documenti Apache 1.3 quando è DirectoryMatchstato introdotto. Ci sono stati anche cambiamenti in Apache 1.3 (dall'1.2) per quanto riguarda il modo in cui i contenitori regex (ad es. <Directory ~E quelli appena introdotti <DirectoryMatch) sono stati uniti.
MrWhite,

1

Ci sono altre differenze tra le direttive Match e non Match?

Non strettamente una differenza tra le due versioni di regex ( <Directory ~e <DirectoryMatch), ma alcune direttive, come AllowOverridee AllowOverrideList, sono consentite solo in un <Directory>contenitore semplice (non regex) . Quindi, questo esclude sia <Directory ~e <DirectoryMatch.

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

Disponibile solo in <Directory>sezioni
AllowOverride è valido solo in <Directory>sezioni specificate, senza le espressioni regolari, non in <Location>, <DirectoryMatch>o <Files>sezioni.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.