Service index.html on 404 (for SPA)

This commit is contained in:
Joshua Kifer committed 2022-03-26 18:33:18 -06:00
1 parent 962ab2726a
commit 70fdfabd18
3 files changed
+57 -18

No files matched your search

+2
View File
@@ -37,6 +37,8 @@ hyper = "0.14.17"
axum = { version = "0.4.5", features = ["ws", "headers"] } axum = { version = "0.4.5", features = ["ws", "headers"] }
tower-http = { version = "0.2.2", features = ["fs", "trace"] } tower-http = { version = "0.2.2", features = ["fs", "trace"] }
headers = "0.3.7" headers = "0.3.7"
tower = "0.4.12"
# hyper = { version = "0.14.11", features = ["full"] } # hyper = { version = "0.14.11", features = ["full"] }
[[bin]] [[bin]]
+2
View File
@@ -42,6 +42,7 @@ impl Default for DioxusConfig {
watcher: WebWatcherConfing { watcher: WebWatcherConfing {
watch_path: Some(vec![PathBuf::from("src")]), watch_path: Some(vec![PathBuf::from("src")]),
reload_html: Some(false), reload_html: Some(false),
index_on_404: Some(false),
}, },
resource: WebResourceConfing { resource: WebResourceConfing {
dev: WebDevResourceConfing { dev: WebDevResourceConfing {
@@ -80,6 +81,7 @@ pub struct WebAppConfing {
pub struct WebWatcherConfing { pub struct WebWatcherConfing {
pub watch_path: Option<Vec<PathBuf>>, pub watch_path: Option<Vec<PathBuf>>,
pub reload_html: Option<bool>, pub reload_html: Option<bool>,
pub index_on_404: Option<bool>,
} }
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
+53 -18
View File
@@ -1,6 +1,7 @@
use axum::{ use axum::{
body::{Full, HttpBody},
extract::{ws::Message, Extension, TypedHeader, WebSocketUpgrade}, extract::{ws::Message, Extension, TypedHeader, WebSocketUpgrade},
http::StatusCode, http::{Response, StatusCode},
response::IntoResponse, response::IntoResponse,
routing::{get, get_service}, routing::{get, get_service},
Router, Router,
@@ -8,7 +9,8 @@ use axum::{
use notify::{RecommendedWatcher, Watcher}; use notify::{RecommendedWatcher, Watcher};
use std::{path::PathBuf, sync::Arc}; use std::{path::PathBuf, sync::Arc};
use tower_http::services::ServeDir; use tower::ServiceBuilder;
use tower_http::services::fs::{ServeDir, ServeFileSystemResponseBody};
use crate::{builder, serve::Serve, CrateConfig, Result}; use crate::{builder, serve::Serve, CrateConfig, Result};
use tokio::sync::broadcast; use tokio::sync::broadcast;
@@ -74,23 +76,56 @@ pub async fn startup(config: CrateConfig) -> Result<()> {
let port = "8080"; let port = "8080";
log::info!("📡 Dev-Server is started at: http://127.0.0.1:{}/", port); log::info!("📡 Dev-Server is started at: http://127.0.0.1:{}/", port);
axum::Server::bind(&format!("0.0.0.0:{}", port).parse().unwrap()) let file_service_config = config.clone();
.serve( let file_service = ServiceBuilder::new()
Router::new() .and_then(
.route("/_dioxus/ws", get(ws_handler)) |response: Response<ServeFileSystemResponseBody>| async move {
.fallback( let response = if file_service_config
get_service(ServeDir::new(config.crate_dir.join(&dist_path))).handle_error( .dioxus_config
|error: std::io::Error| async move { .web
( .watcher
StatusCode::INTERNAL_SERVER_ERROR, .index_on_404
format!("Unhandled internal error: {}", error), .unwrap_or(false)
) && response.status() == StatusCode::NOT_FOUND
}, {
), let body = Full::from(
) // TODO: Cache/memoize this.
.layer(Extension(ws_reload_state)) std::fs::read_to_string(
.into_make_service(), file_service_config
.crate_dir
.join(file_service_config.out_dir)
.join("index.html"),
)
.ok()
.unwrap(),
)
.map_err(|err| match err {})
.boxed();
Response::builder()
.status(StatusCode::OK)
.body(body)
.unwrap()
} else {
response.map(|body| body.boxed())
};
Ok(response)
},
) )
.service(ServeDir::new((&config.crate_dir).join(&dist_path)));
let router = Router::new()
.route("/_dioxus/ws", get(ws_handler))
.fallback(
get_service(file_service).handle_error(|error: std::io::Error| async move {
(
StatusCode::INTERNAL_SERVER_ERROR,
format!("Unhandled internal error: {}", error),
)
}),
);
axum::Server::bind(&format!("0.0.0.0:{}", port).parse().unwrap())
.serve(router.layer(Extension(ws_reload_state)).into_make_service())
.await?; .await?;
Ok(()) Ok(())