use futures_rustls::{TlsAcceptor, rustls};
use futures::io::AsyncReadExt;
use futures::{AsyncBufRead, AsyncWrite};
use httpio::enums::http_body::HttpBody;
use httpio::enums::http_status_code::HttpStatusCode;
use httpio::structures::connection::http_server_connection::HttpServerConnection;
use httpio::structures::http_response::HttpResponse;
use rcgen::generate_simple_self_signed;
use rustls::pki_types::{CertificateDer, PrivateKeyDer};
use smol::io::BufReader;
use smol::net::TcpListener;
use smol::stream::StreamExt;
use std::sync::Arc;
const HTTP_ADDR: &str = "127.0.0.1:8081";
const HTTPS_ADDR: &str = "127.0.0.1:8443";
fn main() -> Result<(), Box<dyn std::error::Error>> {
let subject_alt_names = vec!["localhost".to_string(), "127.0.0.1".to_string()];
let cert = generate_simple_self_signed(subject_alt_names).unwrap();
let cert_der = cert.cert.der().to_vec();
let priv_key_der = cert.key_pair.serialize_der();
let certs = vec![CertificateDer::from(cert_der)];
let private_key = PrivateKeyDer::try_from(priv_key_der).unwrap();
let config = rustls::ServerConfig::builder()
.with_no_client_auth()
.with_single_cert(certs, private_key)
.map_err(|e| format!("TLS config error: {}", e))?;
let acceptor = TlsAcceptor::from(Arc::new(config));
smol::block_on(async {
let http_task = smol::spawn(run_http_server());
let https_task = smol::spawn(run_https_server(acceptor));
let _ = futures::future::join(http_task, https_task).await;
Ok(())
})
}
async fn run_http_server() -> Result<(), std::io::Error> {
let http_listener = TcpListener::bind(HTTP_ADDR).await?;
println!("HTTP Listening on {}", HTTP_ADDR);
let mut incoming = http_listener.incoming();
while let Some(stream) = incoming.next().await {
match stream {
Ok(stream) => {
smol::spawn(async move {
let reader = BufReader::new(stream.clone());
let writer = stream;
handle_connection(reader, writer).await;
}).detach();
}
Err(e) => eprintln!("Error accepting HTTP connection: {}", e),
}
}
Ok(())
}
async fn run_https_server(acceptor: TlsAcceptor) -> Result<(), std::io::Error> {
let https_listener = TcpListener::bind(HTTPS_ADDR).await?;
println!("HTTPS Listening on {}", HTTPS_ADDR);
let mut incoming = https_listener.incoming();
while let Some(stream) = incoming.next().await {
match stream {
Ok(stream) => {
let acceptor = acceptor.clone();
smol::spawn(async move {
match acceptor.accept(stream).await {
Ok(tls_stream) => {
let (reader, writer) = tls_stream.split();
let reader = BufReader::new(reader);
handle_connection(reader, writer).await;
}
Err(e) => eprintln!("TLS handshake error: {}", e),
}
}).detach();
}
Err(e) => eprintln!("Error accepting HTTPS connection: {}", e),
}
}
Ok(())
}
async fn handle_connection<R, W>(reader: R, writer: W)
where
R: AsyncBufRead + Unpin + Send + 'static,
W: AsyncWrite + Unpin + Send + 'static,
{
let mut connection = HttpServerConnection::new(reader, writer);
match connection.read_request().await {
Ok(request) => {
println!("Received request: {} {}", request.method.to_string(), request.path);
let body_content = format!("Hello, World! You requested {}", request.path);
let body = HttpBody::Content(body_content.into_bytes());
let response = HttpResponse::new(HttpStatusCode::Ok, body);
if let Err(e) = connection.send_response(response).await {
eprintln!("Failed to send response: {}", e);
}
}
Err(e) => eprintln!("Failed to read request: {}", e),
}
}