Явные различия между <Directory> и <DirectoryMatch> (и другими директивами <* Match>)

8

Предисловие

Я очень новичок в отношении веб-серверов. Я настраиваю сервер Apache2 и в настоящее время изучаю документацию.

Я заметил , что <Directory>, <Location>и <Files>директивы имеют соответствующую <*Match>директиву: <DirectoryMatch>, <LocationMatch>и <FilesMatch>соответственно. Разница на поверхности достаточно очевидна:

  • <*Match> директивы принимают регулярное выражение в качестве аргумента
  • Директивы Non-Match принимают в качестве аргумента обычную строку или глобус в стиле оболочки.

Любопытно, что директивам, отличным от Match, также может быть задано регулярное выражение в качестве аргумента, если ему предшествует '~'. Таким образом, следующие две строки должны быть идентичны:

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

Вопросов

Что я хотел бы знать, так это то, есть ли какие-то тонкие или ключевые отличия, о которых нужно знать, что документы Apachecore не упоминаются. В <DirectoryMatch>разделе упоминается одно тонкое отличие:

Совместимость

До 2.3.9 эта директива неявно применялась к подкаталогам (вроде <Directory>) и не могла соответствовать символу конца строки ($). В 2.3.9 и позже только вложенные директивы влияют только на каталоги.

Помимо этого, я хотел бы знать:

  • Есть ли другие различия между директивами Match и Non-Match?
  • Какая директива более предпочтительна, когда требуется регулярное выражение?
  • Любая другая информация, которую вы считаете уместной?

Ноты

  • <DirectoryMatch>и <Directory "~">находятся на одном уровне слияния
  • Хотя это и не указано явно, <Directory "~">может использовать именованные группы и обратные ссылки, как <DirectoryMatch>.
ZeroKnight
источник

Ответы:

2

Разница в разрешенном типе параметра:

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

против

<DirectoryMatch regex> ... </DirectoryMatch>

DirectoryMatchэто расширенный набор функций, так как вы сможете закодировать любой путь в виде регулярного выражения. Противоположность не верна.

Directory ~вероятно, последнее добавление. Основанный на коммите, найденном в репозитории (коммит 07b82419b59d1bb7ba8860b86a2d381d5d1090bc в ноябре 1996 года), этот случай был добавлен в Apache 1.2

DirectoryMatch затем был добавлен в Apache 1.3 (commit a318749e61fda612e883a9ea594459a4517166b8 в июле 1997 г.) с более широким набором функций.

И в документации, обновленной в этом коммите, четко сказано, что вы должны отдавать предпочтение версии соответствия при использовании регулярного выражения:

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

(этот оператор «рекомендуется использовать DirectoryMatch» был удален позже в коммите в августе 1997 г.)

DirectoryMatchвсе еще лучше, потому что Directory ~обрабатываются только после «нормальных» Directoryоператоров, и DirectoryMatchпозволяет вам захватывать данные, которые вы можете впоследствии использовать.

Когда вы используете регулярное выражение, я бы предпочел Matchвариант, так как он прояснит, что вы используете регулярное выражение, а не конкретный случай варианта с несоответствием. Помимо небольших различий, приведенных выше, это не будет иметь большого значения.

ОБНОВЛЕНИЕ фактически, вероятно, никаких изменений в результате, так как код делает то же самое:

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

Точно такой же призыв r = ap_pregcomp(cmd->pool, cmd->path, AP_REG_EXTENDED|USE_ICASE);в обоих случаях.

Патрик Мевзек
источник
2
«DirectoryMatch - это надмножество» - хотя ОП специально сравнивает <Directory ~и <DirectoryMatchнет <Directory. До Apache 2.3.9, <Directory ~возможно , был надмножеством, потому что он поддерживал $привязку регулярных выражений, тогда как <DirectoryMatchне поддерживал . (Возможно, поэтому рекомендация по использованию DirectoryMatchбыла удалена в более ранних документах?)
MrWhite
2
« DirectoryMatchвсе еще лучше, потому что Directory ~обрабатываются только после« нормальных » Directoryоператоров и DirectoryMatchпозволяет вам собирать данные, которые вы можете впоследствии использовать». - но, как отмечено ФП, эти директивы одинаковы в обоих этих отношениях.
MrWhite
1
Я согласен, что DirectoryMatchлегче читать и, следовательно, предпочтительнее (более Directory ~). Хотя в документах это явно не указано, DirectoryMatchоно используется во всех недавних примерах (например, на странице « Разделы конфигурации» ) и Directory ~никогда не упоминается. Документы, тем не менее, прямо заявляют, что аналогично названы LocationMatchи FilesMatchявляются предпочтительными по сравнению с соответствующей ~версией этих директив.
MrWhite
@MrWhite DirectoryMatchне поддерживал привязку $до Apache 2.3.9? Коммиты, которые я обнаружил, связаны с Apache 1.2 / 1.3, до этого.
Патрик Мевзек
1
Да, как указано в OP (из 2.4 документа ), тогда как в ранних примерах <Directory ~даже был указатель конца строки. Да, я вижу, что эти коммиты от 1.2 / 1.3 - хорошо копать! :) Это также указано в документации Apache 1.3, когда она DirectoryMatchбыла представлена. Также произошли изменения в Apache 1.3 (от 1.2) в отношении того, как слились контейнеры регулярных выражений (то есть <Directory ~и только что введенные <DirectoryMatch).
MrWhite
1

Есть ли другие различия между директивами Match и Non-Match?

Не строго различие между двумя версиями регулярных выражений ( <Directory ~и <DirectoryMatch), но некоторые директивы, такие как AllowOverrideи AllowOverrideList, разрешены только в простом (не регулярном выражении) <Directory>контейнере. Таким образом, это исключает как <Directory ~и <DirectoryMatch.

Ссылка:
https://httpd.apache.org/docs/2.4/mod/core.html#allowoverride

Доступно только в <Directory>секциях
AllowOverride действует только в <Directory>разделах , указанных без регулярных выражений, не в <Location>, <DirectoryMatch>или <Files>секции.

MrWhite
источник