From 52a292a4d56723ac46ec5e570a3d5a51650d090a Mon Sep 17 00:00:00 2001 From: Michael Zhang Date: Thu, 10 Aug 2023 18:25:47 -0500 Subject: [PATCH] embed --- .gitignore | 3 +- Cargo.lock | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 2 ++ package.json | 3 +- src/main.rs | 75 ++++++++++++++++++++++++++++++++++----------- src/message.rs | 4 +-- 6 files changed, 149 insertions(+), 21 deletions(-) diff --git a/.gitignore b/.gitignore index 50b6338..c2fec07 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target -/node_modules \ No newline at end of file +/node_modules +/dist \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index c5dfadf..835dc49 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -510,7 +510,9 @@ dependencies = [ "derivative", "flume", "futures", + "mime_guess", "mzlib", + "rust-embed", "serde", "serde_bytes", "serde_json", @@ -744,6 +746,16 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "mime_guess" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" +dependencies = [ + "mime", + "unicase", +] + [[package]] name = "miniz_oxide" version = "0.7.1" @@ -940,6 +952,40 @@ dependencies = [ "bitflags", ] +[[package]] +name = "rust-embed" +version = "6.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a36224c3276f8c4ebc8c20f158eca7ca4359c8db89991c4925132aaaf6702661" +dependencies = [ + "rust-embed-impl", + "rust-embed-utils", + "walkdir", +] + +[[package]] +name = "rust-embed-impl" +version = "6.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49b94b81e5b2c284684141a2fb9e2a31be90638caf040bf9afbc5a0416afe1ac" +dependencies = [ + "proc-macro2", + "quote", + "rust-embed-utils", + "syn 2.0.28", + "walkdir", +] + +[[package]] +name = "rust-embed-utils" +version = "7.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d38ff6bf570dc3bb7100fce9f7b60c33fa71d80e88da3f2580df4ff2bdded74" +dependencies = [ + "sha2", + "walkdir", +] + [[package]] name = "rustc-demangle" version = "0.1.23" @@ -958,6 +1004,15 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "scopeguard" version = "1.2.0" @@ -1332,6 +1387,15 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +[[package]] +name = "unicase" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" +dependencies = [ + "version_check", +] + [[package]] name = "unicode-bidi" version = "0.3.13" @@ -1386,6 +1450,16 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "walkdir" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "want" version = "0.3.1" @@ -1477,6 +1551,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" diff --git a/Cargo.toml b/Cargo.toml index 58c75ba..c0db2d2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,8 @@ dashmap = "5.5.0" derivative = "2.2.0" flume = "0.10.14" futures = "0.3.28" +mime_guess = "2.0.4" +rust-embed = "6.8.1" serde = { version = "1.0.183", features = ["derive"] } serde_bytes = "0.11.12" serde_json = "1.0.104" diff --git a/package.json b/package.json index c8b3de4..3b0d007 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,7 @@ { "scripts": { - "dev": "vite" + "dev": "vite", + "build": "vite build" }, "devDependencies": { "@types/libsodium-wrappers": "^0.7.10", diff --git a/src/main.rs b/src/main.rs index cbbfcbf..5806e7c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,7 +7,7 @@ use std::{io::Cursor, mem, sync::Arc}; use automerge::{ sync::{State as SyncState, SyncDoc}, - Automerge, Value, + Automerge, }; use axum::{ extract::{ @@ -18,9 +18,10 @@ use axum::{ routing::get, Router, }; -use chrono::{DateTime, Utc}; +use chrono::Utc; use dashmap::{DashMap, DashSet}; use flume::r#async::SendSink; +use frontend::frontend; use futures::{stream, FutureExt, SinkExt, StreamExt}; use message::Message; use mzlib::axum_error::Result; @@ -61,7 +62,10 @@ impl Room { async fn main() -> Result<()> { let state = AppState::default(); - let app = Router::new().route("/ws", get(handler)).with_state(state); + let app = Router::new() + .route("/ws", get(handler)) + .fallback(frontend) + .with_state(state); axum::Server::bind(&"0.0.0.0:3100".parse().unwrap()) .serve(app.into_make_service()) @@ -70,6 +74,45 @@ async fn main() -> Result<()> { Ok(()) } +#[allow(non_upper_case_globals)] +mod frontend { + use axum::{ + body::{Body, HttpBody}, + http::{header::CONTENT_TYPE, HeaderMap, HeaderValue, StatusCode, Uri}, + response::IntoResponse, + }; + use rust_embed::RustEmbed; + + #[derive(RustEmbed)] + #[folder = "dist/"] + struct Frontend; + + pub async fn frontend(uri: Uri) -> impl IntoResponse { + let path = uri.path().trim_start_matches("/").to_owned(); + + match Frontend::get(&path).or_else(|| Frontend::get("index.html")) { + Some(file) => { + let guess = mime_guess::from_path(path); + let mut headers = HeaderMap::default(); + if let Some(guess) = guess.first() { + headers.append( + CONTENT_TYPE, + HeaderValue::from_str(&guess.to_string()).unwrap(), + ); + } + + let data = file.data.as_ref(); + let body = Body::from(data.to_owned()); + let body = body.boxed(); + (headers, body).into_response() + } + None => { + (StatusCode::NOT_FOUND, format!("No route for {}", uri)).into_response() + } + } + } +} + async fn handler( ws: WebSocketUpgrade, State(state): State, @@ -78,7 +121,7 @@ async fn handler( } async fn handle_socket(state: AppState, socket: WebSocket) -> Result<()> { - let (mut socket_tx, socket_rx) = socket.split(); + let (socket_tx, socket_rx) = socket.split(); // Generate an ID for this connection let client_id = Uuid::new_v4(); @@ -148,7 +191,7 @@ async fn handle_socket(state: AppState, socket: WebSocket) -> Result<()> { // println!("inner doc: {:?}", room.document); // Remove current client, so send to everyone else - let mut connected_clients = room.connected_clients.clone(); + let connected_clients = room.connected_clients.clone(); connected_clients.remove(client_id); // Send to everyone else @@ -183,11 +226,11 @@ async fn handle_socket(state: AppState, socket: WebSocket) -> Result<()> { } Message::ChatMessage { - timestamp, - message_id, + timestamp: _, + message_id: _, room_id, - author, - content, + author: _, + content: _, } => { let room = state .rooms @@ -217,17 +260,15 @@ async fn handle_socket(state: AppState, socket: WebSocket) -> Result<()> { connected_clients.remove(&client_id); match &message { - Message::FileUploadBegin { header, .. } => { - match room.current_uploader { - Some(v) if v == client_id => {} - Some(v) => continue, - None => room.current_uploader = Some(client_id.clone()), - } - } + Message::FileUploadBegin { .. } => match room.current_uploader { + Some(v) if v == client_id => {} + Some(_v) => continue, + None => room.current_uploader = Some(client_id.clone()), + }, Message::FileUploadComplete { .. } => { room.current_uploader = None; } - Message::FileUploadChunk { data, .. } => {} + Message::FileUploadChunk { .. } => {} _ => {} }; diff --git a/src/message.rs b/src/message.rs index f0586ed..de33cf0 100644 --- a/src/message.rs +++ b/src/message.rs @@ -1,10 +1,10 @@ use std::collections::HashSet; -use std::fmt::{write, Formatter}; +use std::fmt::{Formatter}; use std::io::Cursor; use axum::extract::ws; use chrono::{DateTime, Utc}; -use ciborium::Value; + use mzlib::axum_error::Result; use serde::de::Visitor; use serde::{Deserialize, Deserializer, Serialize, Serializer};