move body to stdin

This commit is contained in:
Murphy 2023-07-02 22:40:04 -04:00
parent 41fe16978e
commit 77eee644c9
5 changed files with 28 additions and 14 deletions

View file

@ -38,7 +38,7 @@ printf "joe\n"
exit 200 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 ```sh
#!/bin/bash #!/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 # we still need to tell there will be no more headers
printf "\n" printf "\n"
# the body of any http request made will be stored in argument 1 # the body of any http request made will be stored in stdin
printf "$1" cat
exit 200 exit 200
``` ```

View file

@ -4,7 +4,7 @@
# we still need to tell there will be no more headers # we still need to tell there will be no more headers
printf "\n" printf "\n"
# the body of any http request made will be stored in argument 1 # the body of any http request made will be stored in stdin
printf "$1" cat
exit 200 exit 200

View file

@ -6,6 +6,5 @@ printf "\n"
neofetch neofetch
# return http code 418 im a teapot exit 200
exit 418

View file

@ -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 { pub struct Script {
path: String path: String
@ -11,17 +13,28 @@ impl Script {
Self { path } 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 res = Response::new();
let mut command = Command::new(&self.path); 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 { 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, Ok(output) => output,
Err(err) => return Err(err) Err(err) => return Err(format!("{err}"))
}; };
let status = output.status.code().unwrap_or(500) as u16; let status = output.status.code().unwrap_or(500) as u16;
@ -32,6 +45,8 @@ impl Script {
res.headers.serialize(&mut lines); res.headers.serialize(&mut lines);
let body: String = lines.collect::<Vec<&str>>().join("\n"); let body: String = lines.collect::<Vec<&str>>().join("\n");
res.headers.put(Header::new("Content-Length", &format!("{}", body.len())));
if body.len() > 0 { if body.len() > 0 {
res.body = Some(body); res.body = Some(body);
} }

View file

@ -38,7 +38,7 @@ pub async fn handle_connection(mut socket: TcpStream, config: Arc<Config>) {
return return
}; };
match script.run(req.body.as_ref()) { match script.run(req.body.as_ref()).await {
Ok(res) => { Ok(res) => {
let res_str = res.deserialize(); let res_str = res.deserialize();
let _ = socket.write(res_str.as_bytes()).await; let _ = socket.write(res_str.as_bytes()).await;