Bug fix: If text file wasn't utf8 it would fail and not send any
response to clients.
This commit is contained in:
61
Cargo.lock
generated
61
Cargo.lock
generated
@@ -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",
|
||||
|
||||
12
Cargo.toml
12
Cargo.toml
@@ -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"]
|
||||
|
||||
|
||||
@@ -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,18 +308,35 @@ pub async fn handle_connection(mut con: conn::Connection, url: url::Url) -> Resu
|
||||
}
|
||||
|
||||
let mut mime = get_mime(&path);
|
||||
if mime == "text/gemini" && con.srv.server.lang.is_some() {
|
||||
mime += &("; lang=".to_string() + &con.srv.server.lang.to_owned().unwrap());
|
||||
}
|
||||
if !mime.starts_with("text/") {
|
||||
logger::logger(con.peer_addr, Status::Success, url.as_str());
|
||||
get_binary(con, path, mime).await?;
|
||||
return Ok(());
|
||||
}
|
||||
let content = get_content(path, &url).await?;
|
||||
con.send_body(Status::Success, Some(&mime), Some(content))
|
||||
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());
|
||||
}
|
||||
if !mime.starts_with("text/") {
|
||||
logger::logger(con.peer_addr, Status::Success, url.as_str());
|
||||
get_binary(con, path, mime).await?;
|
||||
return Ok(());
|
||||
}
|
||||
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());
|
||||
logger::logger(con.peer_addr, Status::Success, url.as_str());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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",
|
||||
|
||||
32
src/main.rs
32
src/main.rs
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user