fixed docker build static
Build and Publish / Build and Publish Docker Image (push) Successful in 1m47s
Build and Publish / Build and Publish Docker Image (push) Successful in 1m47s
This commit is contained in:
Generated
+1
-1
@@ -3255,7 +3255,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "web-petting"
|
||||
version = "0.1.6"
|
||||
version = "0.1.7"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"chrono-tz",
|
||||
|
||||
+28
-25
@@ -395,32 +395,35 @@ async fn favicon(_request: Request) -> cot::Result<Response> {
|
||||
}
|
||||
|
||||
async fn serve_static(_request: Request, Path(filename): Path<String>) -> cot::Result<Response> {
|
||||
let safe_name = filename.replace(['/', '\\', '.', ' '], "");
|
||||
// rebuild with original extension
|
||||
let ext = filename.rsplit('.').next().unwrap_or("");
|
||||
let _stem = filename.rsplit('.').last().unwrap_or("");
|
||||
let _ = safe_name; // just for validation idea; use the path directly with whitelist
|
||||
let path = format!("static/{}", filename);
|
||||
match tokio::fs::read(&path).await {
|
||||
Ok(data) => {
|
||||
let content_type = match ext {
|
||||
"png" => "image/png",
|
||||
"jpg" | "jpeg" => "image/jpeg",
|
||||
"webp" => "image/webp",
|
||||
"svg" => "image/svg+xml",
|
||||
"gif" => "image/gif",
|
||||
_ => "application/octet-stream",
|
||||
};
|
||||
let body = cot::Body::fixed(data);
|
||||
let mut resp = Response::new(body);
|
||||
resp.headers_mut()
|
||||
.insert("content-type", content_type.parse().unwrap());
|
||||
resp.headers_mut()
|
||||
.insert("cache-control", "public, max-age=604800".parse().unwrap());
|
||||
Ok(resp)
|
||||
}
|
||||
Err(_) => Html::new("404").into_response(),
|
||||
// Only allow simple filenames (no path traversal)
|
||||
if filename.contains('/') || filename.contains('\\') || filename.contains("..") {
|
||||
return Html::new("404").into_response();
|
||||
}
|
||||
let ext = filename.rsplit('.').next().unwrap_or("");
|
||||
// Try relative path first, then /data/static/ (Docker)
|
||||
let path = format!("static/{filename}");
|
||||
let data = match tokio::fs::read(&path).await {
|
||||
Ok(d) => d,
|
||||
Err(_) => match tokio::fs::read(format!("/data/static/{filename}")).await {
|
||||
Ok(d) => d,
|
||||
Err(_) => return Html::new("404").into_response(),
|
||||
},
|
||||
};
|
||||
let content_type = match ext {
|
||||
"png" => "image/png",
|
||||
"jpg" | "jpeg" => "image/jpeg",
|
||||
"webp" => "image/webp",
|
||||
"svg" => "image/svg+xml",
|
||||
"gif" => "image/gif",
|
||||
_ => "application/octet-stream",
|
||||
};
|
||||
let body = cot::Body::fixed(data);
|
||||
let mut resp = Response::new(body);
|
||||
resp.headers_mut()
|
||||
.insert("content-type", content_type.parse().unwrap());
|
||||
resp.headers_mut()
|
||||
.insert("cache-control", "public, max-age=604800".parse().unwrap());
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
async fn robots_txt(_request: Request, db: Database) -> cot::Result<Response> {
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 274 KiB After Width: | Height: | Size: 272 KiB |
Reference in New Issue
Block a user