req-responder/src/main.rs
Pierre HUBERT ec56fcd876
All checks were successful
continuous-integration/drone/push Build is passing
Enable CI
2025-03-28 16:38:05 +01:00

71 lines
2.0 KiB
Rust

use actix_web::web::Payload;
use actix_web::{App, Error, HttpRequest, HttpResponse, HttpServer, error, web};
use clap::Parser;
use futures::StreamExt;
const MAX_BODY_SIZE: usize = 262_144; // max payload size is 256k
/// Simple HTTP responder
#[derive(Parser, Debug)]
#[clap(author, version, about, long_about = None)]
struct Args {
/// Listen address
#[clap(short, long, env, default_value = "0.0.0.0:8000")]
listen_address: String,
}
async fn handler(req: HttpRequest, mut payload: Payload) -> Result<HttpResponse, Error> {
let mut headers = req
.headers()
.iter()
.map(|h| format!("{}: {}", h.0.as_str(), h.1.to_str().unwrap_or_default()))
.collect::<Vec<_>>();
headers.sort();
let mut body = web::BytesMut::new();
while let Some(chunk) = payload.next().await {
let chunk = chunk?;
// limit max size of in-memory payload
if (body.len() + chunk.len()) > MAX_BODY_SIZE {
return Err(error::ErrorBadRequest("overflow"));
}
body.extend_from_slice(&chunk);
}
let response = format!(
"Remote Peer: {}\nVerb: {}\nPath: {}\nQuery: {}\n\n=== Headers ===\n{}\n\n=== Body ===\n{}",
req.peer_addr().expect("Missing remote peer address!"),
req.head().method,
req.uri().path(),
req.uri().query().unwrap_or_default(),
headers.join("\n"),
String::from_utf8_lossy(&body)
);
Ok(HttpResponse::Ok().content_type("text/plain").body(response))
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));
let args: Args = Args::parse();
log::info!("Will listen on {}...", args.listen_address);
HttpServer::new(|| App::new().route("{tail:.*}", web::route().to(handler)))
.bind(args.listen_address)?
.run()
.await
}
#[cfg(test)]
mod test {
use crate::Args;
#[test]
fn verify_cli() {
use clap::CommandFactory;
Args::command().debug_assert()
}
}