summaryrefslogtreecommitdiff
path: root/src/server/mod.rs
blob: 5b7aedbffad1995f75ecfc3390b1b419f9ac7ff7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
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<SslAcceptor>,
    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<TcpStream>) {
    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<SslAcceptor> {
    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());
}