diff --git a/examples/dynamic_asset.rs b/examples/dynamic_asset.rs index 1c004e015..51dcfac3a 100644 --- a/examples/dynamic_asset.rs +++ b/examples/dynamic_asset.rs @@ -1,28 +1,26 @@ use dioxus::prelude::*; -use dioxus_desktop::wry::http::Response; -use dioxus_desktop::{use_asset_handler, AssetRequest}; -use std::path::Path; +use dioxus_desktop::{use_asset_handler, wry::http::Response}; fn main() { dioxus_desktop::launch(app); } fn app(cx: Scope) -> Element { - use_asset_handler(cx, |request: &AssetRequest| { - let path = request.path().to_path_buf(); - async move { - if path != Path::new("logo.png") { - return None; - } - let image_data: &[u8] = include_bytes!("./assets/logo.png"); - Some(Response::new(image_data.into())) + use_asset_handler(cx, "logos", |request, response| { + // Note that the "logos" prefix is stripped from the URI + // + // However, the asset is absolute to its "virtual folder" - meaning it starts with a leading slash + if request.uri().path() != "/logo.png" { + return; } + + response.respond(Response::new(include_bytes!("./assets/logo.png").to_vec())); }); cx.render(rsx! { div { img { - src: "logo.png" + src: "/logos/logo.png" } } }) diff --git a/packages/desktop/src/protocol.rs b/packages/desktop/src/protocol.rs index b06bdbcb3..06304cdd2 100644 --- a/packages/desktop/src/protocol.rs +++ b/packages/desktop/src/protocol.rs @@ -1,7 +1,7 @@ use crate::{assets::*, edits::EditQueue}; use std::path::{Path, PathBuf}; use wry::{ - http::{status::StatusCode, Request, Response}, + http::{status::StatusCode, Request, Response, Uri}, RequestAsyncResponder, Result, }; @@ -59,7 +59,7 @@ pub(super) fn index_request( /// - If that doesn't match, tries a user provided asset handler /// - If that doesn't match, tries to serve a file from the filesystem pub(super) fn desktop_handler( - request: Request>, + mut request: Request>, asset_handlers: AssetHandlerRegistry, edit_queue: &EditQueue, responder: RequestAsyncResponder, @@ -83,6 +83,13 @@ pub(super) fn desktop_handler( if let Some(name) = name.to_str() { if asset_handlers.has_handler(name) { + // Trim the leading path from the URI + // + // I hope this is reliable! + // + // so a request for /assets/logos/logo.png?query=123 will become /logos/logo.png?query=123 + strip_uri_prefix(&mut request, name); + return asset_handlers.handle_request(name, request, responder); } } @@ -114,6 +121,26 @@ fn serve_from_fs(path: PathBuf) -> Result>> { .body(std::fs::read(asset)?)?) } +fn strip_uri_prefix(request: &mut Request>, name: &str) { + // trim the leading path + if let Some(path) = request.uri().path_and_query() { + let new_path = path + .path() + .trim_start_matches('/') + .strip_prefix(name) + .expect("expected path to have prefix"); + + let new_uri = Uri::builder() + .scheme(request.uri().scheme_str().unwrap_or("http")) + .path_and_query(format!("{}{}", new_path, path.query().unwrap_or(""))) + .authority("index.html") + .build() + .expect("failed to build new URI"); + + *request.uri_mut() = new_uri; + } +} + /// Construct the inline script that boots up the page and bridges the webview with rust code. /// /// The arguments here: