diff --git a/.gitignore b/.gitignore index 1361d93..4bef88c 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,10 @@ *.db-shm *.db-wal +# Tls +cert.key +cert.pem + # IDE configs .idea .vscode diff --git a/Cargo.lock b/Cargo.lock index 600ed72..46ed0f8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -67,6 +67,12 @@ version = "1.0.65" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98161a4e3e2184da77bb14f02184cdd111e83bbbcc9979dfee3c44b9a85f5602" +[[package]] +name = "arc-swap" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "983cd8b9d4b02a6dc6ffa557262eb5858a27a0038ffffe21a0f133eaa819a164" + [[package]] name = "async-compression" version = "0.3.14" @@ -155,6 +161,26 @@ dependencies = [ "tower-service", ] +[[package]] +name = "axum-server" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba6170b61f7b086609dabcae68d2e07352539c6ef04a7c82980bdfa01a159d" +dependencies = [ + "arc-swap", + "bytes", + "futures-util", + "http", + "http-body", + "hyper", + "pin-project-lite", + "rustls", + "rustls-pemfile", + "tokio", + "tokio-rustls", + "tower-service", +] + [[package]] name = "backtrace" version = "0.3.66" @@ -627,6 +653,7 @@ version = "0.0.0-dev" dependencies = [ "anyhow", "axum", + "axum-server", "backtrace", "byte-unit", "crypto-utils", diff --git a/Cargo.toml b/Cargo.toml index 4f28cef..bb8a0e0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,6 +37,7 @@ toml = "0.5" # HTTP server axum = { version = "0.6.0-rc.2", features = ["http2", "multipart"] } +axum-server = { version = "0.4", features = ["tls-rustls"] } tower-http = { version = "0.3", features = ["full"] } hyper = { version = "0.14", features = ["full"] } byte-unit = "4.0.14" diff --git a/README.md b/README.md index c3a9fd2..ac7d448 100644 --- a/README.md +++ b/README.md @@ -13,3 +13,22 @@
+ +## Documentation + +### 👨💻 Compile server + +```bash +cargo build --release +``` + +Now you can run server using command `./target/release/homedisk`. + +### 🔒 Generate development TLS certificate + +```bash +# Generate private key +openssl genrsa -out cert.key 204 +# Generate certificate +openssl req -new -x509 -key cert.key -out cert.pem -days 365 +``` diff --git a/config.toml b/config.toml index f267db3..7f1598f 100644 --- a/config.toml +++ b/config.toml @@ -1,20 +1,14 @@ [http] -# HTTP host host = "0.0.0.0" -# HTTP port -port = 8080 -# Cors domains -cors = [ - "127.0.0.1:8000", - "localhost:8000", -] +httpPort = 8080 # http server port (recommended 80) +httpsPort = 8443 # https server port (recommended 443) +cors = [ "localhost:8000" ] # CORS domains +tlsCert = "./cert.pem" # TLS certificate file +tlsKey = "./cert.key" # TLS key file [jwt] -# JWT Secret string (used to sign tokens) -secret = "secret key used to sign tokens" -# Token expiration time in hours -expires = 24 # one day +secret = "secret key used to sign tokens" # jsonwebtoken secret string used to sign tokens +expires = 24 # token expiration time in hours (default one day) [storage] -# Directory where user files will be stored -path = "/home/homedisk" +path = "/home/homedisk" # path to directory where user files will be stored diff --git a/src/server/mod.rs b/src/server/mod.rs index a32c969..9d544da 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -2,18 +2,32 @@ mod api; pub mod error; pub mod utils; +use std::path::PathBuf; + use anyhow::anyhow; -use axum::{http::HeaderValue, routing::get, Extension, Router, Server}; -use tower_http::cors::{AllowOrigin, CorsLayer}; -use tracing::info; +use axum::{ + extract::Host, + handler::HandlerWithoutStateExt, + http::{HeaderValue, StatusCode, Uri}, + response::Redirect, + routing::get, + Extension, Router, +}; +use axum_server::tls_rustls::RustlsConfig; +use tower_http::{ + cors::{AllowOrigin, CorsLayer}, + BoxError, +}; +use tracing::{debug, info}; use crate::{config::Config, database::Database}; pub async fn start_server(config: Config, db: Database) -> anyhow::Result<()> { - info!( - "🚀 Server has launched on http://{}:{}", - config.http.host, config.http.port - ); + let host = format!("{}:{}", config.http.host, config.http.https_port); + + tokio::spawn(redirect_http_to_https(config.clone())); + + info!("🚀 Server has launched on https://{host}"); // change the type from Vec