<Directory>和<DirectoryMatch>(以及其他<* Match>指令)之间的显式差异


8

前言

我是有关Web服务器的新手。我正在设置一个Apache2服务器,目前正在研究文档。

我的发现<Directory><Location><Files>指示每个都有相应的<*Match>:指令<DirectoryMatch><LocationMatch><FilesMatch>分别。表面上的差异足够明显:

  • <*Match> 指令以正则表达式为参数
  • 非匹配指令将纯字符串或外壳样式的glob作为其参数。

奇怪的是,如果非Match指令前面带有“〜”,可以为其指定正则表达式作为其参数。因此,以下两行应该相同:

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

问题

我想知道的是,是否有任何细微或关键的差异需要注意,Apache的core文档没有提及。本<DirectoryMatch>节确实提到了一个细微的区别:

兼容性

在2.3.9之前的版本中,此伪指令隐式应用于子目录(如<Directory>),并且与行符号($)的末尾不匹配。在2.3.9及更高版本中,仅与表达式匹配的目录受附带的指令影响。

除此之外,我想知道:

  • Match和non-Match指令之间还有其他区别吗?
  • 当需要正则表达式时,哪个指令更可取?
  • 您认为还有其他相关信息吗?

笔记

  • <DirectoryMatch>并且<Directory "~">在同一合并级别
  • 尽管没有明确提及,但<Directory "~">可以像一样使用命名组和反向引用<DirectoryMatch>

Answers:


2

区别在于允许的参数类型:

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

<DirectoryMatch regex> ... </DirectoryMatch>

DirectoryMatch是一个超集,明智的选择,因为您将可以将任何路径编码为正则表达式。相反的说法是不正确的。

Directory ~可能是后期添加。根据在存储库中找到的提交(1996年11月提交07b82419b59d1bb7ba8860b86a2d381d5d1090bc),此情况已在Apache 1.2中添加

DirectoryMatch 然后在Apache 1.3中添加了此功能(1997年7月提交a318749e61fda612e883a9ea594459a4517166b8),并具有一组更丰富的功能。

并且在该提交中更新的文档明确指出,使用正则表达式时,您应该偏爱匹配版本:

    &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年8月的提交中被删除)

DirectoryMatch之所以具有更高的优势,Directory ~是因为它仅在“正常” Directory语句之后进行处理,并DirectoryMatch允许您捕获随后可以使用的数据。

当您使用正则表达式时,我会偏爱该Match变体,因为它使您更清楚地看到您正在使用正则表达式,而不是非匹配变体的特定情况。除了上述微小差异外,它不会产生太大差异。

实际上,由于代码执行的操作相同,因此UPDATE实际上可能不会改变结果:

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是一个超集” -虽然OP具体比较<Directory ~<DirectoryMatch,而不是<Directory。在Apache 2.3.9之前,<Directory ~可以说是超集,因为它支持$regex锚,而不支持<DirectoryMatch。(这也可能就是为什么DirectoryMatch在以前的文档中删除了使用建议的原因?)
怀特先生

2
DirectoryMatch仍然是优越的,因为Directory ~仅在“正常” Directory语句之后才处理,并DirectoryMatch允许您捕获随后可以使用的数据。” -但正如OP所指出的,这些指令在这两个方面都是相同的。
MrWhite

1
我同意,DirectoryMatch它更易于阅读,因此更可取(优于Directory ~)。尽管文档未明确说明,但DirectoryMatch所有最近的示例(例如,在Config Sections页面上)都使用了该文档,并且Directory ~从未提及。但是,文档确实明确声明了类似命名的文档,LocationMatch并且FilesMatch~这些指令的相应版本更可取。
MrWhite

@MrWhite 在Apache 2.3.9之前DirectoryMatch不支持$锚点吗?到目前为止,我发现的提交与Apache 1.2 / 1.3有关。
Patrick Mevzek '18

1
是的,正如OP所述(来自2.4文档),而<Directory ~什至的早期示例包括字符串结尾锚。是的,我看到这些提交来自1.2 / 1.3-很好的挖掘!:)它在还指出阿帕奇1.3文档DirectoryMatch被引入。在Apache 1.3(从1.2)中也有关于正则表达式容器(即<Directory ~和刚刚引入的<DirectoryMatch)如何合并的更改。
MrWhite

1

Match和non-Match指令之间还有其他区别吗?

这两个regex版本(<Directory ~<DirectoryMatch)之间没有严格的区别,但是某些指令(例如AllowOverrideAllowOverrideList)仅允许在普通(非正则表达式)<Directory>容器中使用。因此,不包括<Directory ~<DirectoryMatch

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

只适用于<Directory>部分
AllowOverride仅在有效<Directory>无正则表达式指定的,不分段<Location><DirectoryMatch><Files>部分。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.