Small amount of refactoring
This commit is contained in:
18
Cargo.lock
generated
18
Cargo.lock
generated
@@ -140,7 +140,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gemserv"
|
name = "gemserv"
|
||||||
version = "0.4.7"
|
version = "0.4.8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"log",
|
"log",
|
||||||
@@ -193,9 +193,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.107"
|
version = "0.2.108"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fbe5e23404da5b4f555ef85ebed98fb4083e55a00c317800bc2a50ede9f3d219"
|
checksum = "8521a1b57e76b1ec69af7599e75e38e7b7fad6610f037db8c79b127201b5d119"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lock_api"
|
name = "lock_api"
|
||||||
@@ -326,9 +326,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "openssl-sys"
|
name = "openssl-sys"
|
||||||
version = "0.9.70"
|
version = "0.9.71"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c6517987b3f8226b5da3661dad65ff7f300cc59fb5ea8333ca191fc65fde3edf"
|
checksum = "7df13d165e607909b363a4757a6f133f8a818a74e9d3a98d09c6128e15fa4c73"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"cc",
|
"cc",
|
||||||
@@ -521,9 +521,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.13.0"
|
version = "1.14.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "588b2d10a336da58d877567cd8fb8a14b463e2104910f8132cd054b4b96e29ee"
|
checksum = "70e992e41e0d2fb9f755b37446f20900f64446ef54874f40a60c78f021ac6144"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"bytes",
|
"bytes",
|
||||||
@@ -541,9 +541,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-macros"
|
name = "tokio-macros"
|
||||||
version = "1.5.1"
|
version = "1.6.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "114383b041aa6212c579467afa0075fbbdd0718de036100bc0ba7961d8cb9095"
|
checksum = "c9efc1aba077437943f7515666aa2b882dfabfbfdf89c819ea75a8d6e9eaba5e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "gemserv"
|
name = "gemserv"
|
||||||
version = "0.4.7"
|
version = "0.4.8"
|
||||||
authors = ["int 80h <int@80h.dev>"]
|
authors = ["int 80h <int@80h.dev>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
description = "A gemini server"
|
description = "A gemini server"
|
||||||
@@ -12,7 +12,7 @@ license = "MIT"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
tokio = { version = "1.13.0", features = [ "full" ] }
|
tokio = { version = "1.14", features = [ "full" ] }
|
||||||
openssl = "0.10.38"
|
openssl = "0.10.38"
|
||||||
tokio-openssl = "0.6.3"
|
tokio-openssl = "0.6.3"
|
||||||
futures-util = "0.3.17"
|
futures-util = "0.3.17"
|
||||||
|
|||||||
@@ -89,7 +89,6 @@ fn check(byt: u8, peer_addr: SocketAddr, u: &url::Url) -> bool {
|
|||||||
#[cfg(feature = "cgi")]
|
#[cfg(feature = "cgi")]
|
||||||
pub async fn cgi(
|
pub async fn cgi(
|
||||||
con: &mut conn::Connection,
|
con: &mut conn::Connection,
|
||||||
srv: &config::ServerCfg,
|
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
url: &url::Url,
|
url: &url::Url,
|
||||||
script_name: String,
|
script_name: String,
|
||||||
@@ -97,7 +96,7 @@ pub async fn cgi(
|
|||||||
) -> Result<(), io::Error> {
|
) -> Result<(), io::Error> {
|
||||||
|
|
||||||
let x509 = con.stream.ssl().peer_certificate();
|
let x509 = con.stream.ssl().peer_certificate();
|
||||||
let mut envs = envs(con.peer_addr, x509, srv, &url);
|
let mut envs = envs(con.peer_addr, x509, &con.srv, &url);
|
||||||
envs.insert("SCRIPT_NAME".into(), script_name);
|
envs.insert("SCRIPT_NAME".into(), script_name);
|
||||||
envs.insert("PATH_INFO".into(), path_info);
|
envs.insert("PATH_INFO".into(), path_info);
|
||||||
|
|
||||||
@@ -148,7 +147,7 @@ pub async fn cgi(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "scgi")]
|
#[cfg(feature = "scgi")]
|
||||||
pub async fn scgi(addr: String, u: url::Url, mut con: conn::Connection, srv: &config::ServerCfg) -> Result<(), io::Error> {
|
pub async fn scgi(addr: String, u: url::Url, mut con: conn::Connection) -> Result<(), io::Error> {
|
||||||
let addr = addr
|
let addr = addr
|
||||||
.to_socket_addrs()?
|
.to_socket_addrs()?
|
||||||
.next()
|
.next()
|
||||||
@@ -163,7 +162,7 @@ pub async fn scgi(addr: String, u: url::Url, mut con: conn::Connection, srv: &co
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
let x509 = con.stream.ssl().peer_certificate();
|
let x509 = con.stream.ssl().peer_certificate();
|
||||||
let envs = envs(con.peer_addr, x509, srv, &u);
|
let envs = envs(con.peer_addr, x509, &con.srv, &u);
|
||||||
let len = 0usize;
|
let len = 0usize;
|
||||||
let mut byt = String::from(format!("CONTENT_LENGTH\x00{}\x00SCGI\x001\x00
|
let mut byt = String::from(format!("CONTENT_LENGTH\x00{}\x00SCGI\x001\x00
|
||||||
RQUEST_METHOD\x00POST\x00REQUEST_URI\x00{}\x00", len, u.path()));
|
RQUEST_METHOD\x00POST\x00REQUEST_URI\x00{}\x00", len, u.path()));
|
||||||
|
|||||||
@@ -64,4 +64,4 @@ impl Config {
|
|||||||
}
|
}
|
||||||
map
|
map
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -12,6 +12,7 @@ use crate::status::Status;
|
|||||||
pub struct Connection {
|
pub struct Connection {
|
||||||
pub stream: SslStream<TcpStream>,
|
pub stream: SslStream<TcpStream>,
|
||||||
pub peer_addr: SocketAddr,
|
pub peer_addr: SocketAddr,
|
||||||
|
pub srv: crate::config::ServerCfg,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Connection {
|
impl Connection {
|
||||||
|
|||||||
120
src/main.rs
120
src/main.rs
@@ -64,7 +64,7 @@ async fn get_binary(mut con: conn::Connection, path: PathBuf, meta: String) -> i
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_content(path: PathBuf, u: url::Url) -> Result<String, io::Error> {
|
async fn get_content(path: PathBuf, u: &url::Url) -> Result<String, io::Error> {
|
||||||
let meta = tokio::fs::metadata(&path).await?;
|
let meta = tokio::fs::metadata(&path).await?;
|
||||||
if meta.is_file() {
|
if meta.is_file() {
|
||||||
return Ok(tokio::fs::read_to_string(path).await?);
|
return Ok(tokio::fs::read_to_string(path).await?);
|
||||||
@@ -119,12 +119,11 @@ async fn get_content(path: PathBuf, u: url::Url) -> Result<String, io::Error> {
|
|||||||
#[cfg(feature = "cgi")]
|
#[cfg(feature = "cgi")]
|
||||||
async fn handle_cgi(
|
async fn handle_cgi(
|
||||||
con: &mut conn::Connection,
|
con: &mut conn::Connection,
|
||||||
srv: &config::ServerCfg,
|
|
||||||
request: &str,
|
request: &str,
|
||||||
url: &Url,
|
url: &Url,
|
||||||
full_path: &PathBuf,
|
full_path: &PathBuf,
|
||||||
) -> Result<bool, io::Error> {
|
) -> Result<bool, io::Error> {
|
||||||
if srv.server.cgi.unwrap_or(false) {
|
if con.srv.server.cgi.unwrap_or(false) {
|
||||||
let mut path = full_path.clone();
|
let mut path = full_path.clone();
|
||||||
let mut segments = url.path_segments().unwrap();
|
let mut segments = url.path_segments().unwrap();
|
||||||
let mut path_info = "".to_string();
|
let mut path_info = "".to_string();
|
||||||
@@ -143,11 +142,11 @@ async fn handle_cgi(
|
|||||||
let meta = tokio::fs::metadata(&path).await?;
|
let meta = tokio::fs::metadata(&path).await?;
|
||||||
let perm = meta.permissions();
|
let perm = meta.permissions();
|
||||||
|
|
||||||
match &srv.server.cgipath {
|
match &con.srv.server.cgipath {
|
||||||
Some(c) => {
|
Some(c) => {
|
||||||
if path.starts_with(c) {
|
if path.starts_with(c) {
|
||||||
if perm.mode() & 0o0111 == 0o0111 {
|
if perm.mode() & 0o0111 == 0o0111 {
|
||||||
cgi::cgi(con, srv, path, url, script_name, path_info).await?;
|
cgi::cgi(con, path, url, script_name, path_info).await?;
|
||||||
return Ok(true);
|
return Ok(true);
|
||||||
} else {
|
} else {
|
||||||
logger::logger(con.peer_addr, Status::CGIError, request);
|
logger::logger(con.peer_addr, Status::CGIError, request);
|
||||||
@@ -158,7 +157,7 @@ async fn handle_cgi(
|
|||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
if meta.is_file() && perm.mode() & 0o0111 == 0o0111 {
|
if meta.is_file() && perm.mode() & 0o0111 == 0o0111 {
|
||||||
cgi::cgi(con, srv, path, url, script_name, path_info).await?;
|
cgi::cgi(con, path, url, script_name, path_info).await?;
|
||||||
return Ok(true);
|
return Ok(true);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -167,30 +166,22 @@ async fn handle_cgi(
|
|||||||
Ok(false)
|
Ok(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO Rewrite this monster.
|
async fn get_request(mut con: conn::Connection) -> Result<(conn::Connection, url::Url), String> {
|
||||||
async fn handle_connection(
|
|
||||||
mut con: conn::Connection,
|
|
||||||
srv: &config::ServerCfg,
|
|
||||||
) -> Result<(), io::Error> {
|
|
||||||
let index = match &srv.server.index {
|
|
||||||
Some(i) => i.clone(),
|
|
||||||
None => "index.gemini".to_string(),
|
|
||||||
};
|
|
||||||
let mut buffer = [0; 1024];
|
let mut buffer = [0; 1024];
|
||||||
let len = match tokio::time::timeout(tokio::time::Duration::from_secs(5), con.stream.read(&mut buffer)).await {
|
let len = match tokio::time::timeout(tokio::time::Duration::from_secs(5), con.stream.read(&mut buffer)).await {
|
||||||
Ok(result) => result.unwrap(),
|
Ok(result) => result.unwrap(),
|
||||||
Err(_) => {
|
Err(e) => {
|
||||||
logger::logger(con.peer_addr, Status::BadRequest, "");
|
logger::logger(con.peer_addr, Status::BadRequest, "");
|
||||||
con.send_status(Status::BadRequest, None).await?;
|
con.send_status(Status::BadRequest, None).await.map_err(|e| e.to_string())?;
|
||||||
return Ok(());
|
return Err(e.to_string());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let mut request = match String::from_utf8(buffer[..len].to_vec()) {
|
let mut request = match String::from_utf8(buffer[..len].to_vec()) {
|
||||||
Ok(request) => request,
|
Ok(request) => request,
|
||||||
Err(_) => {
|
Err(e) => {
|
||||||
logger::logger(con.peer_addr, Status::BadRequest, "");
|
logger::logger(con.peer_addr, Status::BadRequest, "");
|
||||||
con.send_status(Status::BadRequest, None).await?;
|
con.send_status(Status::BadRequest, None).await.map_err(|e| e.to_string())?;
|
||||||
return Ok(());
|
return Err(e.to_string());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if request.starts_with("//") {
|
if request.starts_with("//") {
|
||||||
@@ -208,35 +199,48 @@ async fn handle_connection(
|
|||||||
Ok(url) => url,
|
Ok(url) => url,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
logger::logger(con.peer_addr, Status::BadRequest, &request);
|
logger::logger(con.peer_addr, Status::BadRequest, &request);
|
||||||
con.send_status(Status::BadRequest, None).await?;
|
con.send_status(Status::BadRequest, None).await.map_err(|e| e.to_string())?;
|
||||||
return Ok(());
|
return Err("Bad url".to_string());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if Some(srv.server.hostname.as_str()) != url.host_str() {
|
if Some(con.srv.server.hostname.as_str()) != url.host_str() {
|
||||||
logger::logger(con.peer_addr, Status::ProxyRequestRefused, &request);
|
logger::logger(con.peer_addr, Status::ProxyRequestRefused, &url.as_str());
|
||||||
con.send_status(Status::ProxyRequestRefused, None).await?;
|
con.send_status(Status::ProxyRequestRefused, None).await.map_err(|e| e.to_string())?;
|
||||||
return Ok(());
|
return Err("Wrong host".to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
match url.port() {
|
match url.port() {
|
||||||
Some(p) => {
|
Some(p) => {
|
||||||
if p != srv.port {
|
if p != con.srv.port {
|
||||||
logger::logger(con.peer_addr, Status::ProxyRequestRefused, &request);
|
logger::logger(con.peer_addr, Status::ProxyRequestRefused, &url.as_str());
|
||||||
con.send_status(status::Status::ProxyRequestRefused, None)
|
con.send_status(status::Status::ProxyRequestRefused, None)
|
||||||
.await?;
|
.await.map_err(|e| e.to_string())?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
if url.scheme() != "gemini" {
|
if url.scheme() != "gemini" {
|
||||||
logger::logger(con.peer_addr, Status::ProxyRequestRefused, &request);
|
logger::logger(con.peer_addr, Status::ProxyRequestRefused, &url.as_str());
|
||||||
con.send_status(Status::ProxyRequestRefused, None).await?;
|
con.send_status(Status::ProxyRequestRefused, None).await.map_err(|e| e.to_string())?;
|
||||||
return Ok(());
|
return Err("scheme not gemini".to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return Ok((con, url))
|
||||||
|
}
|
||||||
|
|
||||||
match &srv.server.redirect {
|
// TODO Rewrite this monster.
|
||||||
|
async fn handle_connection(
|
||||||
|
mut con: conn::Connection,
|
||||||
|
url: url::Url
|
||||||
|
) -> Result<(), io::Error> {
|
||||||
|
let index = match &con.srv.server.index {
|
||||||
|
Some(i) => i.clone(),
|
||||||
|
None => "index.gemini".to_string(),
|
||||||
|
};
|
||||||
|
|
||||||
|
match &con.srv.server.redirect.to_owned() {
|
||||||
Some(re) => {
|
Some(re) => {
|
||||||
let u = match url.path() {
|
let u = match url.path() {
|
||||||
"/" => "/",
|
"/" => "/",
|
||||||
@@ -244,7 +248,7 @@ async fn handle_connection(
|
|||||||
};
|
};
|
||||||
match re.get(u) {
|
match re.get(u) {
|
||||||
Some(r) => {
|
Some(r) => {
|
||||||
logger::logger(con.peer_addr, Status::RedirectTemporary, &request);
|
logger::logger(con.peer_addr, Status::RedirectTemporary, &url.as_str());
|
||||||
con.send_status(Status::RedirectTemporary, Some(r)).await?;
|
con.send_status(Status::RedirectTemporary, Some(r)).await?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
@@ -255,7 +259,7 @@ async fn handle_connection(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "proxy")]
|
#[cfg(feature = "proxy")]
|
||||||
if let Some(pr) = &srv.server.proxy_all {
|
if let Some(pr) = con.srv.server.proxy_all.to_owned() {
|
||||||
let host_port: Vec<&str> = pr.splitn(2, ':').collect();
|
let host_port: Vec<&str> = pr.splitn(2, ':').collect();
|
||||||
let host = host_port[0];
|
let host = host_port[0];
|
||||||
let port: Option<u16>;
|
let port: Option<u16>;
|
||||||
@@ -269,12 +273,12 @@ async fn handle_connection(
|
|||||||
upstream_url.set_host(Some(host)).unwrap();
|
upstream_url.set_host(Some(host)).unwrap();
|
||||||
upstream_url.set_port(port).unwrap();
|
upstream_url.set_port(port).unwrap();
|
||||||
|
|
||||||
revproxy::proxy_all(pr, upstream_url, con).await?;
|
revproxy::proxy_all(pr.as_str(), upstream_url, con).await?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "proxy")]
|
#[cfg(feature = "proxy")]
|
||||||
match &srv.server.proxy {
|
match &con.srv.server.proxy {
|
||||||
Some(pr) => match url.path_segments().map(|c| c.collect::<Vec<_>>()) {
|
Some(pr) => match url.path_segments().map(|c| c.collect::<Vec<_>>()) {
|
||||||
Some(s) => match pr.get(s[0]) {
|
Some(s) => match pr.get(s[0]) {
|
||||||
Some(p) => {
|
Some(p) => {
|
||||||
@@ -289,7 +293,7 @@ async fn handle_connection(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "scgi")]
|
#[cfg(feature = "scgi")]
|
||||||
match &srv.server.scgi {
|
match &con.srv.server.scgi {
|
||||||
Some(sc) => {
|
Some(sc) => {
|
||||||
let u = match url.path() {
|
let u = match url.path() {
|
||||||
"/" => "/",
|
"/" => "/",
|
||||||
@@ -297,7 +301,7 @@ async fn handle_connection(
|
|||||||
};
|
};
|
||||||
match sc.get(u) {
|
match sc.get(u) {
|
||||||
Some(r) => {
|
Some(r) => {
|
||||||
cgi::scgi(r.to_string(), url, con, srv).await?;
|
cgi::scgi(r.to_string(), url, con).await?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
None => {}
|
None => {}
|
||||||
@@ -309,7 +313,7 @@ async fn handle_connection(
|
|||||||
|
|
||||||
let mut path = PathBuf::new();
|
let mut path = PathBuf::new();
|
||||||
|
|
||||||
if url.path().starts_with("/~") && srv.server.usrdir.unwrap_or(false) {
|
if url.path().starts_with("/~") && con.srv.server.usrdir.unwrap_or(false) {
|
||||||
let usr = url.path().trim_start_matches("/~");
|
let usr = url.path().trim_start_matches("/~");
|
||||||
let usr: Vec<&str> = usr.splitn(2, "/").collect();
|
let usr: Vec<&str> = usr.splitn(2, "/").collect();
|
||||||
if cfg!(target_os = "macos") {
|
if cfg!(target_os = "macos") {
|
||||||
@@ -323,7 +327,7 @@ async fn handle_connection(
|
|||||||
path.push(format!("{}/{}/", usr[0], "public_gemini"));
|
path.push(format!("{}/{}/", usr[0], "public_gemini"));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
path.push(&srv.server.dir);
|
path.push(&con.srv.server.dir);
|
||||||
if url.path() != "" || url.path() != "/" {
|
if url.path() != "" || url.path() != "/" {
|
||||||
let decoded = util::url_decode(url.path().trim_start_matches("/").as_bytes());
|
let decoded = util::url_decode(url.path().trim_start_matches("/").as_bytes());
|
||||||
path.push(decoded);
|
path.push(decoded);
|
||||||
@@ -333,11 +337,11 @@ async fn handle_connection(
|
|||||||
if !path.exists() {
|
if !path.exists() {
|
||||||
// See if it's a subpath of a CGI script before returning NotFound
|
// See if it's a subpath of a CGI script before returning NotFound
|
||||||
#[cfg(feature = "cgi")]
|
#[cfg(feature = "cgi")]
|
||||||
if handle_cgi(&mut con, srv, &request, &url, &path).await? {
|
if handle_cgi(&mut con, &url.as_str(), &url, &path).await? {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
logger::logger(con.peer_addr, Status::NotFound, &request);
|
logger::logger(con.peer_addr, Status::NotFound, &url.as_str());
|
||||||
con.send_status(Status::NotFound, None).await?;
|
con.send_status(Status::NotFound, None).await?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
@@ -349,7 +353,7 @@ async fn handle_connection(
|
|||||||
// This block is terrible
|
// This block is terrible
|
||||||
if meta.is_dir() {
|
if meta.is_dir() {
|
||||||
if !url.path().ends_with("/") {
|
if !url.path().ends_with("/") {
|
||||||
logger::logger(con.peer_addr, Status::RedirectPermanent, &request);
|
logger::logger(con.peer_addr, Status::RedirectPermanent, &url.as_str());
|
||||||
con.send_status(
|
con.send_status(
|
||||||
Status::RedirectPermanent,
|
Status::RedirectPermanent,
|
||||||
Some(format!("{}/", url).as_str()),
|
Some(format!("{}/", url).as_str()),
|
||||||
@@ -372,35 +376,35 @@ async fn handle_connection(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "cgi")]
|
#[cfg(feature = "cgi")]
|
||||||
if handle_cgi(&mut con, srv, &request, &url, &path).await? {
|
if handle_cgi(&mut con, &url.as_str(), &url, &path).await? {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
if meta.is_file() && perm.mode() & 0o0111 == 0o0111 {
|
if meta.is_file() && perm.mode() & 0o0111 == 0o0111 {
|
||||||
logger::logger(con.peer_addr, Status::NotFound, &request);
|
logger::logger(con.peer_addr, Status::NotFound, &url.as_str());
|
||||||
con.send_status(Status::NotFound, None).await?;
|
con.send_status(Status::NotFound, None).await?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
if perm.mode() & 0o0444 != 0o0444 {
|
if perm.mode() & 0o0444 != 0o0444 {
|
||||||
logger::logger(con.peer_addr, Status::NotFound, &request);
|
logger::logger(con.peer_addr, Status::NotFound, &url.as_str());
|
||||||
con.send_status(Status::NotFound, None).await?;
|
con.send_status(Status::NotFound, None).await?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut mime = get_mime(&path);
|
let mut mime = get_mime(&path);
|
||||||
if mime == "text/gemini" && srv.server.lang.is_some() {
|
if mime == "text/gemini" && con.srv.server.lang.is_some() {
|
||||||
mime += &("; lang=".to_string() + &srv.server.lang.to_owned().unwrap());
|
mime += &("; lang=".to_string() + &con.srv.server.lang.to_owned().unwrap());
|
||||||
}
|
}
|
||||||
if !mime.starts_with("text/") {
|
if !mime.starts_with("text/") {
|
||||||
logger::logger(con.peer_addr, Status::Success, &request);
|
logger::logger(con.peer_addr, Status::Success, &url.as_str());
|
||||||
get_binary(con, path, mime).await?;
|
get_binary(con, path, mime).await?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
let content = get_content(path, url).await?;
|
let content = get_content(path, &url).await?;
|
||||||
con.send_body(status::Status::Success, Some(&mime), Some(content))
|
con.send_body(status::Status::Success, Some(&mime), Some(content))
|
||||||
.await?;
|
.await?;
|
||||||
logger::logger(con.peer_addr, Status::Success, &request);
|
logger::logger(con.peer_addr, Status::Success, &url.as_str());
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -484,10 +488,14 @@ fn main() -> io::Result<()> {
|
|||||||
None => cmap.get(&default).unwrap(),
|
None => cmap.get(&default).unwrap(),
|
||||||
},
|
},
|
||||||
None => cmap.get(&default).unwrap(),
|
None => cmap.get(&default).unwrap(),
|
||||||
};
|
}.to_owned();
|
||||||
|
|
||||||
let con = conn::Connection { stream, peer_addr };
|
let con = conn::Connection { stream, peer_addr, srv };
|
||||||
handle_connection(con, srv).await?;
|
let (con, url) = match get_request(con).await {
|
||||||
|
Ok((c, u)) => (c, u),
|
||||||
|
Err(_) => return Ok(()) as io::Result<()>,
|
||||||
|
};
|
||||||
|
handle_connection(con, url).await?;
|
||||||
|
|
||||||
Ok(()) as io::Result<()>
|
Ok(()) as io::Result<()>
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user