# async-scgi [![License](https://img.shields.io/badge/license-MPL%202.0-blue.svg)]( https://sr.ht/~zethra/async-scgi/) [![Cargo](https://img.shields.io/crates/v/async-scgi.svg)]( https://crates.io/crates/async-scgi) [![Documentation](https://docs.rs/async-scgi/badge.svg)]( https://docs.rs/async-scgi) This is a Rust library for handling SCGI requests and responses in an async context. This library will work with any async runtime that uses the [`futures-io`](https://crates.io/crates/futures-io) library I/O traits. This crate provides two main tools: - The [`ScgiRequest`] type to read & write SCGI requests. - The [`read_request`] function to read an SCGI request from a socket. ## Client Example ```rust use std::str::from_utf8; use async_scgi::{ScgiHeaders, ScgiRequest}; use futures_lite::{AsyncReadExt, AsyncWriteExt}; use smol::net::TcpStream; fn main() -> anyhow::Result<()> { smol::block_on(async { let mut stream = TcpStream::connect("127.0.0.1:12345").await?; let mut headers = ScgiHeaders::new(); headers.insert("PATH_INFO".to_owned(), "/".to_owned()); headers.insert("SERVER_NAME".to_owned(), "example.com".to_owned()); let body = b"Hello world!"; let req = ScgiRequest { headers, body: body.to_vec(), }; stream.write_all(&req.encode()).await?; let mut resp = vec![]; stream.read_to_end(&mut resp).await?; let resp_str = from_utf8(&resp)?; println!("{}", resp_str); Ok(()) }) } ``` ## Server Example ```rust use futures_lite::{AsyncWriteExt, StreamExt}; use smol::io::BufReader; use smol::net::TcpListener; use std::str::from_utf8; fn main() -> anyhow::Result<()> { smol::block_on(async { let listener = TcpListener::bind("127.0.0.1:12345").await?; let mut incoming = listener.incoming(); while let Some(stream) = incoming.next().await { let mut stream = BufReader::new(stream?); let req = async_scgi::read_request(&mut stream).await?; println!("Headers: {:?}", req.headers); println!("Body: {}", from_utf8(&req.body).unwrap()); stream.write_all(b"Hello Client!").await?; } Ok(()) }) } ```