initial commit
This commit is contained in:
commit
d9e5170676
11 changed files with 968 additions and 0 deletions
45
src/main.rs
Normal file
45
src/main.rs
Normal file
|
@ -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 */ }
|
||||
}
|
||||
}
|
||||
}
|
50
src/response.rs
Normal file
50
src/response.rs
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue