Forráskód Böngészése

feat: default asset server

Jonathan Kelley 3 éve
szülő
commit
430cde7068

BIN
examples/assets/logo.png


+ 18 - 0
examples/custom_assets.rs

@@ -0,0 +1,18 @@
+use dioxus::prelude::*;
+
+fn main() {
+    dioxus::desktop::launch(app);
+}
+
+fn app(cx: Scope) -> Element {
+    let (disabled, set_disabled) = use_state(&cx, || false);
+
+    cx.render(rsx! {
+        div {
+            "hi"
+            img {
+                src: "examples/../../../assets/logo.png",
+            }
+        }
+    })
+}

+ 4 - 3
packages/desktop/Cargo.toml

@@ -12,7 +12,7 @@ keywords = ["dom", "ui", "gui", "react", "wasm"]
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
 [dependencies]
-dioxus-core = { path = "../core", version ="^0.1.7", features = ["serialize"] }
+dioxus-core = { path = "../core", version = "^0.1.7", features = ["serialize"] }
 argh = "0.1.4"
 serde = "1.0.120"
 serde_json = "1.0.61"
@@ -27,9 +27,10 @@ tokio = { version = "1.12.0", features = [
     "rt",
     "time",
 ], optional = true, default-features = false }
-dioxus-core-macro = { path = "../core-macro", version ="^0.1.6"}
-dioxus-html = { path = "../html", features = ["serialize"], version ="^0.1.4"}
+dioxus-core-macro = { path = "../core-macro", version = "^0.1.6" }
+dioxus-html = { path = "../html", features = ["serialize"], version = "^0.1.4" }
 webbrowser = "0.5.5"
+mime_guess = "2.0.3"
 
 [features]
 default = ["tokio_runtime"]

+ 30 - 5
packages/desktop/src/lib.rs

@@ -210,18 +210,43 @@ pub fn launch_with_props<P: 'static + Send>(
                         // For now, we only serve two pieces of content which get included as bytes into the final binary.
                         let path = request.uri().replace("dioxus://", "");
 
-                        if path.trim_end_matches('/') == "index.html" {
+                        // all assets shouldbe called from index.html
+                        let trimmed = path.trim_start_matches("index.html/");
+
+                        if trimmed.is_empty() {
                             wry::http::ResponseBuilder::new()
                                 .mimetype("text/html")
                                 .body(include_bytes!("./index.html").to_vec())
-                        } else if path.trim_end_matches('/') == "index.html/index.js" {
+                        } else if trimmed == "index.js" {
                             wry::http::ResponseBuilder::new()
                                 .mimetype("text/javascript")
                                 .body(include_bytes!("../../jsinterpreter/interpreter.js").to_vec())
                         } else {
-                            wry::http::ResponseBuilder::new()
-                                .status(wry::http::status::StatusCode::NOT_FOUND)
-                                .body(format!("Not found: {}", path).as_bytes().to_vec())
+                            // Read the file content from file path
+                            use std::fs::read;
+
+                            let path_buf = std::path::Path::new(trimmed).canonicalize()?;
+                            let cur_path = std::path::Path::new(".").canonicalize()?;
+
+                            if !path_buf.starts_with(cur_path) {
+                                return wry::http::ResponseBuilder::new()
+                                    .status(wry::http::status::StatusCode::FORBIDDEN)
+                                    .body(String::from("Forbidden").into_bytes());
+                            }
+
+                            if !path_buf.exists() {
+                                return wry::http::ResponseBuilder::new()
+                                    .status(wry::http::status::StatusCode::NOT_FOUND)
+                                    .body(String::from("Not Found").into_bytes());
+                            }
+
+                            let mime = mime_guess::from_path(&path_buf).first_or_octet_stream();
+
+                            // do not let path searching to go two layers beyond the caller level
+                            let data = read(path_buf)?;
+                            let meta = format!("{mime}");
+
+                            wry::http::ResponseBuilder::new().mimetype(&meta).body(data)
                         }
                     })
                     .with_file_drop_handler(move |window, evet| {