use crate::server::response::Response; use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod, SslStream}; use std::collections::HashMap; use std::net::{SocketAddr, TcpListener, TcpStream}; use std::thread; use std::vec::Vec; use std::sync::Arc; use url::Url; pub mod response; pub mod handler; #[derive(Clone)] pub struct ServerConfig { defaultHost: Url, } pub struct Server { acceptor: std::sync::Arc, config: ServerConfig, } impl Server { pub fn new(host: &str) -> Server { let config = ServerConfig{defaultHost: Url::parse(host).unwrap()}; Server { acceptor: build_acceptor(), config: config, } } pub fn serve(&self) { let addrs = [SocketAddr::from(([127, 0, 0, 1], 1965))]; let listener = TcpListener::bind(&addrs[..]).unwrap(); for stream in listener.incoming() { match stream { Ok(stream) => { let acceptor = self.acceptor.clone(); let config = self.config.clone(); thread::spawn(move || { let stream = acceptor.accept(stream).unwrap(); handle_client(&config, stream); }); } Err(e) => { /* connection failed */ } } } } } fn handle_client(config: &ServerConfig, mut stream: SslStream) { let mut buffer = [0; 1026]; stream.ssl_read(&mut buffer); let request = String::from_utf8(buffer.to_vec()).unwrap(); let location = match Url::parse(&request) { Ok(url) => url, Err(e) => config.defaultHost.join(&request).unwrap(), }; let response = match handler::handle(config, location) { Some(response) => response, None => response::internal_error(), }; stream.ssl_write(&response.format()); } fn build_acceptor() -> std::sync::Arc { let mut acceptor = SslAcceptor::mozilla_intermediate_v5(SslMethod::tls()).unwrap(); acceptor .set_private_key_file("doc/key.pem", SslFiletype::PEM) .unwrap(); acceptor.set_certificate_chain_file("doc/cert.pem").unwrap(); acceptor.check_private_key().unwrap(); return Arc::new(acceptor.build()); }