![Apache:SetHandler 指令中管道符号后的 URI 的含义、目的和语义?](https://linux22.com/image/793471/Apache%EF%BC%9ASetHandler%20%E6%8C%87%E4%BB%A4%E4%B8%AD%E7%AE%A1%E9%81%93%E7%AC%A6%E5%8F%B7%E5%90%8E%E7%9A%84%20URI%20%E7%9A%84%E5%90%AB%E4%B9%89%E3%80%81%E7%9B%AE%E7%9A%84%E5%92%8C%E8%AF%AD%E4%B9%89%EF%BC%9F.png)
fcgi://
指令中管道符号后的 URI的含义、目的和语义是什么SetHandler
?
根据我对文档的理解,fcgi://
URI 的方案部分之后的所有内容对 Apache 来说没有特殊含义,而仅用作不透明的唯一标识符来区分不同的反向代理。
这是我当前的配置,仅使用fcgi://localhost/
且按预期工作。
# Using (?:pattern) instead of (pattern) is a small optimization that
# avoid capturing the matching pattern (as $1) which isn't used here
<FilesMatch ".+\.ph(?:ar|p|tml)$">
# The following "If" avoids unnecessary "Primary Script Unknown" errors from
# PHP FPM, if an attacker tries fishing typical PHP scripts (such as "wp-login.php")
# as we only call PHP FPM for actually existing files.
<If "-f %{SCRIPT_FILENAME}">
# The URL after the pipe and "fcgi" can be anything unique.
# It has no particular meaning, but serves as a opaque, unique identifier and
# match the <Proxy> definition below.
SetHandler "proxy:unix:/run/php-fpm/www.sock|fcgi://localhost/"
</If>
</FilesMatch>
# The URL of the proxy is arbitrary, but must match the URL which is used by the
# "SetHandler" directive above.
# This creates an explicit worker (see https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#workers)
# to handle requests which are relayed to the PHP FPM and allows to explicitly
# set connection options.
<Proxy "fcgi://localhost">
ProxySet flushpackets=auto flushwait=10 timeout=1200
</Proxy>
fcgi://localhost/php/
由于我需要配置另一个 FCGI 反向代理,因此我在两个地方都将 URI 更改为 ,即
...
# The URL after the pipe and "fcgi" can be anything unique.
# It has no particular meaning, but must match the <Proxy> definition below.
# We use "localhost/php" here as a telling name to make explicit that this
# proxy is our local PHP FPM.
SetHandler "proxy:unix:/run/php-fpm/www.sock|fcgi://localhost/php/"
...
<Proxy "fcgi://localhost/php">
...
这导致了错误
[proxy_fcgi:error] cloud.mhnnet.de: AH01071: Got error 'Primary script unknown'
对于以前工作的脚本。
显然,管道符号后的 URI 并非无关紧要。我哪里错了?URI 部分如何工作?
以下是文档的一些摘录:
从Apache 2.4 文档、模块mod_proxy_fcgi
、示例(我重点标注):
以下示例将请求 URI 作为文件系统路径传递,以供 PHP-FPM 守护程序运行。在本例中,PHP-FPM 正在监听 unix 域套接字 (UDS)。需要 2.4.9 或更高版本。使用此语法,后面的主机名和可选端口
fcgi://
将被忽略。ProxyPassMatch "^/(.*\.php(/.*)?)$" "unix:/var/run/php5-fpm.sock|fcgi://localhost/var/www/"
[...]
<FilesMatch "\.php$"> # Note: The only part that varies is /path/to/app.sock SetHandler "proxy:unix:/path/to/app.sock|fcgi://localhost/" </FilesMatch> # Define a matching worker. # The part that is matched to the SetHandler is the part that # follows the pipe. If you need to distinguish, "localhost; can # be anything unique. <Proxy "fcgi://localhost/" enablereuse=on max=10> </Proxy>
从Apache 2.4 文档、模块mod_proxy
、通过处理程序访问(我重点标注):
您还可以通过创建合适的处理程序传递来强制将请求作为反向代理请求处理。下面的示例配置将使用反向代理将所有 PHP 脚本请求传递到指定的 FastCGI 服务器:
<FilesMatch "\.php$"> # Unix sockets require 2.4.7 or later SetHandler "proxy:unix:/path/to/app.sock|fcgi://localhost/" </FilesMatch>
从Apache 2.4 文档、模块mod_proxy
、ProxyPass
指令(我重点标注):
在 2.4.7 及更高版本中,通过使用在前面添加 的目标,可以支持使用 Unix 域套接字
unix:/path/lis.sock|
。例如,要代理 HTTP 并将 UDS 定位到/home/www.socket
,您可以使用unix:/home/www.socket|http://localhost/whatever/
。
答案1
正如文档所述
以下示例将请求 URI 作为文件系统路径传递,以供 PHP-FPM 守护程序运行。在本例中,PHP-FPM 正在监听 unix 域套接字 (UDS)。需要 2.4.9 或更高版本。使用此语法,后面的主机名和可选端口
fcgi://
将被忽略。
仅忽略主机名和端口,不是一个潜在的路径组件!
因此,以下配置按预期工作
<FilesMatch ".+\.ph(?:ar|p|tml)$">
<If "-f %{SCRIPT_FILENAME}">
SetHandler "proxy:unix:/run/php-fpm/www.sock|fcgi://php/"
</If>
</FilesMatch>
<Proxy "fcgi://php/">
ProxySet flushpackets=auto flushwait=10 timeout=1200
</Proxy>
此示例配置使用fcgi://php/
而不是典型的fcgi://localhost/
。Apache 根据任意虚构域“php”将处理程序映射到代理定义。
因此,文档中写道
在 2.4.7 及更高版本中,通过使用在前面添加 的目标,可以支持使用 Unix 域套接字
unix:/path/lis.sock|
。例如,要代理 HTTP 并将 UDS 定位到/home/www.socket
,您可以使用unix:/home/www.socket|http://localhost/whatever/
。
太疯狂了。示例应该是unix:/home/www.socket|http://whatever/
,即主机名可以是“任意”,但不能是路径组件。