Description
Search for duplicate feature request
- I already searched, and this feature request or improvement is not a duplicate.
Feature scope
Improve existing functionality
Feature request related to a problem
I intend to extend the existing virtual hosts functionality to make it more useful. One change would be introducing a subdir
parameter, allowing to limit the settings not merely to a virtual host but to a directory within it.
The available settings should go beyond root
. IMHO it should be possible to optionally specify the following settings here:
compression
page404
page50x
directory-listing
directory-listing-order
directory-listing-format
basic-auth
page-fallback
redirect-trailing-slash
compression-static
health
index-files
maintenance-mode
maintenance-mode-status
maintenance-mode-file
Some of these options require moving rewrite processing up, so that it happens before the health check for example. Let me know what you think.
Describe the solution you'd like
Much of the current RequestHandlerOpts
structure would move into a LocalOpts
structure with all fields optional. We would have a LocalOpts
structure for the root level (global settings) as well as for each virtual host/subdir combination. These can be stored efficiently in a Radix tree, with "{vhost}/{subdir}"
used as key (""
for the settings root). There is a number of Rust crates implementing the Radix tree data structure, I’d need to check whether any of them meet the requirements.
When handling a request, we would take "{vhost}/{subdir}"
as key for the current request and find the longest prefix for it in the Radix tree. We would collect all the LocalOpts
instances found along the path to that longest prefix and merge them: if somewhere further down the path a field is set (is_some()
), then it always overrides the existing value. We can special-case the scenario where only the root LocalOpts
apply and skip the merging then – this will make certain there is no performance degradation if virtual hosts aren’t used.
The downside is still that we would have a bunch of Option
fields in LocalOpts
that might not be set. We can solve this by providing field retrieval methods like the following:
fn page404(&self) -> &Path {
const DEFAULT: PathBuf = PathBuf::from("./404.html");
self.page404.as_ref().unwrap_or(&DEFAULT)
}
The RequestHandlerOpts
data structure and the corresponding handler are public, so we are talking about breaking changes of course.
Build target
All targets