Jonathan Kelley преди 1 година
родител
ревизия
347351d1ee
променени са 2 файла, в които са добавени 39 реда и са изтрити 14 реда
  1. 10 12
      examples/dynamic_asset.rs
  2. 29 2
      packages/desktop/src/protocol.rs

+ 10 - 12
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"
             }
         }
     })

+ 29 - 2
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<Vec<u8>>,
+    mut request: Request<Vec<u8>>,
     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<Response<Vec<u8>>> {
         .body(std::fs::read(asset)?)?)
 }
 
+fn strip_uri_prefix(request: &mut Request<Vec<u8>>, 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: