Skip to content

Commit

Permalink
chore: avoid using format when building asset paths and double-check …
Browse files Browse the repository at this point in the history
…path (#228)

Signed-off-by: Angel M De Miguel <[email protected]>
  • Loading branch information
Angelmmiguel authored Oct 4, 2023
1 parent 451f67a commit 253b727
Showing 1 changed file with 21 additions and 7 deletions.
28 changes: 21 additions & 7 deletions crates/server/src/handlers/assets.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
// Copyright 2022 VMware, Inc.
// Copyright 2022-2023 VMware, Inc.
// SPDX-License-Identifier: Apache-2.0

use crate::AppData;
use actix_files::NamedFile;
use actix_web::{web::Data, HttpRequest};
use std::io::{Error, ErrorKind};
use std::path::{Component, Path};

/// Checks if the given component is not normal or absolute. If the component
/// is not valid, it returns true.
fn component_is_valid(component: Component) -> bool {
matches!(component, Component::Normal(_) | Component::RootDir)
}

/// Find a static HTML file in the `public` folder. This function is used
/// when there's no direct file to be served. It will look for certain patterns
Expand All @@ -18,19 +25,26 @@ pub async fn handle_assets(req: &HttpRequest) -> Result<NamedFile, Error> {
.root_path;
let uri_path = req.path();

// Parse the URI as a filesystem path
let parsed_path = Path::new(uri_path);

// Double-check the given path path does not contain any unexpected value.
// It was previously sanitized, but this is a double check.
if !parsed_path.components().all(component_is_valid) {
return Err(Error::new(ErrorKind::NotFound, "The file is not present"));
}

let public_folder = root_path.join("public");

// File path. This is required for the wasm_handler as dynamic routes may capture static files
let file_path = root_path.join(format!("public{uri_path}"));
let file_path = public_folder.join(parsed_path);
// A.k.a pretty urls. We may access /about and this matches to /about/index.html
let index_folder_path = root_path.join(format!("public{uri_path}/index.html"));
// Same as before, but the file is located at ./about.html
let html_ext_path = root_path.join(format!("public{uri_path}.html"));
let index_folder_path = public_folder.join(parsed_path).join("index.html");

if file_path.exists() {
NamedFile::open_async(file_path).await
} else if uri_path.ends_with('/') && index_folder_path.exists() {
NamedFile::open_async(index_folder_path).await
} else if !uri_path.ends_with('/') && html_ext_path.exists() {
NamedFile::open_async(html_ext_path).await
} else {
Err(Error::new(ErrorKind::NotFound, "The file is not present"))
}
Expand Down

0 comments on commit 253b727

Please sign in to comment.