diff options
| author | Jan Wolff <janw@mailbox.org> | 2020-05-14 21:45:59 +0200 |
|---|---|---|
| committer | Jan Wolff <janw@mailbox.org> | 2020-05-14 21:49:38 +0200 |
| commit | d9e51706768dcb11ef32f4a2d5fd9161e1e92fed (patch) | |
| tree | b0b15c39c8e77007b159fe25e1c388cb9cd4838f /src | |
initial commit
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.rs | 45 | ||||
| -rw-r--r-- | src/response.rs | 50 |
2 files changed, 95 insertions, 0 deletions
diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..8181b92 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,45 @@ +use openssl::ssl::{SslMethod, SslAcceptor, SslStream, SslFiletype}; +use std::net::{TcpListener, TcpStream, SocketAddr}; +use std::sync::Arc; +use std::thread; +mod response; + +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()); +} + +fn handle_client(mut stream: SslStream<TcpStream>) { + let mut buffer = [0; 1026]; + stream.ssl_read(&mut buffer); + let request = String::from_utf8(buffer.to_vec()).unwrap(); + + let header = response::Header::new(response::Status::Success, "text/gemini".to_string()); + let response = response::Response::new(header, [].to_vec()); + + stream.ssl_write(&response.format()); +} + +fn main() { + let addrs = [ + SocketAddr::from(([127, 0, 0, 1], 1965)), + ]; + let acceptor = build_acceptor(); + let listener = TcpListener::bind(&addrs[..]).unwrap(); + + for stream in listener.incoming() { + match stream { + Ok(stream) => { + let acceptor = acceptor.clone(); + thread::spawn(move || { + let stream = acceptor.accept(stream).unwrap(); + handle_client(stream); + }); + } + Err(e) => { /* connection failed */ } + } + } +} diff --git a/src/response.rs b/src/response.rs new file mode 100644 index 0000000..521cad7 --- /dev/null +++ b/src/response.rs @@ -0,0 +1,50 @@ +use std::vec; + +#[derive(Copy, Clone)] +pub enum Status { + Input = 1, + Success = 2, + Redirect = 3, + TemporaryFailure = 4, + PermanentFailure = 5, + ClientCertificateRequired = 6, +} + +pub struct Header { + status: Status, + meta: String, +} + +pub struct Response { + header: Header, + data: std::vec::Vec<u8>, +} + +impl Header { + pub fn new(status: Status, meta: String) -> Header { + return Header{ + status: status, + meta: meta, + } + } + + pub fn format(&self) -> String { + let status: u8 = self.status as u8; + return format!("{} {}\r\n", status * 10, self.meta) + } +} + +impl Response { + pub fn new(header: Header, data: std::vec::Vec<u8>) -> Response { + return Response{ + header: header, + data: data, + } + } + + pub fn format(&self) -> std::vec::Vec<u8> { + let mut resp: std::vec::Vec<u8> = self.header.format().as_bytes().to_vec(); + resp.extend(&self.data); + return resp; + } +} |
