feat: add favicons, support embedded assets properly

- Refactor asset serving to check embedded assets before proxying
This commit is contained in:
2026-01-06 12:26:06 -06:00
parent c6dd1dffb0
commit be718976d6
8 changed files with 25 additions and 3 deletions
+11 -1
View File
@@ -9,10 +9,14 @@ static ERROR_PAGES: Dir = include_dir!("$CARGO_MANIFEST_DIR/web/build/prerendere
pub async fn serve_embedded_asset(uri: Uri) -> Response {
let path = uri.path();
serve_asset_by_path(path)
}
/// Serve an embedded asset by path, or return None if not found
pub fn try_serve_embedded_asset(path: &str) -> Option<Response> {
let asset_path = path.strip_prefix('/').unwrap_or(path);
if let Some(file) = CLIENT_ASSETS.get_file(asset_path) {
CLIENT_ASSETS.get_file(asset_path).map(|file| {
let mime_type = mime_guess::from_path(asset_path)
.first_or_octet_stream()
.as_ref()
@@ -39,6 +43,12 @@ pub async fn serve_embedded_asset(uri: Uri) -> Response {
}
(StatusCode::OK, headers, file.contents()).into_response()
})
}
fn serve_asset_by_path(path: &str) -> Response {
if let Some(response) = try_serve_embedded_asset(path) {
response
} else {
tracing::debug!(path, "Embedded asset not found");
(StatusCode::NOT_FOUND, "Asset not found").into_response()
+10 -1
View File
@@ -23,7 +23,7 @@ mod middleware;
mod og;
mod r2;
mod tarpit;
use assets::serve_embedded_asset;
use assets::{serve_embedded_asset, try_serve_embedded_asset};
use config::{Args, ListenAddr};
use formatter::{CustomJsonFormatter, CustomPrettyFormatter};
use health::HealthChecker;
@@ -1235,6 +1235,15 @@ async fn isr_handler(State(state): State<Arc<AppState>>, req: Request) -> Respon
return (StatusCode::NOT_FOUND, "Not found").into_response();
}
// Check if this is a static asset that exists in embedded CLIENT_ASSETS
// This handles root-level files like favicon.ico, favicon.svg, etc.
if is_static_asset(path) {
if let Some(response) = try_serve_embedded_asset(path) {
return response;
}
// If not found in embedded assets, continue to proxy (might be in Bun's static dir)
}
let bun_url = if state.downstream_url.starts_with('/') || state.downstream_url.starts_with("./")
{
if query.is_empty() {