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
80
81
82
83
84
85
86
87
88
89
90
|
use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod, SslStream};
use std::collections::HashMap;
use std::net::{SocketAddr, TcpListener, TcpStream};
use std::path::{Path, PathBuf};
use std::sync::Arc;
use std::thread;
use std::vec::Vec;
use url::Url;
pub mod handler;
pub mod response;
#[derive(Clone)]
pub struct ServerConfig {
default_host: Url,
www_root: PathBuf,
addrs: Vec<SocketAddr>,
}
impl ServerConfig {
pub fn new(default_host: String, www_root: String) -> ServerConfig {
let mut url = Url::parse("gemini://default").unwrap();
url.set_host(Some(default_host.as_str()));
ServerConfig {
default_host: url,
www_root: PathBuf::from(www_root),
addrs: Vec::new(),
}
}
pub fn add_addr(&mut self, addr: String) {
self.addrs.push(addr.parse().unwrap());
}
}
pub struct Server {
acceptor: std::sync::Arc<SslAcceptor>,
config: ServerConfig,
}
impl Server {
pub fn new(config: &ServerConfig) -> Server {
Server {
acceptor: build_acceptor(),
config: config.clone(),
}
}
pub fn serve(&self) {
let listener = TcpListener::bind(&self.config.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.default_host.join(&request).unwrap(),
};
handler::handle(config, location, &mut stream);
}
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());
}
|