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]]
|
[[package]]
|
||||||
name = "web-petting"
|
name = "web-petting"
|
||||||
version = "0.1.6"
|
version = "0.1.7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"chrono-tz",
|
"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> {
|
async fn serve_static(_request: Request, Path(filename): Path<String>) -> cot::Result<Response> {
|
||||||
let safe_name = filename.replace(['/', '\\', '.', ' '], "");
|
// Only allow simple filenames (no path traversal)
|
||||||
// rebuild with original extension
|
if filename.contains('/') || filename.contains('\\') || filename.contains("..") {
|
||||||
let ext = filename.rsplit('.').next().unwrap_or("");
|
return Html::new("404").into_response();
|
||||||
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(),
|
|
||||||
}
|
}
|
||||||
|
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> {
|
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