diff --git a/docker/prod/docker-compose.yml b/docker/prod/docker-compose.yml index 2189c44..186e8e1 100644 --- a/docker/prod/docker-compose.yml +++ b/docker/prod/docker-compose.yml @@ -2,7 +2,7 @@ version: '3.3' services: pictrs: - image: asonix/pictrs:v0.3.0-alpha.13-shell-out-r2 + image: asonix/pictrs:v0.3.0-alpha.13-shell-out-r3 ports: - "127.0.0.1:8080:8080" restart: always diff --git a/src/exiv2.rs b/src/exiv2.rs index 8ee207e..4c1c2a5 100644 --- a/src/exiv2.rs +++ b/src/exiv2.rs @@ -19,14 +19,6 @@ pub(crate) enum Exvi2Error { Unsupported, } -pub(crate) enum ValidInputType { - Mp4, - Gif, - Png, - Jpeg, - Webp, -} - pub(crate) struct Details { pub(crate) mime_type: mime::Mime, pub(crate) width: usize, @@ -62,42 +54,6 @@ where Ok(()) } -pub(crate) async fn input_type

(file: P) -> Result -where - P: AsRef, -{ - let permit = semaphore().acquire().await?; - - let output = tokio::process::Command::new("exiv2") - .arg(&"pr") - .arg(&file.as_ref()) - .output() - .await?; - drop(permit); - - let s = String::from_utf8_lossy(&output.stdout); - - let mime_line = s - .lines() - .find(|line| line.starts_with("MIME")) - .ok_or_else(|| Exvi2Error::Missing)?; - - let mut segments = mime_line.rsplit(':'); - let mime_type = segments.next().ok_or_else(|| Exvi2Error::Missing)?; - - let input_type = match mime_type.trim() { - "video/mp4" => ValidInputType::Mp4, - "video/quicktime" => ValidInputType::Mp4, - "image/gif" => ValidInputType::Gif, - "image/png" => ValidInputType::Png, - "image/jpeg" => ValidInputType::Jpeg, - "image/webp" => ValidInputType::Webp, - _ => return Err(Exvi2Error::Unsupported), - }; - - Ok(input_type) -} - pub(crate) async fn details

(file: P) -> Result where P: AsRef, diff --git a/src/magick.rs b/src/magick.rs index 4098107..f90c3b9 100644 --- a/src/magick.rs +++ b/src/magick.rs @@ -13,22 +13,14 @@ pub(crate) enum MagickError { Format, } -pub(crate) enum ValidFormat { - Jpeg, +pub(crate) enum ValidInputType { + Mp4, + Gif, Png, + Jpeg, Webp, } -impl ValidFormat { - fn as_magic_type(&self) -> &'static str { - match self { - ValidFormat::Jpeg => "JPEG", - ValidFormat::Png => "PNG", - ValidFormat::Webp => "WEBP", - } - } -} - static MAX_CONVERSIONS: once_cell::sync::OnceCell = once_cell::sync::OnceCell::new(); @@ -69,7 +61,7 @@ where Ok(()) } -pub(crate) async fn validate_format

(file: &P, format: ValidFormat) -> Result<(), MagickError> +pub(crate) async fn input_type

(file: &P) -> Result where P: AsRef, { @@ -85,13 +77,22 @@ where let s = String::from_utf8_lossy(&output.stdout); - if s.lines() - .all(|item| item.is_empty() || item == format.as_magic_type()) - { - return Ok(()); - } + let mut lines = s.lines(); + let first = lines.next(); - Err(MagickError::Format) + let opt = lines.fold(first, |acc, item| match acc { + Some(prev) if prev == item => Some(prev), + _ => None, + }); + + match opt { + Some("MP4") => Ok(ValidInputType::Mp4), + Some("GIF") => Ok(ValidInputType::Gif), + Some("PNG") => Ok(ValidInputType::Png), + Some("JPEG") => Ok(ValidInputType::Jpeg), + Some("WEBP") => Ok(ValidInputType::Webp), + _ => Err(MagickError::Format), + } } pub(crate) async fn process_image( diff --git a/src/validate.rs b/src/validate.rs index 791929b..f374401 100644 --- a/src/validate.rs +++ b/src/validate.rs @@ -1,6 +1,4 @@ -use crate::{ - config::Format, error::UploadError, exiv2::ValidInputType, magick::ValidFormat, tmp_file, -}; +use crate::{config::Format, error::UploadError, magick::ValidInputType, tmp_file}; pub(crate) fn image_webp() -> mime::Mime { "image/webp".parse().unwrap() @@ -16,7 +14,7 @@ pub(crate) async fn validate_image( tmpfile: std::path::PathBuf, prescribed_format: Option, ) -> Result { - let input_type = crate::exiv2::input_type(&tmpfile).await?; + let input_type = crate::magick::input_type(&tmpfile).await?; match (prescribed_format, input_type) { (_, ValidInputType::Gif) | (_, ValidInputType::Mp4) => { @@ -28,8 +26,6 @@ pub(crate) async fn validate_image( Ok(video_mp4()) } (Some(Format::Jpeg), ValidInputType::Jpeg) | (None, ValidInputType::Jpeg) => { - tracing::debug!("Validating format"); - crate::magick::validate_format(&tmpfile, ValidFormat::Jpeg).await?; tracing::debug!("Clearing metadata"); crate::exiv2::clear_metadata(&tmpfile).await?; tracing::debug!("Validated"); @@ -37,8 +33,6 @@ pub(crate) async fn validate_image( Ok(mime::IMAGE_JPEG) } (Some(Format::Png), ValidInputType::Png) | (None, ValidInputType::Png) => { - tracing::debug!("Validating format"); - crate::magick::validate_format(&tmpfile, ValidFormat::Png).await?; tracing::debug!("Clearing metadata"); crate::exiv2::clear_metadata(&tmpfile).await?; tracing::debug!("Validated"); @@ -46,8 +40,6 @@ pub(crate) async fn validate_image( Ok(mime::IMAGE_PNG) } (Some(Format::Webp), ValidInputType::Webp) | (None, ValidInputType::Webp) => { - tracing::debug!("Validating format"); - crate::magick::validate_format(&tmpfile, ValidFormat::Webp).await?; tracing::debug!("Clearing metadata"); crate::exiv2::clear_metadata(&tmpfile).await?; tracing::debug!("Validated");