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}