use std::env::var; use std::io; use std::net::SocketAddr; use std::sync::Once; use axum::body::Bytes; use axum::body::Full; use axum::extract::DefaultBodyLimit; use axum::extract::Multipart; use axum::http::StatusCode; use axum::response::IntoResponse; use axum::response::Response; use axum::routing::post; use axum::Router; use magick_rust::magick_wand_genesis; use magick_rust::MagickWand; use tower_http::limit::RequestBodyLimitLayer; use tracing_subscriber::prelude::__tracing_subscriber_SubscriberExt; use tracing_subscriber::util::SubscriberInitExt; static START: Once = Once::new(); #[tokio::main] async fn main() -> io::Result<()> { tracing_subscriber::registry() .with( tracing_subscriber::EnvFilter::try_from_default_env() .unwrap_or_else(|_| "liquid-rescale-api-v2=debug,tower_http=debug".into()), ) .with(tracing_subscriber::fmt::layer()) .init(); axum::Server::bind(&SocketAddr::from(( [0, 0, 0, 0], match var("SERVER_PORT") { Ok(port) => port.parse::().unwrap(), Err(_) => 8321, }, ))) .serve( Router::new() .route("/", post(handle_request)) .layer(DefaultBodyLimit::disable()) .layer(RequestBodyLimitLayer::new(10 * 1024 * 1024 /* 10mb */)) .layer(tower_http::trace::TraceLayer::new_for_http()) .into_make_service(), ) .await .unwrap(); Ok(()) } async fn handle_request(mut payload: Multipart) -> Result>, Response> { let mut data: Vec = Vec::new(); while let Some(field) = payload.next_field().await.unwrap() { let content_type = field.content_type().unwrap(); match content_type { "image/jpeg" | "image/png" => data = field.bytes().await.unwrap().to_vec(), _ => return Err(StatusCode::UNSUPPORTED_MEDIA_TYPE.into_response()), } } START.call_once(|| magick_wand_genesis()); let wand = MagickWand::new(); wand.read_image_blob(&data).unwrap(); wand.fit(640, 640); wand.liquid_rescale_image(320, 320, 1.0, 0.0).unwrap(); wand.fit(640, 640); let bytes = wand.write_image_blob("JPEG").unwrap(); let body = Full::from(bytes); Ok(Response::builder() .status(StatusCode::OK) .header("Content-Type", "image/jpeg") .body(Full::from(body)) .unwrap()) }