summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md6
-rwxr-xr-xexamples/body.sh4
-rwxr-xr-xexamples/command.sh3
-rw-r--r--src/script.rs27
-rw-r--r--src/server.rs2
5 files changed, 28 insertions, 14 deletions
diff --git a/README.md b/README.md
index 8ba0773..e6b7580 100644
--- a/README.md
+++ b/README.md
@@ -38,7 +38,7 @@ printf "joe\n"
exit 200
```
-Finally if you wish to read the request body given by the user, that is always stored in argument 1. For example to create a echo endpoint:
+Finally if you wish to read the request body given by the user, that is always stored in stdin. For example to create a echo endpoint:
```sh
#!/bin/bash
@@ -46,8 +46,8 @@ Finally if you wish to read the request body given by the user, that is always s
# we still need to tell there will be no more headers
printf "\n"
-# the body of any http request made will be stored in argument 1
-printf "$1"
+# the body of any http request made will be stored in stdin
+cat
exit 200
```
diff --git a/examples/body.sh b/examples/body.sh
index 5c56df2..bf671df 100755
--- a/examples/body.sh
+++ b/examples/body.sh
@@ -4,7 +4,7 @@
# we still need to tell there will be no more headers
printf "\n"
-# the body of any http request made will be stored in argument 1
-printf "$1"
+# the body of any http request made will be stored in stdin
+cat
exit 200
diff --git a/examples/command.sh b/examples/command.sh
index 52a5666..64e159b 100755
--- a/examples/command.sh
+++ b/examples/command.sh
@@ -6,6 +6,5 @@ printf "\n"
neofetch
-# return http code 418 im a teapot
-exit 418
+exit 200
diff --git a/src/script.rs b/src/script.rs
index 369fbf8..4a94ba4 100644
--- a/src/script.rs
+++ b/src/script.rs
@@ -1,6 +1,8 @@
-use std::{env, collections::HashMap, fs::read_to_string, process::Command, result::Result, error::Error};
+use std::{env, collections::HashMap, process::Stdio, fs::read_to_string, result::Result, error::Error};
+use tokio::process::Command;
+use tokio::io::AsyncWriteExt;
-use crate::http::{response::Response, method::Method};
+use crate::http::{response::Response, method::Method, header::Header};
pub struct Script {
path: String
@@ -11,17 +13,28 @@ impl Script {
Self { path }
}
- pub fn run(&self, body: Option<&String>) -> Result<Response, std::io::Error> {
+ pub async fn run(&self, body: Option<&String>) -> Result<Response, String> {
let mut res = Response::new();
let mut command = Command::new(&self.path);
+ command.stdin(Stdio::piped());
+ command.stdout(Stdio::piped());
+
+ let mut child = match command.spawn() {
+ Ok(child) => child,
+ Err(err) => return Err(format!("{err}"))
+ };
+
if let Some(body) = body {
- command.args([body]);
+ let Some(mut stdin) = child.stdin.take() else {
+ return Err("failed to read stdin".into())
+ };
+ let _ = stdin.write(body.as_bytes()).await;
}
- let output = match command.output() {
+ let output = match child.wait_with_output().await {
Ok(output) => output,
- Err(err) => return Err(err)
+ Err(err) => return Err(format!("{err}"))
};
let status = output.status.code().unwrap_or(500) as u16;
@@ -32,6 +45,8 @@ impl Script {
res.headers.serialize(&mut lines);
let body: String = lines.collect::<Vec<&str>>().join("\n");
+ res.headers.put(Header::new("Content-Length", &format!("{}", body.len())));
+
if body.len() > 0 {
res.body = Some(body);
}
diff --git a/src/server.rs b/src/server.rs
index 4b1f2b3..1d8193f 100644
--- a/src/server.rs
+++ b/src/server.rs
@@ -38,7 +38,7 @@ pub async fn handle_connection(mut socket: TcpStream, config: Arc<Config>) {
return
};
- match script.run(req.body.as_ref()) {
+ match script.run(req.body.as_ref()).await {
Ok(res) => {
let res_str = res.deserialize();
let _ = socket.write(res_str.as_bytes()).await;