summaryrefslogtreecommitdiff
path: root/src/collect_files.rs
diff options
context:
space:
mode:
authorBen Bridle <bridle.benjamin@gmail.com>2025-01-18 12:04:07 +1300
committerBen Bridle <bridle.benjamin@gmail.com>2025-01-18 12:04:07 +1300
commit3765c30ef322c31456aa419e970955330a1461ad (patch)
treef241e990b8ea3eaae01b89647956ab68d63b7499 /src/collect_files.rs
parent9717476273e05379ada099946307ae2682b8abef (diff)
downloadtoaster-3765c30ef322c31456aa419e970955330a1461ad.zip
Check that links to static files are valid
When a link doesn't contain a protocol, it's assumed to be a link to a relative or absolute path to an internal static file. This link is checked against the list of collected static files to ensure that it exists. For an unlabelled link to an internal static file, the label will be the file name without preceding path segments.
Diffstat (limited to 'src/collect_files.rs')
-rw-r--r--src/collect_files.rs56
1 files changed, 37 insertions, 19 deletions
diff --git a/src/collect_files.rs b/src/collect_files.rs
index 64cfc30..9aa4983 100644
--- a/src/collect_files.rs
+++ b/src/collect_files.rs
@@ -273,27 +273,9 @@ impl Website {
if !path.starts_with('/') {
path = format!("{}{path}", from.parent_url());
}
+ let path = make_url_safe(&collapse_path(&path));
- // Iteratively collapse ".." segments.
- let mut segments: Vec<&str> = path.split('/')
- .filter(|s| !s.is_empty() && *s != ".")
- .collect();
- 'outer: loop {
- for i in 0..(segments.len().saturating_sub(1)) {
- if segments[i] == ".." {
- if i == 0 {
- segments.remove(0);
- } else {
- segments.remove(i-1);
- segments.remove(i-1);
- }
- continue 'outer;
- }
- }
- break;
- }
// Find page with this path in website.
- let path = make_url_safe(&segments.join("/"));
for page in &self.pages {
if page.full_url == path {
let root = from.root();
@@ -310,6 +292,21 @@ impl Website {
return None;
}
+ pub fn has_static(&self, from: &impl LinkFrom, path: &str) -> Option<String> {
+ // Attach parent if not an absolute path.
+ let path = match !path.starts_with('/') {
+ true => collapse_path(&format!("{}{path}", make_url_safe(from.parent_url()))),
+ false => collapse_path(path),
+ };
+ for file in &self.static_files {
+ if file.full_url == path {
+ let root = from.root();
+ return Some(format!("{root}{path}"));
+ }
+ }
+ return None;
+ }
+
pub fn has_image(&self, file_name: &str) -> bool {
let image_path = format!("images/thumb/{file_name}");
self.static_files.iter().any(|s| s.full_url == image_path)
@@ -320,3 +317,24 @@ impl Website {
}
}
+
+fn collapse_path(path: &str) -> String {
+ // Iteratively collapse ".." segments.
+ let mut segments: Vec<&str> = path.split('/')
+ .filter(|s| !s.is_empty() && *s != ".")
+ .collect();
+ 'outer: loop {
+ for i in 0..(segments.len().saturating_sub(1)) {
+ if segments[i] == ".." {
+ if i == 0 {
+ segments.remove(0);
+ } else {
+ segments.remove(i-1);
+ segments.remove(i-1);
+ }
+ continue 'outer;
+ }
+ }
+ return segments.join("/");
+ }
+}