static_files_module/
configuration.rs

1// Copyright 2024 Wladimir Palant
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Data structures required for `StaticFilesHandler` configuration
16
17use serde::Deserialize;
18use std::path::PathBuf;
19use structopt::StructOpt;
20
21use crate::compression_algorithm::CompressionAlgorithm;
22
23/// Command line options of the static files module
24#[derive(Debug, Default, StructOpt)]
25pub struct StaticFilesOpt {
26    /// The root directory.
27    #[structopt(short, long, parse(from_os_str))]
28    pub root: Option<PathBuf>,
29
30    /// Redirect /file%2e.txt to /file.txt and /dir to /dir/.
31    #[structopt(long)]
32    pub canonicalize_uri: Option<bool>,
33
34    /// Index file to look for when displaying a directory. This command line flag can be specified
35    /// multiple times.
36    #[structopt(long)]
37    pub index_file: Option<Vec<String>>,
38
39    /// URI path of the page to display instead of the default Not Found page, e.g. /404.html
40    #[structopt(long)]
41    pub page_404: Option<String>,
42
43    /// File extension to check when looking for pre-compressed versions of a file. This command
44    /// line flag can be specified multiple times. Supported file extensions are gz (gzip),
45    /// zz (zlib deflate), z (compress), br (Brotli), zst (Zstandard).
46    #[structopt(long)]
47    pub precompressed: Option<Vec<CompressionAlgorithm>>,
48}
49
50/// Configuration file settings of the static files module
51#[derive(Debug, PartialEq, Eq, Deserialize)]
52#[serde(default)]
53pub struct StaticFilesConf {
54    /// The root directory.
55    pub root: Option<PathBuf>,
56
57    /// Redirect /file%2e.txt to /file.txt and /dir to /dir/.
58    pub canonicalize_uri: bool,
59
60    /// When `canonicalize_uri` is used, prefix redirect targets with the given string. This is
61    /// useful when the static files handler is applied to a subdirectory of the actual webspace.
62    pub redirect_prefix: Option<String>,
63
64    /// List of index files to look for in a directory.
65    pub index_file: Vec<String>,
66
67    /// URI path of the page to display instead of the default Not Found page, e.g. /404.html
68    pub page_404: Option<String>,
69
70    /// List of file extensions to check when looking for pre-compressed versions of a file.
71    /// Supported file extensions are gz (gzip), zz (zlib deflate), z (compress), br (Brotli),
72    /// zst (Zstandard).
73    pub precompressed: Vec<CompressionAlgorithm>,
74}
75
76impl StaticFilesConf {
77    /// Merges the command line options into the current configuration. Any command line options
78    /// present overwrite existing settings.
79    pub fn merge_with_opt(&mut self, opt: StaticFilesOpt) {
80        if opt.root.is_some() {
81            self.root = opt.root;
82        }
83
84        if let Some(canonicalize_uri) = opt.canonicalize_uri {
85            self.canonicalize_uri = canonicalize_uri;
86        }
87
88        if let Some(index_file) = opt.index_file {
89            self.index_file = index_file;
90        }
91
92        if opt.page_404.is_some() {
93            self.page_404 = opt.page_404;
94        }
95
96        if let Some(precompressed) = opt.precompressed {
97            self.precompressed = precompressed;
98        }
99    }
100}
101
102impl Default for StaticFilesConf {
103    fn default() -> Self {
104        Self {
105            root: None,
106            canonicalize_uri: true,
107            redirect_prefix: None,
108            index_file: vec!["index.html".into()],
109            page_404: None,
110            precompressed: Vec::new(),
111        }
112    }
113}