it-swarm.com.de

Explizite Unterschiede zwischen <Directory> und <DirectoryMatch> (und anderen <* Match> -Anweisungen)

Vorwort

Ich bin ein Neuling in Bezug auf Webserver. Ich richte einen Apache2-Server ein und stöbere gerade in der Dokumentation.

Mir ist aufgefallen, dass die Anweisungen <Directory> , <Location> und <Files> jeweils eine entsprechende _<*Match>_ Direktive: <DirectoryMatch> , <LocationMatch> und <FilesMatch> . Der Unterschied auf der Oberfläche ist deutlich genug:

  • _<*Match>_-Direktiven verwenden einen regulären Ausdruck als Argument
  • Non-Match-Direktiven verwenden als Argument einen einfachen String oder einen Glob im Shell-Stil.

Seltsamerweise können die Direktiven, die keine Match-Direktiven sind, auch mit einem regulären Ausdruck als Argument versehen werden, wenn ein '~' vorangestellt ist. Die folgenden zwei Zeilen sollten also identisch sein:

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

Fragen

Was ich wissen möchte, ist, ob es subtile oder wichtige Unterschiede gibt, die zu beachten sind Apache's core docs nicht erwähnen. Der Abschnitt _<DirectoryMatch>_ erwähnt einen subtilen Unterschied:

Kompatibilität

Vor 2.3.9 galt diese Anweisung implizit für Unterverzeichnisse (wie _<Directory>_) und konnte nicht mit dem Zeilenende-Symbol ( $). In 2.3.9 und höher sind nur Verzeichnisse, die dem Ausdruck entsprechen, von den beigefügten Anweisungen betroffen.

Darüber hinaus würde ich gerne wissen:

  • Gibt es weitere Unterschiede zwischen den Match- und Nicht-Match-Richtlinien?
  • Welche Direktive ist vorzuziehen, wenn ein regulärer Ausdruck erforderlich ist?
  • Sind andere Informationen Ihrer Meinung nach relevant?

Anmerkungen

  • _<DirectoryMatch>_ und _<Directory "~">_ befinden sich auf demselben Merge-Level
  • Obwohl nicht ausdrücklich erwähnt, kann _<Directory "~">_ genau wie _<DirectoryMatch>_ benannte Gruppen und Rückverweise verwenden.
8
ZeroKnight

Der Unterschied ist im Parametertyp erlaubt:

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

vs

<DirectoryMatch regex> ... </DirectoryMatch>

DirectoryMatch ist eine Obermenge, da Sie jeden Pfad als Regex codieren können. Das Gegenteil ist nicht wahr.

Directory ~ ist wahrscheinlich eine späte Ergänzung. Basierend auf einem im Repository gefundenen Commit (Commit 07b82419b59d1bb7ba8860b86a2d381d5d1090bc vom November 1996) wurde dieser Fall in Apache 1.2 hinzugefügt

DirectoryMatch wurde dann in Apache 1.3 hinzugefügt (Commit a318749e61fda612e883a9ea594459a4517166b8 im Juli 1997) und bietet eine größere Auswahl an Funktionen.

Und in der Dokumentation, die in diesem Commit aktualisiert wurde, steht eindeutig, dass Sie bei Verwendung eines regulären Ausdrucks die Übereinstimmungsversion bevorzugen sollten:

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

(Diese Anweisung "Es wird empfohlen, DirectoryMatch zu verwenden" wurde später bei einem Commit im August 1997 entfernt.)

DirectoryMatch ist immer noch überlegen, da Directory ~ nur nach "normalen" Directory Anweisungen behandelt werden und DirectoryMatch Ihnen ermöglicht, Daten zu erfassen, die Sie anschließend verwenden können.

Wenn Sie einen regulären Ausdruck verwenden, würde ich die Variante Match bevorzugen, da dadurch klarer wird, dass Sie einen regulären Ausdruck verwenden, und nicht einen bestimmten Fall der Nicht-Übereinstimmungsvariante. Abgesehen von den oben genannten kleinen Unterschieden würde es jedoch keinen großen Unterschied machen.

UPDATE in der Tat wahrscheinlich keine Änderungen im Ergebnis, da der Code das gleiche tut:

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

Also genau derselbe Aufruf von r = ap_pregcomp(cmd->pool, cmd->path, AP_REG_EXTENDED|USE_ICASE); in beiden Fällen.

2
Patrick Mevzek

Gibt es weitere Unterschiede zwischen den Match- und Nicht-Match-Richtlinien?

Nicht unbedingt ein Unterschied zwischen den beiden Regex-Versionen (<Directory ~ und <DirectoryMatch), aber einige Anweisungen, wie AllowOverride und AllowOverrideList, sind nur in einer einfachen (nicht Regex) <Directory> Container. Das schließt also sowohl <Directory ~ als auch <DirectoryMatch aus.

Referenz:
https://httpd.Apache.org/docs/2.4/mod/core.html#allowoverride

Nur verfügbar in <Directory> Abschnitten
AllowOverride ist nur in <Directory> Abschnitten gültig, die ohne reguläre Ausdrücke angegeben sind, nicht in <Location>, <DirectoryMatch> oder <Files> Abschnitten.

1
MrWhite