basic functionality

This commit is contained in:
Timofey Gelazoniya 2023-07-10 22:02:10 +03:00
parent 3cf13b4454
commit 416e33db7f
Signed by: zeldon
GPG Key ID: 047886915281DD2A
3 changed files with 71 additions and 6 deletions

25
Cargo.lock generated
View File

@ -303,6 +303,12 @@ dependencies = [
"pin-project-lite",
]
[[package]]
name = "http-range-header"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0bfe8eed0a9285ef776bb792479ea3834e8b94e13d615c2f66d03dd50a435a29"
[[package]]
name = "httparse"
version = "1.8.0"
@ -379,6 +385,7 @@ dependencies = [
"axum",
"magick_rust",
"tokio",
"tower-http",
]
[[package]]
@ -748,6 +755,24 @@ dependencies = [
"tracing",
]
[[package]]
name = "tower-http"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8bd22a874a2d0b70452d5597b12c537331d49060824a95f49f108994f94aa4c"
dependencies = [
"bitflags 2.3.3",
"bytes",
"futures-core",
"futures-util",
"http",
"http-body",
"http-range-header",
"pin-project-lite",
"tower-layer",
"tower-service",
]
[[package]]
name = "tower-layer"
version = "0.3.2"

View File

@ -3,9 +3,8 @@ name = "liquid-rescale-api-v2"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
axum = { version = "0.6", features = ["multipart", "macros"] }
tokio = { version = "1.29.1", features = ["macros", "rt-multi-thread"] }
tower-http = { version = "0.4.1", features = ["limit"] }
magick_rust = "0.19.0"

View File

@ -1,6 +1,18 @@
use std::{env::var, io, net::SocketAddr};
use std::{env::var, io, net::SocketAddr, sync::Once};
use axum::{routing::get, Router};
use axum::{
body::{Bytes, Full},
extract::{DefaultBodyLimit, Multipart},
http::StatusCode,
response::{IntoResponse, Response},
routing::get,
Router,
};
use magick_rust::{magick_wand_genesis, MagickWand};
use tower_http::limit::RequestBodyLimitLayer;
static START: Once = Once::new();
#[tokio::main]
async fn main() -> io::Result<()> {
@ -14,6 +26,8 @@ async fn main() -> io::Result<()> {
.serve(
Router::new()
.route("/", get(handle_request))
.layer(DefaultBodyLimit::disable())
.layer(RequestBodyLimitLayer::new(10 * 1024 * 1024 /* 10mb */))
.into_make_service(),
)
.await
@ -22,6 +36,33 @@ async fn main() -> io::Result<()> {
Ok(())
}
async fn handle_request() -> &'static str {
"Hello world!"
async fn handle_request(mut payload: Multipart) -> Result<Response<Full<Bytes>>, Response> {
let mut data: Vec<u8> = 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())
}