diff --git a/core/http/src/handling/response/build_and_write.rs b/core/http/src/handling/response/build_and_write.rs index 67f87bb259a2400e69235bf7e2799a75424783e2..3b6bd1b42a61717d06b86ccc28dbb6d51912495d 100644 --- a/core/http/src/handling/response/build_and_write.rs +++ b/core/http/src/handling/response/build_and_write.rs @@ -38,4 +38,10 @@ impl Response { stream.write_all(&resp).await?; Ok(()) } + + pub async fn write_unencrypted(self, mut stream: TcpStream) -> Result<()> { + let resp = self.build(None); + stream.write_all(&resp).await?; + Ok(()) + } } diff --git a/core/http/src/setup.rs b/core/http/src/setup.rs index c1b3ced5704483c64d7e3fa898a90ac0dbbd8d8a..4730fdb7fe2d8d4eb7d24fda3be30f75b606572b 100644 --- a/core/http/src/setup.rs +++ b/core/http/src/setup.rs @@ -9,7 +9,7 @@ use tokio_native_tls::{native_tls::{Identity, self}, TlsAcceptor}; use crate::{ handlers::handler::handle_connection, - handling::routes::{Route, Uri}, + handling::{routes::{Route, Uri}, response::{Response, Status}}, }; #[derive(Clone)] @@ -29,6 +29,7 @@ pub struct Config { mountpoints: Option<Vec<MountPoint<'static>>>, /// Contains a [tokio::net::TcpListener] that is bound for the server address: TcpListener, + to_secure_redirect: TcpListener, tls_acceptor: TlsAcceptor, } @@ -93,10 +94,11 @@ impl<'a> Config { /// is no interrupt signal pub async fn launch(self) { println!( - "Server launched from http://{}", - self.address.local_addr().unwrap() + "Server launched from https://{} and http://{}", + self.address.local_addr().unwrap(), self.to_secure_redirect.local_addr().unwrap() ); let mut sigint = signal(SignalKind::interrupt()).unwrap(); + let location_string = format!("Location: https://{}", self.address.local_addr().unwrap()); loop { select! { _ = sigint.recv() => { @@ -108,6 +110,15 @@ impl<'a> Config { let tls_acceptor = self.tls_acceptor.clone(); tokio::spawn(async move { handle_connection(socket, mountpoints, tls_acceptor).await; }); } + Ok((socket, _)) = self.to_secure_redirect.accept() => { + let redirect_response = Response { + headers: vec![location_string.clone()], + cookies: None, + status: Some(Status::MovedPermanently), + body: Box::new(""), + }; + tokio::spawn(async move { let _ = redirect_response.write_unencrypted(socket).await; }); + } } } } @@ -122,22 +133,24 @@ impl<'a> Config { /// # Example /// ``` /// async fn example() { -/// let _ = http::build("127.0.0.1:8000"); +/// let _ = http::build("127.0.0.1:8080", "127.0.0.1:8443"); /// } /// ``` /// # Panics /// Panics if the IP is not bindable, or other forms of system errors or it's not a valid /// IP-Address -pub async fn build(ip: &str) -> Config { - let listener = if let Ok(listener) = TcpListener::bind(ip).await { - listener - } else { +pub async fn build(ip_http: &str, ip_secure: &str) -> Config { + let Ok(listener_secure) = TcpListener::bind(ip_secure).await else { panic!("\x1b[31mCould't bind Listener to address\x1b[0m"); }; - let ip = ip.splitn(2, ':').collect::<Vec<&str>>(); + let ip = ip_secure.splitn(2, ':').collect::<Vec<&str>>(); if ip.len() != 2 { panic!("Invalid IP Address"); } + + let Ok(listener_http) = TcpListener::bind(ip_http).await else { + panic!("\x1b[31mCould't bind Listener to address\x1b[0m"); + }; let identity = Identity::from_pkcs12(include_bytes!("certificates/identity.pfx"), "1234").unwrap(); let port = ip[1]; @@ -148,11 +161,14 @@ pub async fn build(ip: &str) -> Config { >> \x1b[34mIp\x1b[0m: {ip} >> \x1b[34mPort\x1b[0m: {port} >> \x1b[34mWorkers\x1b[0m: {workers} +\x1b[32m Security\x1b[0m + >> \x1b[32mHttp to Https Redirect: {ip_http} -> {ip_secure}\x1b[0m \x1b[35m🛪 Mountpoints\x1b[0m" ); Config { mountpoints: None, - address: listener, + address: listener_secure, + to_secure_redirect: listener_http, tls_acceptor: native_tls::TlsAcceptor::builder(identity).build().unwrap().into() } } diff --git a/site/src/main.rs b/site/src/main.rs index 6938a3b65ddaa8a0567d37ed5e9de64859b8fff3..ffa61b16091b67e3ad0d80b16bd99be5169bf42e 100644 --- a/site/src/main.rs +++ b/site/src/main.rs @@ -104,7 +104,7 @@ async fn main() { rank: 0, }; - http::build("127.0.0.1:8080") + http::build("127.0.0.1:8080", "127.0.0.1:8443") .await .mount("/", vec![fileserver, post_test, static_hi]) .mount("/post/", vec![post_test])