This commit is contained in:
Muhammad Hamza 2022-05-08 18:53:35 +05:00 committed by GitHub
parent 333af62e20
commit 3760c5f8b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 45 additions and 20 deletions

View File

@ -16,7 +16,9 @@ wasm-logger = "0.2"
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
tokio = { version = "1.15.0", features = ["full"] }
warp = "0.3"
axum = "0.5"
tower = { version = "0.4", features = ["make"] }
tower-http = { version = "0.3", features = ["fs"] }
env_logger = "0.9"
num_cpus = "1.13"
tokio-util = { version = "0.7", features = ["rt"] }

View File

@ -1,11 +1,20 @@
use std::collections::HashMap;
use std::path::PathBuf;
use axum::body::Body;
use axum::error_handling::HandleError;
use axum::extract::Query;
use axum::handler::Handler;
use axum::http::{Request, StatusCode};
use axum::response::Html;
use axum::routing::get;
use axum::{Extension, Router};
use clap::Parser;
use function_router::{ServerApp, ServerAppProps};
use once_cell::sync::Lazy;
use tokio_util::task::LocalPoolHandle;
use warp::Filter;
use tower::ServiceExt;
use tower_http::services::ServeDir;
// We spawn a local pool that is as big as the number of cpu threads.
static LOCAL_POOL: Lazy<LocalPoolHandle> = Lazy::new(|| LocalPoolHandle::new(num_cpus::get()));
@ -14,12 +23,16 @@ static LOCAL_POOL: Lazy<LocalPoolHandle> = Lazy::new(|| LocalPoolHandle::new(num
#[derive(Parser, Debug)]
struct Opt {
/// the "dist" created by trunk directory to be served for hydration.
#[structopt(short, long, parse(from_os_str))]
#[clap(short, long, parse(from_os_str))]
dir: PathBuf,
}
async fn render(index_html_s: &str, url: &str, queries: HashMap<String, String>) -> String {
let url = url.to_string();
async fn render(
Extension(index_html_s): Extension<String>,
url: Request<Body>,
Query(queries): Query<HashMap<String, String>>,
) -> Html<String> {
let url = url.uri().to_string();
let content = LOCAL_POOL
.spawn_pinned(move || async move {
@ -37,7 +50,7 @@ async fn render(index_html_s: &str, url: &str, queries: HashMap<String, String>)
// Good enough for an example, but developers should avoid the replace and extra allocation
// here in an actual app.
index_html_s.replace("<body>", &format!("<body>{}", content))
Html(index_html_s.replace("<body>", &format!("<body>{}", content)))
}
#[tokio::main]
@ -50,23 +63,33 @@ async fn main() {
.await
.expect("failed to read index.html");
let render = move |s: warp::filters::path::FullPath, queries: HashMap<String, String>| {
let index_html_s = index_html_s.clone();
async move { warp::reply::html(render(&index_html_s, s.as_str(), queries).await) }
let handle_error = |e| async move {
(
StatusCode::INTERNAL_SERVER_ERROR,
format!("error occurred: {}", e),
)
};
let html = warp::path::end().and(
warp::path::full()
.and(warp::filters::query::query())
.then(render.clone()),
);
let routes = html.or(warp::fs::dir(opts.dir)).or(warp::path::full()
.and(warp::filters::query::query())
.then(render));
let app = Router::new()
.route("/api/test", get(|| async move { "Hello World" }))
// needed because https://github.com/tower-rs/tower-http/issues/262
.route("/", get(render))
.fallback(HandleError::new(
ServeDir::new(opts.dir)
.append_index_html_on_directories(false)
.fallback(
render
.layer(Extension(index_html_s))
.into_service()
.map_err(|err| -> std::io::Error { match err {} }),
),
handle_error,
));
println!("You can view the website at: http://localhost:8080/");
warp::serve(routes).run(([127, 0, 0, 1], 8080)).await;
axum::Server::bind(&"0.0.0.0:8080".parse().unwrap())
.serve(app.into_make_service())
.await
.unwrap();
}