diff --git a/config.yaml.example b/config.yaml.example index 0b72924..5420cc9 100644 --- a/config.yaml.example +++ b/config.yaml.example @@ -1,5 +1,6 @@ database_url: postgres://mitra:mitra@127.0.0.1:55432/mitra storage_dir: files +web_client_dir: null http_host: '127.0.0.1' http_port: 8380 diff --git a/contrib/mitra_config.yaml b/contrib/mitra_config.yaml index 3ebfd70..636572c 100644 --- a/contrib/mitra_config.yaml +++ b/contrib/mitra_config.yaml @@ -2,6 +2,8 @@ database_url: postgres://mitra:mitra@127.0.0.1:5432/mitra storage_dir: /var/lib/mitra +# Path to web client static files +#web_client_dir: /usr/share/mitra/www http_host: '127.0.0.1' http_port: 8383 diff --git a/src/config/main.rs b/src/config/main.rs index c4f569a..f3a2769 100644 --- a/src/config/main.rs +++ b/src/config/main.rs @@ -69,6 +69,7 @@ pub struct Config { // Core settings pub database_url: String, pub storage_dir: PathBuf, + pub web_client_dir: Option, pub http_host: String, pub http_port: u32, diff --git a/src/lib.rs b/src/lib.rs index adb4cc4..7c62f3e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,4 +18,4 @@ mod monero; pub mod nodeinfo; mod utils; pub mod webfinger; -mod web_client; +pub mod web_client; diff --git a/src/main.rs b/src/main.rs index 4d0dd7f..d5625b4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -33,6 +33,7 @@ use mitra::mastodon_api::timelines::views::timeline_api_scope; use mitra::mastodon_api::UPLOAD_MAX_SIZE; use mitra::nodeinfo::views as nodeinfo; use mitra::webfinger::views as webfinger; +use mitra::web_client::views::web_client_service; #[actix_web::main] async fn main() -> std::io::Result<()> { @@ -155,8 +156,6 @@ async fn main() -> std::io::Result<()> { .service(activitypub::actor_scope()) .service(activitypub::instance_actor_scope()) .service(activitypub::object_view) - .service(activitypub::frontend_profile_redirect) - .service(activitypub::frontend_post_redirect) .service(atom::get_atom_feed) .service(nodeinfo::get_nodeinfo) .service(nodeinfo::get_nodeinfo_2_0); @@ -169,6 +168,14 @@ async fn main() -> std::io::Result<()> { )); }; }; + if let Some(ref web_client_dir) = config.web_client_dir { + app = app.service(web_client_service(web_client_dir)); + } else { + // Enable redirects only when serving of web client is disabled + app = app + .service(activitypub::frontend_profile_redirect) + .service(activitypub::frontend_post_redirect) + }; app }) .workers(num_workers) diff --git a/src/web_client/mod.rs b/src/web_client/mod.rs index c8faf42..fd1dad8 100644 --- a/src/web_client/mod.rs +++ b/src/web_client/mod.rs @@ -1 +1,2 @@ pub mod urls; +pub mod views; diff --git a/src/web_client/views.rs b/src/web_client/views.rs new file mode 100644 index 0000000..47a90d3 --- /dev/null +++ b/src/web_client/views.rs @@ -0,0 +1,29 @@ +use std::path::Path; + +use actix_files::{Files, NamedFile}; +use actix_web::{ + dev::{fn_service, ServiceRequest, ServiceResponse}, + web::Data, +}; + +use crate::config::Config; + +pub fn web_client_service(web_client_dir: &Path) -> Files { + Files::new("/", web_client_dir) + .index_file("index.html") + .prefer_utf8(true) + .default_handler(fn_service(|service_request: ServiceRequest| { + // Workaround for https://github.com/actix/actix-web/issues/2617 + let (request, _) = service_request.into_parts(); + let index_path = request.app_data::>() + .expect("app data should contain config") + .web_client_dir.as_ref() + .expect("web_client_dir should be present in config") + .join("index.html"); + async { + let index_file = NamedFile::open_async(index_path).await?; + let response = index_file.into_response(&request); + Ok(ServiceResponse::new(request, response)) + } + })) +}