1use std::future::Future;
4
5use cegla::{
6 server::{convert_cgi_request, convert_from_http_response},
7 CgiEnvironment, CgiIncoming,
8};
9use tokio::io::{AsyncRead, AsyncWrite};
10use tokio_util::io::StreamReader;
11
12pub async fn handle_request<I, O, E, F, Fut, B, Err>(
15 stdin: I,
16 mut stdout: O,
17 stderr: E,
18 request_fn: F,
19) -> Result<(), std::io::Error>
20where
21 I: AsyncRead + Unpin + 'static,
22 O: AsyncWrite + Unpin,
23 E: AsyncWrite + Unpin,
24 F: FnOnce(http::Request<CgiIncoming<I>>, E) -> Fut,
25 Fut: Future<Output = Result<http::Response<B>, Err>>,
26 B: http_body::Body,
27 B::Data: AsRef<[u8]> + Send + 'static,
28 B::Error: Into<std::io::Error>,
29 Err: Into<std::io::Error>,
30{
31 let request = convert_cgi_request(stdin, CgiEnvironment::from_iter(std::env::vars()))?;
32
33 let response = request_fn(request, stderr).await.map_err(|err| err.into())?;
34
35 let response_data = convert_from_http_response(response)?;
36 let mut response_reader = StreamReader::new(response_data);
37 tokio::io::copy(&mut response_reader, &mut stdout).await?;
38
39 Ok(())
40}