我有一个有趣的条件解析问题需要解决,但尚未在网上搜索和查看 lighttpd 文档。许多搜索都导致出现类似的问题,并提供了有用的答案(针对这些问题,让我们看看这个问题是如何运行的:
我在网关路由器(OpenWRT,或者如果你愿意的话,叫 Turris OS,因为它是 Turris Omnia)上运行了 lighttpd,它有多个域指向它,并将其分发出去,作为该网关 LAN 侧服务器的反向代理。
常规配置如下:
$HTTP["host"] =~ "(a.com|b.com|c.com)$" {
proxy.server = ( "" => ( ( "host" => "..." ) ) )
...
} else $HTTP["host"] =~ "(d.org|e.org)$" {
proxy.server = ( "" => ( ( "host" => "..." ) ) )
...
} else $HTTP["host"] =~ "(f.net|g.net)$" {
proxy.server = ( "" => ( ( "host" => "..." ) ) )
...
}
这一直是一个梦想。
现在,我想从该路由器直接为所有这些站点提供一条公共的特定路径。
再次形式化地来说:
$HTTP["url"] =~ "^/topdir/subir/" {
server.document-root = "/www/sharedstuff"
}
我可以将其完美地组合如下(并且有效):
$HTTP["url"] =~ "^/topdir/subir/" {
server.document-root = "/www/sharedstuff"
} else {
$HTTP["host"] =~ "(a.com|b.com|c.com)$" {
proxy.server = ( "" => ( ( "host" => "..." ) ) )
...
} else $HTTP["host"] =~ "(d.org|e.org)$" {
proxy.server = ( "" => ( ( "host" => "..." ) ) )
...
} else $HTTP["host"] =~ "(f.net|g.net)$" {
proxy.server = ( "" => ( ( "host" => "..." ) ) )
...
}
}
甜的。
但是,这是我试图解决的问题。理想情况下,我希望将$HTTP["url"]
条件封装在一个包含文件中,将$HTTP["host"]
条件封装在另一个包含文件中,这样我就可以:
include "/etc/lighttpd/conf.d/shared.conf" # contains the `$HTTP["url"]` constraint
include "/etc/lighttpd/conf.d/distributed.conf" # contains the `$HTTP["host"]` constraint
我不知道我是否期望太多了。因为我无法想到或找到一种方法来做到这一点。
我想象如果shared.conf
包含一些语句,那么就存在一个配置语句,如下:
$HTTP["url"] =~ "^/topdir/subir/" {
server.document-root = "/www/sharedstuff"
ignore-all-subsequent-host-match-conditions
}
另一个有创意的想法(尽管有些幼稚和不可能)是,我们可以重写$HTTP["host"]
如下内容:
$HTTP["host"] = "null.net"
这样后续的匹配都会$HTTP["host"] =~ "(a.com|b.com|c.com)$"
全部失败,并且请求保持本地状态。
以下是迄今为止探索的一些选项:
服务器变量
不行,因为这些是在加载配置时评估的,而不是在处理请求时评估的。
https://redmine.lighttpd.net/projects/1/wiki/docs_configuration#Using-variables
请求标头
setenv.add-request-header
看起来很有吸引力:
https://redmine.lighttpd.net/projects/lighttpd/wiki/Docs_ModSetEnv
如果shared.conf
我们设置了自定义请求标头,也许我们可以使用以下方式对其进行$REQUEST_HEADER["header"]
测试distributed.conf
:
https://redmine.lighttpd.net/projects/1/wiki/docs_configuration#Conditional-Configuration
但我没有成功。似乎有这样的条件:
$REQUEST_HEADER["my_header"] == "value_I_set" {
# Do not act as a reverse proxy
} else $HTTP["host"] =~ "(a.com|b.com|c.com)$" {
proxy.server = ( "" => ( ( "host" => "..." ) ) )
...
} else $HTTP["host"] =~ "(d.org|e.org)$" {
proxy.server = ( "" => ( ( "host" => "..." ) ) )
...
} else $HTTP["host"] =~ "(f.net|g.net)$" {
proxy.server = ( "" => ( ( "host" => "..." ) ) )
...
}
根本不起作用,我真的不知道为什么。很难看出发生了什么,但如果我在条件处理上记录输出,似乎即使对于匹配$REQUEST_HEADER["my_header"]
以下 URL 也是如此:shared.conf
$HTTP["url"] =~ "^/topdir/subir/" {
setenv.add-request-header = ("my_header" => "value_I_set")
}
看来该条件并不测试 setenv 设置的请求标头,而是测试那些传递的请求标头。
答案1
一个可能的配置解决方案是将共享配置后条件$HTTP["host"]
,并根据你的情况,覆盖代理配置
$HTTP["url"] =~ "^/topdir/subir/" {
server.document-root = "/www/sharedstuff"
proxy.server = ()
}
另一个解决方案,更灵活,更强大:lighttpdmod_magnet允许您在几行 lua 中编写任意复杂的逻辑。您可以让您的“共享”配置在 lighttpd mod_proxy 之前处理某些请求(在您的自定义 lua 脚本中)。
顺便问一下,以下简单的解决方案也有效吗?共享配置:
$HTTP["url"] =~ "^/topdir/subir/" {
server.document-root = "/www/sharedstuff"
}
在 lighttpd.conf 中包含的 shared.conf 中
include "/etc/lighttpd/conf.d/shared.conf" # contains the `$HTTP["url"]` constraint
else {
include "/etc/lighttpd/conf.d/distributed.conf" # contains the `$HTTP["host"]` constraint
}