Apache httpd 2.4 中是否有多个相同目录指令的简写?

Apache httpd 2.4 中是否有多个相同目录指令的简写?

这是 Apache httpd 2.4。

我正在尝试将旧版安装从 2.2 移植到 2.4,并在此过程中对其进行一些清理。有很多具有相同设置的目录,其中散布着一些不同的目录。本质上,它看起来像这样:

<directory /var/www/aaa >
  # lots of stuff
</directory>
<directory /var/www/bbb >
  # lots of stuff
</directory>
<directory /var/www/ >
  # lots of stuff
</directory>
<directory /var/www/ccc >
  # lots of other stuff
</directory>

我希望避免多余的行,所以我希望有某种速记,例如:

<directory /var/www/aaa >
<directory /var/www/bbb >
<directory /var/www/ >
  # lots of stuff
</directory>

<directory /var/www/ccc >
  # lots of other stuff
</directory>

<Directory>不以我能找到的任何方式支持多个目录。所以<DirectoryMatch>看起来很合适,像这样:

<directoryMatch /var/www/(aaa|bbb|) >
  # lots of stuff
</directory>

<directoryMatch /var/www/ccc >
  # lots of other stuff
</directory>

这会失败,因为/var/www/(aaa|bbb|)匹配/var/www/ccc不完整。与 相反<Directory><DirectoryMatch>不按照最短目录组件到最长的顺序进行处理。该手册声称“在每个组中,这些部分按照它们在配置文件中出现的顺序进行处理”,但即使我切换这些部分,结果仍然是相同的(即被“ ”而不是“ ”/var/www/ccc击中) 。# lots of stuff# lots of other stuff

在这个例子中,我当然可以扩展regexp( /var/www/(aaa|bbb|(?!ccc))),但不幸的是,真正的配置比这复杂得多。使用正则表达式可能仍然是可能的,但结果将很难理解或维护。

那么,除了 DirectoryMatch 之外,是否还有其他方法可以做到这一点,有人可以给我提示吗?也许可以解释为什么 Apache 似乎更喜欢上面的部分匹配?谢谢。

答案1

没有一种易于阅读的方法来DirectoryMatch匹配所有/var/www/aaa, /var/www/bbb, 和/var/www, 但不是/var/www/ccc。这是因为/var/www包括所有其他三个目录。

可能更容易的是使用模组宏定义配置的公共部分,然后Directory按照原始示例中的方式应用它们。

a2enmod macro                # Enable the mod_macro module
systemctl restart apache2    # YMMV but this is the systemd way

然后您可以定义您的宏。这是我用的一个

# Logging
#
<Macro CronoLogger $vHost>
    ServerSignature On
    LogLevel warn
    ErrorLog "|/usr/bin/cronolog /home/www/$vHost/logs/%Y/%m/%d/public-error.log"
    CustomLog "|/usr/bin/cronolog /home/www/$vHost/logs/%Y/%m/%d/public-access.log" combined
</Macro>

我将它包含在这样的 vHost 定义中

Use CronoLogger www.contoso.com

在您的情况下,通过示例宏,StandardStuff param1 param2您可以像这样使用它

<Directory /var/www>
    Use StandardStuff /var/www /
</Directory>

<Directory /var/www/aaa>
    Use StandardStuff /var/www /aaa
</Directory>

<Directory /var/www/bbb>
    Use StandardStuff /var/www /bbb
</Directory>

<Directory /var/www/ccc>
    # Do non-standard stuff here
    #
</Directory>

答案2

该手册声称“在每个组中,这些部分按照它们在配置文件中出现的顺序进行处理”,但即使我切换这些部分,结果仍然是相同的(/var/www/ccc 被“#”击中)很多东西”而不是“#很多其他东西”)。

当两个指令匹配时,它们都会被处理。

启用mod_headers( a2enmod headers) 并尝试

<DirectoryMatch /var/www/(aaa|bbb|)>
    Header add AAA one
</DirectoryMatch>
<DirectoryMatch /var/www/ccc>
    Header add AAA two
</DirectoryMatch>

您将使用开发人员工具看到 的响应http://localhost/ccc包含两个标头。

如果你想匹配/var/www, /var/www/foo.html, /var/www/aaa /var/www/aaa/bar, /var/www/bbb, /var/www/bbb/baz,那么这应该有效:

<DirectoryMatch ^/var/www/([^/]*|aaa/.*|bbb/.*)$>
  • [^/]*匹配其中/var/www/不是目录的任何内容
  • aaa/.*|bbb/.*匹配里面的任何内容,包括子目录
  • $这里很重要,否则正则表达式仅定义匹配目录的开头,并且超出您想要的范围

如果您只需要匹配目录(并且里面没有其他文件),请使用

<DirectoryMatch ^/var/www(/aaa|/bbb)?/?$>

我可能更喜欢LocationMatch(如果可能的话),这样您就不必关心目录结构。

相关内容