summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--readme.md3
-rw-r--r--src/main.rs1
-rw-r--r--src/modules/files.rs45
3 files changed, 48 insertions, 1 deletions
diff --git a/readme.md b/readme.md
index 955deec..4817493 100644
--- a/readme.md
+++ b/readme.md
@@ -121,6 +121,9 @@ themselves; in that case the request is passed on.
prepended to the response.
- `root`: root directory to be served (string)
- `index`: enables directory indexing (boolean)
+ - `localize`: sends a localized version if possible. for localized content the
+ ISO 639-1 language code is injected in front of the first file name
+ extension (boolean) **semi-experimental**
- **module `file`**
- Replies with static content.
diff --git a/src/main.rs b/src/main.rs
index 0dcf01b..a3edd28 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,6 +1,7 @@
#![feature(try_trait_v2)]
#![feature(slice_split_once)]
#![feature(iterator_try_collect)]
+#![feature(path_add_extension)]
pub mod certs;
pub mod config;
diff --git a/src/modules/files.rs b/src/modules/files.rs
index 6336648..76ef62c 100644
--- a/src/modules/files.rs
+++ b/src/modules/files.rs
@@ -7,6 +7,7 @@ use headers::{
AcceptRanges, CacheControl, ContentLength, ContentRange, ContentType, HeaderMapExt,
LastModified,
};
+use http::header::ACCEPT_LANGUAGE;
use http_body_util::{combinators::BoxBody, BodyExt, StreamBody};
use humansize::FormatSizeOptions;
use hyper::{
@@ -48,6 +49,8 @@ struct Files {
// etag: bool,
#[serde(default)]
cache: CacheMode,
+ #[serde(default)]
+ localize: bool,
}
#[derive(Debug, Default, Deserialize)]
#[serde(rename_all = "snake_case")]
@@ -96,6 +99,9 @@ impl Node for Files {
user_path_depth += 1;
}
}
+ if self.localize {
+ path = find_localized_path(path, &request);
+ }
if !path.exists() {
return Err(ServiceError::NotFound);
}
@@ -104,7 +110,16 @@ impl Node for Files {
if metadata.file_type().is_dir() {
debug!("sending index for {path:?}");
- if let Ok(indexhtml) = read_to_string(path.join("index.html")).await {
+ if let Ok(indexhtml) = read_to_string({
+ let path = path.join("index.html");
+ if self.localize {
+ find_localized_path(path, &request)
+ } else {
+ path
+ }
+ })
+ .await
+ {
return Ok(html_string_response(indexhtml));
}
@@ -375,6 +390,34 @@ markup::define! {
}
}
+fn find_localized_path(path: PathBuf, request: &NodeRequest) -> PathBuf {
+ if let Some(al) = request.headers().get(ACCEPT_LANGUAGE) {
+ if let Ok(al) = al.to_str() {
+ for pa in al.split(",").take(5) {
+ let locale = pa.split_once(";").unwrap_or((pa, "")).0;
+ if locale
+ .chars()
+ .all(|c| matches!(c, 'A'..='Z' | 'a'..='z' | '-'))
+ {
+ let np = localized_path(&path, locale);
+ if np.exists() {
+ return np;
+ }
+ }
+ }
+ }
+ }
+ path
+}
+fn localized_path(path: &Path, locale: &str) -> PathBuf {
+ let ext = path.extension().map(|c| c.to_owned());
+ let mut path = path.with_extension(locale);
+ if let Some(ext) = ext {
+ path.add_extension(ext);
+ }
+ path
+}
+
// fn calc_etag(s: SystemTime) -> String {
// // TODO: make this not change after server restart but still unguessable
// let mut hasher = DefaultHasher::new();