I have an interesting condition resolution problem to resolve and have not had luck with on-line searching and looking through documentation for lighttpd yet. Many of those searches led to similar questions asked here and useful answers (for those questio so let's see how this one runs:
I have lighttpd running on a gateway router (OpenWRT, Or Turris OS if you prefer as it's a Turris Omnia) and it has a number of domains pointing its way which it farms out, as a revers proxy to servers on the LAN side of that gateway.
The general config being, in pro forma, like:
$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" => "..." ) ) )
...
}
That has been working a dream for ages.
Now I would like a particular path, common to all these sites to be served from this router directly.
In pro forma again:
$HTTP["url"] =~ "^/topdir/subir/" {
server.document-root = "/www/sharedstuff"
}
And I can combine this admirably as follows (and it works):
$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" => "..." ) ) )
...
}
}
Sweet.
BUT, here's the problem I'm trying to solve. I'd like ideally to encapsulate the $HTTP["url"]
condition in one included file and the $HTTP["host"]
condition in another such that I can:
include "/etc/lighttpd/conf.d/shared.conf" # contains the `$HTTP["url"]` constraint
include "/etc/lighttpd/conf.d/distributed.conf" # contains the `$HTTP["host"]` constraint
I wonder if I'm hoping for too much here. As I can't think or find of a way to do it.
I imagine if shared.conf
contained some statement such that there existed a config statement like:
$HTTP["url"] =~ "^/topdir/subir/" {
server.document-root = "/www/sharedstuff"
ignore-all-subsequent-host-match-conditions
}
Another creative, if naive and impossible, idea is if we could rewrite $HTTP["host"]
akin to:
$HTTP["host"] = "null.net"
So that subsequent matches like $HTTP["host"] =~ "(a.com|b.com|c.com)$"
all fail, and the request stays local.
Here are some options explored thus far:
Server variables
No go as these are evaluated when configuration is loaded not when requests are processed.
https://redmine.lighttpd.net/projects/1/wiki/docs_configuration#Using-variables
Request Headers
setenv.add-request-header
looks attractive:
https://redmine.lighttpd.net/projects/lighttpd/wiki/Docs_ModSetEnv
If in shared.conf
we set a custom request header perhaps we can test for it with a $REQUEST_HEADER["header"]
in distributed.conf
:
https://redmine.lighttpd.net/projects/1/wiki/docs_configuration#Conditional-Configuration
But I have not had any success with that. It seems that a conditional like this:
$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" => "..." ) ) )
...
}
Simply does not work, and I cannot really divine why. It's hard to see what's going on but if I log output on conditional handling it seems that $REQUEST_HEADER["my_header"]
is always blank even for a URL where in shared.conf
this matched:
$HTTP["url"] =~ "^/topdir/subir/" {
setenv.add-request-header = ("my_header" => "value_I_set")
}
It seems the condition doesn't test request headers set by setenv, so much as those delivered.