Timeout for request and cgi
This commit is contained in:
@@ -7,7 +7,7 @@ edition = "2018"
|
|||||||
# 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 = "0.2", features = [ "net", "io-util", "rt-threaded" ] }
|
tokio = { version = "0.2", features = [ "time", "fs", "process", "net", "io-util", "rt-threaded" ] }
|
||||||
openssl = "0.10"
|
openssl = "0.10"
|
||||||
tokio-openssl = "0.4"
|
tokio-openssl = "0.4"
|
||||||
futures-util = "0.3"
|
futures-util = "0.3"
|
||||||
|
|||||||
25
src/cgi.rs
25
src/cgi.rs
@@ -1,7 +1,7 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::process::Command;
|
use tokio::process::Command;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use crate::config;
|
use crate::config;
|
||||||
@@ -44,8 +44,27 @@ pub async fn cgi(
|
|||||||
let cmd = Command::new(path.to_str().unwrap())
|
let cmd = Command::new(path.to_str().unwrap())
|
||||||
.env_clear()
|
.env_clear()
|
||||||
.envs(&envs)
|
.envs(&envs)
|
||||||
.output()
|
.output();
|
||||||
.unwrap();
|
|
||||||
|
let cmd = match tokio::time::timeout(tokio::time::Duration::from_secs(5), cmd).await {
|
||||||
|
Ok(c) => {
|
||||||
|
match c {
|
||||||
|
Ok(cc) => cc,
|
||||||
|
|
||||||
|
Err(_) => {
|
||||||
|
logger::logger(con.peer_addr, Status::CGIError, url.as_str());
|
||||||
|
con.send_status(Status::CGIError, None).await?;
|
||||||
|
return Ok(());
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(_) => {
|
||||||
|
logger::logger(con.peer_addr, Status::CGIError, url.as_str());
|
||||||
|
con.send_status(Status::CGIError, None).await?;
|
||||||
|
return Ok(());
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
if !cmd.status.success() {
|
if !cmd.status.success() {
|
||||||
logger::logger(con.peer_addr, Status::CGIError, url.as_str());
|
logger::logger(con.peer_addr, Status::CGIError, url.as_str());
|
||||||
con.send_status(Status::CGIError, None).await?;
|
con.send_status(Status::CGIError, None).await?;
|
||||||
|
|||||||
22
src/main.rs
22
src/main.rs
@@ -66,10 +66,10 @@ async fn get_binary(mut con: conn::Connection, path: PathBuf, meta: String) -> i
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
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 = fs::metadata(&path).expect("Unable to read metadata");
|
let meta = tokio::fs::metadata(&path).await?;
|
||||||
if meta.is_file() {
|
if meta.is_file() {
|
||||||
return Ok(std::fs::read_to_string(path).expect("Unable to read file"));
|
return Ok(tokio::fs::read_to_string(path).await?);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut list = String::from("# Directory Listing\r\n\r\n");
|
let mut list = String::from("# Directory Listing\r\n\r\n");
|
||||||
@@ -104,7 +104,11 @@ async fn handle_connection(
|
|||||||
None => "index.gemini".to_string(),
|
None => "index.gemini".to_string(),
|
||||||
};
|
};
|
||||||
let mut buffer = [0; 1024];
|
let mut buffer = [0; 1024];
|
||||||
con.stream.read(&mut buffer).await?;
|
if let Err(_) = tokio::time::timeout(tokio::time::Duration::from_secs(5), con.stream.read(&mut buffer)).await {
|
||||||
|
logger::logger(con.peer_addr, Status::BadRequest, "");
|
||||||
|
con.send_status(Status::BadRequest, None).await?;
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
let mut request = match String::from_utf8(buffer[..].to_vec()) {
|
let mut request = match String::from_utf8(buffer[..].to_vec()) {
|
||||||
Ok(request) => request,
|
Ok(request) => request,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
@@ -201,7 +205,7 @@ async fn handle_connection(
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut meta = fs::metadata(&path).expect("Unable to read metadata");
|
let mut meta = tokio::fs::metadata(&path).await?;
|
||||||
let mut perm = meta.permissions();
|
let mut perm = meta.permissions();
|
||||||
|
|
||||||
// TODO fix me
|
// TODO fix me
|
||||||
@@ -218,19 +222,18 @@ async fn handle_connection(
|
|||||||
}
|
}
|
||||||
if path.join(&index).exists() {
|
if path.join(&index).exists() {
|
||||||
path.push(index);
|
path.push(index);
|
||||||
meta = fs::metadata(&path).expect("Unable to read metadata");
|
meta = tokio::fs::metadata(&path).await?;
|
||||||
perm = meta.permissions();
|
perm = meta.permissions();
|
||||||
if perm.mode() & 0o0444 != 0o444 {
|
if perm.mode() & 0o0444 != 0o444 {
|
||||||
let mut p = path.clone();
|
let mut p = path.clone();
|
||||||
p.pop();
|
p.pop();
|
||||||
path.push(format!("{}/", p.display()));
|
path.push(format!("{}/", p.display()));
|
||||||
meta = fs::metadata(&path).expect("Unable to read metadata");
|
meta = tokio::fs::metadata(&path).await?;
|
||||||
perm = meta.permissions();
|
perm = meta.permissions();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO add timeout
|
|
||||||
match &srv.server.cgi {
|
match &srv.server.cgi {
|
||||||
Some(c) => {
|
Some(c) => {
|
||||||
if c.trim_end_matches("/") == path.parent().unwrap().to_str().unwrap() {
|
if c.trim_end_matches("/") == path.parent().unwrap().to_str().unwrap() {
|
||||||
@@ -259,7 +262,7 @@ async fn handle_connection(
|
|||||||
get_binary(con, path, mime).await?;
|
get_binary(con, path, mime).await?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
let content = get_content(path, url)?;
|
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, &request);
|
||||||
@@ -293,6 +296,7 @@ fn main() -> io::Result<()> {
|
|||||||
let mut runtime = runtime::Builder::new()
|
let mut runtime = runtime::Builder::new()
|
||||||
.threaded_scheduler()
|
.threaded_scheduler()
|
||||||
.enable_io()
|
.enable_io()
|
||||||
|
.enable_time()
|
||||||
.build()?;
|
.build()?;
|
||||||
|
|
||||||
let handle = runtime.handle().clone();
|
let handle = runtime.handle().clone();
|
||||||
|
|||||||
Reference in New Issue
Block a user