Bug fix: If text file wasn't utf8 it would fail and not send any

response to clients.
This commit is contained in:
int 80h
2021-12-12 14:56:52 -05:00
parent f23fa8668b
commit 6d11676da4
7 changed files with 93 additions and 99 deletions

61
Cargo.lock generated
View File

@@ -149,15 +149,15 @@ dependencies = [
[[package]]
name = "futures-core"
version = "0.3.18"
version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "629316e42fe7c2a0b9a65b47d159ceaa5453ab14e8f0a3c5eedbb8cd55b4a445"
checksum = "d0c8ff0461b82559810cdccfde3215c3f373807f5e5232b71479bff7bb2583d7"
[[package]]
name = "futures-macro"
version = "0.3.18"
version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a89f17b21645bc4ed773c69af9c9a0effd4a3f1a3876eadd453469f8854e7fdd"
checksum = "6dbd947adfffb0efc70599b3ddcf7b5597bb5fa9e245eb99f62b3a5f7bb8bd3c"
dependencies = [
"proc-macro2",
"quote",
@@ -166,15 +166,15 @@ dependencies = [
[[package]]
name = "futures-task"
version = "0.3.18"
version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dabf1872aaab32c886832f2276d2f5399887e2bd613698a02359e4ea83f8de12"
checksum = "6ee7c6485c30167ce4dfb83ac568a849fe53274c831081476ee13e0dce1aad72"
[[package]]
name = "futures-util"
version = "0.3.18"
version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d22213122356472061ac0f1ab2cee28d2bac8491410fd68c2af53d1cedb83e"
checksum = "d9b5cf40b47a271f77a8b1bec03ca09044d99d2372c0de244e66430761127164"
dependencies = [
"futures-core",
"futures-macro",
@@ -272,9 +272,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.109"
version = "0.2.112"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f98a04dce437184842841303488f70d0188c5f51437d2a834dc097eafa909a01"
checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125"
[[package]]
name = "lock_api"
@@ -404,9 +404,9 @@ dependencies = [
[[package]]
name = "num_cpus"
version = "1.13.0"
version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1"
dependencies = [
"hermit-abi",
"libc",
@@ -423,9 +423,9 @@ dependencies = [
[[package]]
name = "once_cell"
version = "1.8.0"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56"
checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5"
[[package]]
name = "opaque-debug"
@@ -478,9 +478,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "proc-macro2"
version = "1.0.32"
version = "1.0.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43"
checksum = "2f84e92c0f7c9d58328b85a78557813e4bd845130db68d7184635344399423b1"
dependencies = [
"unicode-xid",
]
@@ -566,15 +566,15 @@ dependencies = [
[[package]]
name = "serde"
version = "1.0.130"
version = "1.0.132"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913"
checksum = "8b9875c23cf305cd1fd7eb77234cbb705f21ea6a72c637a5c6db5fe4b8e7f008"
[[package]]
name = "serde_derive"
version = "1.0.130"
version = "1.0.132"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b"
checksum = "ecc0db5cb2556c0e558887d9bbdcf6ac4471e83ff66cf696e5419024d1606276"
dependencies = [
"proc-macro2",
"quote",
@@ -605,9 +605,9 @@ dependencies = [
[[package]]
name = "simple_logger"
version = "1.15.0"
version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "205596cf77a15774e5601c5ef759f4211ac381c0855a1f1d5e24a46f60f93e9a"
checksum = "45b60258a35dc3cb8a16890b8fd6723349bfa458d7960e25e633f1b1c19d7b5e"
dependencies = [
"atty",
"colored",
@@ -636,9 +636,9 @@ checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
[[package]]
name = "syn"
version = "1.0.82"
version = "1.0.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8daf5dd0bb60cbd4137b1b587d2fc0ae729bc07cf01cd70b36a1ed5ade3b9d59"
checksum = "23a1dfb999630e338648c83e91c59a4e9fb7620f520c3194b6b89e276f2f1959"
dependencies = [
"proc-macro2",
"quote",
@@ -699,11 +699,10 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
[[package]]
name = "tokio"
version = "1.14.0"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70e992e41e0d2fb9f755b37446f20900f64446ef54874f40a60c78f021ac6144"
checksum = "fbbf1c778ec206785635ce8ad57fe52b3009ae9e0c9f574a728f3049d3e55838"
dependencies = [
"autocfg",
"bytes",
"libc",
"memchr",
@@ -719,9 +718,9 @@ dependencies = [
[[package]]
name = "tokio-macros"
version = "1.6.0"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9efc1aba077437943f7515666aa2b882dfabfbfdf89c819ea75a8d6e9eaba5e"
checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7"
dependencies = [
"proc-macro2",
"quote",
@@ -730,9 +729,9 @@ dependencies = [
[[package]]
name = "tokio-rustls"
version = "0.23.1"
version = "0.23.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4baa378e417d780beff82bf54ceb0d195193ea6a00c14e22359e7f39456b5689"
checksum = "a27d5f2b839802bd8267fa19b0530f5a08b9c08cd417976be2a65d130fe1c11b"
dependencies = [
"rustls",
"tokio",

View File

@@ -14,22 +14,22 @@ license = "MIT"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
tokio = { version = "1.14", features = [ "full" ] }
tokio = { version = "1.15", features = [ "full" ] }
rustls-pemfile = "0.2.1"
futures-util = "0.3.18"
futures-util = "0.3.19"
toml = "0.5.8"
serde = "1.0.130"
serde_derive = "1.0.130"
serde = "1.0.132"
serde_derive = "1.0.132"
url = "2.2.2"
new_mime_guess = "3.0.2"
mime = "0.3.16"
log = "0.4.14"
simple_logger = "1.15"
simple_logger = "1.16"
sha2 = "0.9.8"
x509-parser = "0.12"
[dependencies.tokio-rustls]
version = "0.23.1"
version = "0.23.2"
optional = false
features = ["dangerous_configuration"]

View File

@@ -41,7 +41,6 @@ async fn get_binary(mut con: conn::Connection, path: PathBuf, meta: String) -> i
let len = {
let buf = reader.fill_buf().await?;
con.send_raw(buf).await?;
tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
buf.len()
};
if len == 0 {
@@ -57,12 +56,7 @@ async fn get_binary(mut con: conn::Connection, path: PathBuf, meta: String) -> i
Ok(())
}
async fn get_content(path: PathBuf, u: &url::Url) -> Result<String> {
let meta = tokio::fs::metadata(&path).await?;
if meta.is_file() {
return Ok(tokio::fs::read_to_string(path).await?);
}
async fn gen_dir_list(path: PathBuf, u: &url::Url) -> Result<String> {
let mut dirs: Vec<String> = Vec::new();
let mut files: Vec<String> = Vec::new();
@@ -201,12 +195,13 @@ pub async fn handle_connection(mut con: conn::Connection, url: url::Url) -> Resu
#[cfg(feature = "proxy")]
match &con.srv.server.proxy {
Some(pr) => match url.path_segments().map(|c| c.collect::<Vec<_>>()) {
Some(s) => if let Some(p) = pr.get(s[0]) {
Some(pr) => {
if let Some(s) = url.path_segments().map(|c| c.collect::<Vec<_>>()) {
if let Some(p) = pr.get(s[0]) {
revproxy::proxy(p.to_string(), url, con).await?;
return Ok(());
},
None => {}
}
}
},
None => {}
}
@@ -313,6 +308,7 @@ pub async fn handle_connection(mut con: conn::Connection, url: url::Url) -> Resu
}
let mut mime = get_mime(&path);
if meta.is_file() {
if mime == "text/gemini" && con.srv.server.lang.is_some() {
mime += &("; lang=".to_string() + &con.srv.server.lang.to_owned().unwrap());
}
@@ -321,10 +317,26 @@ pub async fn handle_connection(mut con: conn::Connection, url: url::Url) -> Resu
get_binary(con, path, mime).await?;
return Ok(());
}
let content = get_content(path, &url).await?;
con.send_body(Status::Success, Some(&mime), Some(content))
match fs::read_to_string(path).await {
Ok(c) => {
con.send_body(Status::Success, Some(&mime), Some(c))
.await?;
logger::logger(con.peer_addr, Status::Success, url.as_str());
}
Err(e) => {
println!("{}", e);
con.send_status(Status::NotFound, None)
.await?;
logger::logger(con.peer_addr, Status::NotFound, url.as_str());
}
}
} else {
let dir = gen_dir_list(path, &url).await?;
con.send_body(Status::Success, Some(&mime), Some(dir))
.await?;
logger::logger(con.peer_addr, Status::Success, url.as_str());
}
Ok(())
}

View File

@@ -4,7 +4,10 @@ use crate::lib::errors;
use std::collections::HashMap;
use std::env;
use std::path;
use std::net;
use std::net::ToSocketAddrs;
use tokio::fs;
use tokio::io;
type Result<T = ()> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;
@@ -12,7 +15,7 @@ type Result<T = ()> = std::result::Result<T, Box<dyn std::error::Error + Send +
pub struct Config {
pub port: Option<u16>,
pub host: Option<String>,
pub interface: Option<Vec<String>>,
pub interface: Option<Vec<net::SocketAddr>>,
pub log: Option<String>,
pub server: Vec<Server>,
}
@@ -65,7 +68,7 @@ impl Config {
}
let fd = fs::read_to_string(p).await.unwrap();
let config: Config = match toml::from_str(&fd) {
let mut config: Config = match toml::from_str(&fd) {
Ok(c) => c,
Err(e) => return Err(Box::new(e)),
};
@@ -86,8 +89,18 @@ impl Config {
"You need to specify either host/port or interface".into(),
)));
} else if config.host.is_some() && config.port.is_some() {
let mut addr: Vec<std::net::SocketAddr> = Vec::new();
addr.push(
format!("{}:{}", &config.host.to_owned().unwrap(), &config.port.unwrap())
.to_socket_addrs()?
.next()
.ok_or_else(|| io::Error::from(io::ErrorKind::AddrNotAvailable))?,
);
config.interface = Some(addr);
return Ok(config);
} else if config.interface.is_some() {
} else if let Some(ref mut i) = config.interface {
i.sort_by(|a, b| a.port().cmp(&b.port()));
i.dedup();
return Ok(config);
}
Err(Box::new(errors::GemError(

View File

@@ -4,7 +4,6 @@ use tokio::net::TcpListener;
use tokio_rustls::server::TlsStream;
use tokio_rustls::TlsAcceptor;
//use futures_util::future::TryFutureExt;
use std::collections::HashMap;
use std::future::Future;
use std::io;
@@ -71,12 +70,10 @@ impl Server {
pub async fn serve(
self,
cmap: HashMap<String, config::ServerCfg>,
default: String,
handler: impl Handler + 'static + Copy,
) -> Result {
for listen in self.listener {
let cmap = cmap.clone();
let default = default.clone();
let listen = Arc::new(listen);
let acceptor = Arc::new(self.acceptor.clone());
@@ -86,8 +83,7 @@ impl Server {
let local_addr = stream.local_addr().unwrap();
let acceptor = acceptor.clone();
let cmap = cmap.clone();
let default = default.clone();
let mut handler = handler.clone();
let mut handler = handler;
tokio::spawn(async move {
let mut stream = match acceptor.accept(stream).await {
@@ -105,7 +101,7 @@ impl Server {
let srv = match cmap.get(sni) {
Some(h) => h,
None => cmap.get(&default).unwrap(),
None => return Ok(()) as io::Result<()>,
}
.to_owned();
@@ -138,7 +134,7 @@ impl Server {
}
}
pub async fn get_request(mut con: conn::Connection) -> Result<(conn::Connection, url::Url)> {
async fn get_request(mut con: conn::Connection) -> Result<(conn::Connection, url::Url)> {
let mut buffer = [0; 1024];
let len = match tokio::time::timeout(
tokio::time::Duration::from_secs(5),

View File

@@ -28,7 +28,7 @@ pub enum Status {
}
impl Status {
pub fn to_str(&self) -> &str {
pub fn to_str(self) -> &'static str {
match self {
Status::Input => "Input",
Status::Success => "Success",

View File

@@ -1,9 +1,6 @@
#[macro_use]
extern crate serde_derive;
use std::io;
use std::net::ToSocketAddrs;
#[cfg(any(feature = "cgi", feature = "scgi"))]
mod cgi;
mod con_handler;
@@ -33,40 +30,17 @@ async fn main() -> errors::Result {
logger::init(&cfg.log)?;
let cmap = cfg.to_map();
let default = &cfg.server[0].hostname;
println!("Serving {} vhosts", cfg.server.len());
let mut addr: Vec<std::net::SocketAddr> = Vec::new();
if cfg.host.is_some() && cfg.port.is_some() {
addr.push(
format!("{}:{}", &cfg.host.to_owned().unwrap(), &cfg.port.unwrap())
.to_socket_addrs()?
.next()
.ok_or_else(|| io::Error::from(io::ErrorKind::AddrNotAvailable))?,
);
} else {
match &cfg.interface {
Some(i) => {
for iface in i {
addr.push(
iface
.to_socket_addrs()?
.next()
.ok_or_else(|| io::Error::from(io::ErrorKind::AddrNotAvailable))?,
);
}
}
None => {}
}
if let Some(i) = &cfg.interface {
addr.append(&mut i.to_owned());
}
addr.sort_by(|a, b| a.port().cmp(&b.port()));
addr.dedup();
let server = server::Server::bind(addr, tls_acceptor_conf, cfg.clone()).await?;
let server = server::Server::bind(addr, tls_acceptor_conf, cfg).await?;
if let Err(e) = server
.serve(
cmap,
default.to_string(),
server::force_boxed(con_handler::handle_connection),
)
.await