diff --git a/src/cgi.rs b/src/cgi.rs index 304059c..cb874bd 100644 --- a/src/cgi.rs +++ b/src/cgi.rs @@ -33,7 +33,7 @@ pub async fn cgi(mut con: conn::Connection, path: PathBuf, url: Url) -> Result<( .output() .unwrap(); if !cmd.status.success() { - con.send_status(status::Status::CGIError, "CGI Error!").await?; + con.send_status(status::Status::CGIError, None).await?; return Ok(()); } let cmd = String::from_utf8(cmd.stdout).unwrap(); diff --git a/src/conn.rs b/src/conn.rs index 8c2b232..1e3d0e2 100644 --- a/src/conn.rs +++ b/src/conn.rs @@ -4,7 +4,7 @@ use tokio::net::TcpStream; use tokio::prelude::*; use tokio_openssl::SslStream; -use crate::status; +use crate::status::Status; pub struct Connection { pub stream: SslStream, @@ -14,8 +14,8 @@ pub struct Connection { impl Connection { pub async fn send_status( &mut self, - stat: status::Status, - meta: &str, + stat: Status, + meta: Option<&str>, ) -> Result<(), io::Error> { self.send_body(stat, meta, None).await?; Ok(()) @@ -23,10 +23,14 @@ pub async fn send_status( pub async fn send_body( &mut self, - stat: status::Status, - meta: &str, + stat: Status, + meta: Option<&str>, body: Option, ) -> Result<(), io::Error> { + let meta = match meta { + Some(m) => m, + None => &stat.to_str(), + }; let mut s = format!("{}\t{}\r\n", stat as u8, meta); if let Some(b) = body { s += &b; diff --git a/src/main.rs b/src/main.rs index 2bdd763..5826138 100644 --- a/src/main.rs +++ b/src/main.rs @@ -54,7 +54,7 @@ fn get_mime(path: &PathBuf) -> String { async fn get_binary(mut con: conn::Connection, path:PathBuf, meta: String) -> io::Result<()> { let fd = File::open(path)?; let mut reader = BufReader::with_capacity(1024*1024,fd); - con.send_status(status::Status::Success, &meta).await?; + con.send_status(status::Status::Success, Some(&meta)).await?; loop { let len = { let buf = reader.fill_buf()?; @@ -107,7 +107,7 @@ async fn handle_connection(mut con: conn::Connection, srv: &config::ServerCfg) - Ok(request) => request, Err(_) => { println!("Bad Request"); - con.send_status(status::Status::BadRequest, "Bad Request!").await?; + con.send_status(status::Status::BadRequest, None).await?; return Ok(()) } }; @@ -118,19 +118,19 @@ async fn handle_connection(mut con: conn::Connection, srv: &config::ServerCfg) - let url = match Url::parse(&request) { Ok(url) => url, - Err(_) => { con.send_status(status::Status::BadRequest, "Bad Request!").await?; + Err(_) => { con.send_status(status::Status::BadRequest, None).await?; return Ok(()) } }; if Some(srv.hostname.as_str()) != url.host_str() { - con.send_status(status::Status::ProxyRequestRefused, "Url doesn't match certificate!").await?; + con.send_status(status::Status::ProxyRequestRefused, None).await?; return Ok(()); } match url.port() { Some(p) => { if p != srv.port { - con.send_status(status::Status::ProxyRequestRefused, "Wrong Port!").await?; + con.send_status(status::Status::ProxyRequestRefused, None).await?; }}, None => {} } @@ -138,7 +138,7 @@ async fn handle_connection(mut con: conn::Connection, srv: &config::ServerCfg) - if url.scheme() != "gemini" { con.send_status( status::Status::ProxyRequestRefused, - "Not a gemini scheme!", + None, ) .await?; return Ok(()); @@ -179,7 +179,7 @@ async fn handle_connection(mut con: conn::Connection, srv: &config::ServerCfg) - } if !path.exists() { - con.send_status(status::Status::NotFound, "Not found!").await?; + con.send_status(status::Status::NotFound, None).await?; return Ok(()); } @@ -193,7 +193,7 @@ async fn handle_connection(mut con: conn::Connection, srv: &config::ServerCfg) - println!("{}", url); con.send_status( status::Status::RedirectPermanent, - format!("{}/", url).as_str(), + Some(format!("{}/", url).as_str()), ) .await?; return Ok(()); @@ -219,14 +219,14 @@ async fn handle_connection(mut con: conn::Connection, srv: &config::ServerCfg) - return Ok(()); } else { con.send_status( - status::Status::CGIError, "CGI Error!").await?; + status::Status::CGIError, None).await?; return Ok(()); } } if perm.mode() & 0o0444 != 0o0444 { con.send_status( - status::Status::NotFound, "Not Found!").await?; + status::Status::NotFound, None).await?; return Ok(()); } @@ -238,7 +238,7 @@ async fn handle_connection(mut con: conn::Connection, srv: &config::ServerCfg) - let content = get_content(path, url)?; con.send_body( status::Status::Success, - mime.as_str(), + Some(mime.as_str()), Some(content), ) .await?; diff --git a/src/revproxy.rs b/src/revproxy.rs index 299834c..e7ebc71 100644 --- a/src/revproxy.rs +++ b/src/revproxy.rs @@ -16,11 +16,11 @@ use crate::status; pub async fn proxy(addr: String, u: url::Url, mut con: conn::Connection) -> Result<(), io::Error> { let p: Vec<&str> = u.path().trim_start_matches("/").splitn(2, "/").collect(); if p.len() == 1 { - con.send_status(status::Status::NotFound, "Not Found").await?; + con.send_status(status::Status::NotFound, None).await?; return Ok(()); } if p[1] == "" || p[1] == "/" { - con.send_status(status::Status::NotFound, "Not Found").await?; + con.send_status(status::Status::NotFound, None).await?; return Ok(()) } let addr = addr @@ -36,7 +36,7 @@ pub async fn proxy(addr: String, u: url::Url, mut con: conn::Connection) -> Resu Ok(s) => s, Err(_) => { eprintln!("Error connecting to proxy"); - con.send_status(status::Status::ProxyError, "Error Connecting to proxy").await?; + con.send_status(status::Status::ProxyError, None).await?; return Ok(()) }, }; @@ -44,7 +44,7 @@ pub async fn proxy(addr: String, u: url::Url, mut con: conn::Connection) -> Resu Ok(s) => s, Err(_) => { eprintln!("Error connecting to proxy"); - con.send_status(status::Status::ProxyError, "Error Connecting to proxy").await?; + con.send_status(status::Status::ProxyError, None).await?; return Ok(()) }, }; diff --git a/src/status.rs b/src/status.rs index 0f1e565..1ef6032 100644 --- a/src/status.rs +++ b/src/status.rs @@ -1,7 +1,7 @@ use std::fmt; #[repr(u8)] -#[derive(Debug)] +#[derive(Debug, Copy, Clone)] pub enum Status { Input = 10, Success = 20, @@ -26,6 +26,35 @@ pub enum Status { ExpiredCertificateRejected = 65, } +impl Status { + pub fn to_str(&self) -> &str { + let meta = match self { + Status::Input => "Input", + Status::Success => "Success", + Status::SuccessEndOfSession => "Success End Of Session", + Status::RedirectTemporary => "Redirect Temporary", + Status::RedirectPermanent => "Redirect Permanent", + Status::TemporaryFailure => "Temporary Failure", + Status::ServerUnavailable => "Server Unavailable", + Status::CGIError => "CGI Error!", + Status::ProxyError => "Proxy Error!", + Status::SlowDown => "Slow Down!", + Status::PermanentFailure => "Permanent Failure", + Status::NotFound => "Not Found!", + Status::Gone => "Gone!", + Status::ProxyRequestRefused => "Proxy Requet Refused", + Status::BadRequest => "Bad Request!", + Status::ClientCertificateRequired => "Client Certificate Required", + Status::TransientCertificateRequested => "Transient Certificate Requested", + Status::AuthorisedCertificateRequired => "Authorised Certificate Required", + Status::CertificateNotAccepted => "Certificate Not Accepted", + Status::FutureCertificateRejected => "Future Certificate Rejected", + Status::ExpiredCertificateRejected => "Expired Certificate Rejected", + }; + return meta + } +} + impl fmt::Display for Status { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{:?}", self)