.png)
У меня есть интересная проблема разрешения условий, которую нужно решить, и пока не везет с поиском в сети и просмотром документации по lighttpd. Многие из этих поисков привели к похожим вопросам, заданным здесь, и полезным ответам (для тех вопросов, давайте посмотрим, как это работает):
У меня lighttpd запущен на шлюзовом маршрутизаторе (OpenWRT или Turris OS, если вам так больше нравится, поскольку это Turris Omnia), и у него есть несколько доменов, указывающих на него, которые он передает в качестве обратного прокси-сервера для серверов на стороне локальной сети этого шлюза.
Общая конфигурация, в проформе, выглядит так:
$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#Использование-переменных
Заголовки запроса
setenv.add-request-header
выглядит привлекательно:
https://redmine.lighttpd.net/projects/lighttpd/wiki/Docs_ModSetEnv
Если shared.conf
мы установим пользовательский заголовок запроса, возможно, мы сможем проверить его с помощью $REQUEST_HEADER["header"]
in 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. Вы могли бы иметь свою "общую" конфигурацию, обрабатывающую определенные запросы (в вашем пользовательском скрипте lua) до lighttpd mod_proxy.
Кстати, следующее наивное решение тоже работает? Общая конфигурация:
$HTTP["url"] =~ "^/topdir/subir/" {
server.document-root = "/www/sharedstuff"
}
в shared.conf включен в lighttpd.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
}