diff options
author | Tyler Murphy <tylerm@tylerm.dev> | 2023-07-02 22:40:04 -0400 |
---|---|---|
committer | Tyler Murphy <tylerm@tylerm.dev> | 2023-07-02 22:40:04 -0400 |
commit | 77eee644c9c9bf6e3c19a5c6efb9d31f5d91318e (patch) | |
tree | 9e8ef5086cb7e30057ead2a78b0347bf3341ce46 | |
parent | add methods to routes, allow custom headers and response codes (diff) | |
download | bashttp-77eee644c9c9bf6e3c19a5c6efb9d31f5d91318e.tar.gz bashttp-77eee644c9c9bf6e3c19a5c6efb9d31f5d91318e.tar.bz2 bashttp-77eee644c9c9bf6e3c19a5c6efb9d31f5d91318e.zip |
move body to stdin
-rw-r--r-- | README.md | 6 | ||||
-rwxr-xr-x | examples/body.sh | 4 | ||||
-rwxr-xr-x | examples/command.sh | 3 | ||||
-rw-r--r-- | src/script.rs | 27 | ||||
-rw-r--r-- | src/server.rs | 2 |
5 files changed, 28 insertions, 14 deletions
@@ -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; |