#[macro_use] extern crate lazy_static; use actix_web::{get, post, App, HttpResponse, HttpServer, Responder}; use base64::decode; use listenfd::ListenFd; use regex::Regex; lazy_static! { static ref DATA_URI_RE: Regex = Regex::new("^data:image/(?Ppng|jpg|jpeg);base64,(?P.+)") .expect("Couldn't parse Regex!"); } #[get("/")] async fn hello() -> impl Responder { HttpResponse::Ok().body("Hey, this is an API!") } #[post("/products")] async fn create_product(req_body: String) -> impl Responder { let caps = if let Some(c) = DATA_URI_RE.captures(&req_body) { c } else { return HttpResponse::BadRequest().body("Invalid data URI or image format."); }; let format = caps .name("format") .expect("Data URI format extraction should never fail.") .as_str(); let data = caps .name("data") .expect("Data URI data extraction should never fail.") .as_str(); let bytes = if let Ok(b) = decode(data) { b } else { return HttpResponse::BadRequest().body("Invalid image data in data URI."); }; let img = image::load_from_memory(&bytes).unwrap(); img.save("test.png").unwrap(); HttpResponse::Ok().body(format!("created\n{}\n{}", format, data)) } #[get("/products")] async fn get_products(_req_body: String) -> impl Responder { HttpResponse::Ok().body("got product!") } #[actix_web::main] async fn main() -> std::io::Result<()> { let mut listenfd = ListenFd::from_env(); let mut server = HttpServer::new(|| { App::new() .service(hello) .service(create_product) .service(get_products) }); server = if let Some(l) = listenfd.take_tcp_listener(0).unwrap() { // "Debug mode" with cargo watch auto-reloading server.listen(l)? } else { // "Release mode" server.bind("127.0.0.1:8000")? }; server.run().await }