summaryrefslogtreecommitdiff
path: root/src/server/handler.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/handler.rs')
-rw-r--r--src/server/handler.rs73
1 files changed, 65 insertions, 8 deletions
diff --git a/src/server/handler.rs b/src/server/handler.rs
index 4a593e8..d27d292 100644
--- a/src/server/handler.rs
+++ b/src/server/handler.rs
@@ -1,32 +1,89 @@
use crate::server::response;
use crate::server::ServerConfig;
-use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod, SslStream};
+use openssl::ssl::SslStream;
use std::fs::File;
use std::io::{copy, BufReader, BufWriter};
use std::net::TcpStream;
use std::path::Path;
use url::Url;
-pub fn handle(config: &ServerConfig, url: Url, stream: &mut SslStream<TcpStream>) {
+fn send_header(stream: &mut SslStream<TcpStream>, header: &response::Header) {
+ match stream.ssl_write(&header.to_vec()) {
+ Ok(_s) => {
+ return;
+ }
+ Err(_e) => {
+ return;
+ }
+ };
+}
+
+pub fn handle_request(config: &ServerConfig, mut stream: SslStream<TcpStream>) {
+ let mut buffer = [0; 1026];
+ match stream.ssl_read(&mut buffer) {
+ Ok(s) => {
+ if s == 0 {
+ send_header(&mut stream, &response::bad_request());
+ return;
+ }
+ }
+ Err(_) => {
+ send_header(&mut stream, &response::bad_request());
+ return;
+ }
+ };
+
+ let request = match String::from_utf8(buffer.to_vec()) {
+ Ok(request) => request,
+ Err(_) => {
+ send_header(&mut stream, &response::bad_request());
+ return;
+ }
+ };
+
+ let location = match Url::parse(&request) {
+ Ok(url) => url,
+ Err(_) => config.default_host.join(&request).unwrap(),
+ };
+
+ handle_response(config, location, &mut stream);
+}
+
+fn handle_response(config: &ServerConfig, url: Url, mut stream: &mut SslStream<TcpStream>) {
if url.scheme() != "gemini" {
- stream.ssl_write(&response::invalid_protocol().to_vec());
+ send_header(&mut stream, &response::permanent_failure());
return;
}
- let rel_path = Path::new(url.path()).strip_prefix("/").unwrap();
- let path = config.www_root.join(rel_path);
+ if url.host() != config.default_host.host() {
+ send_header(&mut stream, &response::proxy_request_refused());
+ return;
+ }
+
+ let rel_path = match Path::new(url.path()).strip_prefix("/") {
+ Ok(path) => path,
+ Err(_) => {
+ send_header(&mut stream, &response::bad_request());
+ return;
+ }
+ };
+ let path = config.gem_root.join(rel_path);
let file = match File::open(&path) {
Ok(file) => file,
Err(_) => {
- stream.ssl_write(&response::not_found().to_vec());
+ send_header(&mut stream, &response::not_found());
return;
}
};
- stream.ssl_write(&response::Header::new(response::Status::Success, "text/gemini").to_vec());
+ let header = response::Header::new(response::Status::Success, "text/gemini");
+ send_header(&mut stream, &header);
let mut buf_file = BufReader::new(file);
let mut buf_stream = BufWriter::new(stream);
- copy(&mut buf_file, &mut buf_stream);
+ match copy(&mut buf_file, &mut buf_stream) {
+ Ok(_s) => {}
+ Err(_e) => {}
+ }
}