2021-10-21 01:13:39 +00:00
|
|
|
use crate::{
|
2022-10-01 00:38:11 +00:00
|
|
|
config::{AudioCodec, ImageFormat, VideoCodec},
|
2022-03-29 16:04:56 +00:00
|
|
|
either::Either,
|
|
|
|
error::{Error, UploadError},
|
2022-10-02 02:17:18 +00:00
|
|
|
ffmpeg::FileFormat,
|
2022-03-29 16:04:56 +00:00
|
|
|
magick::ValidInputType,
|
2021-10-21 01:13:39 +00:00
|
|
|
};
|
2021-09-04 00:53:53 +00:00
|
|
|
use actix_web::web::Bytes;
|
|
|
|
use tokio::io::AsyncRead;
|
2021-08-28 22:15:14 +00:00
|
|
|
|
2021-09-26 16:02:19 +00:00
|
|
|
struct UnvalidatedBytes {
|
|
|
|
bytes: Bytes,
|
|
|
|
written: usize,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl UnvalidatedBytes {
|
|
|
|
fn new(bytes: Bytes) -> Self {
|
|
|
|
UnvalidatedBytes { bytes, written: 0 }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl AsyncRead for UnvalidatedBytes {
|
|
|
|
fn poll_read(
|
|
|
|
mut self: std::pin::Pin<&mut Self>,
|
|
|
|
_cx: &mut std::task::Context<'_>,
|
|
|
|
buf: &mut tokio::io::ReadBuf<'_>,
|
|
|
|
) -> std::task::Poll<std::io::Result<()>> {
|
|
|
|
let bytes_to_write = (self.bytes.len() - self.written).min(buf.remaining());
|
|
|
|
if bytes_to_write > 0 {
|
|
|
|
let end = self.written + bytes_to_write;
|
|
|
|
buf.put_slice(&self.bytes[self.written..end]);
|
|
|
|
self.written = end;
|
|
|
|
}
|
|
|
|
std::task::Poll::Ready(Ok(()))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-02 02:17:18 +00:00
|
|
|
#[tracing::instrument(skip_all)]
|
2022-10-01 00:38:11 +00:00
|
|
|
pub(crate) async fn validate_bytes(
|
2021-09-04 00:53:53 +00:00
|
|
|
bytes: Bytes,
|
2022-03-28 04:27:07 +00:00
|
|
|
prescribed_format: Option<ImageFormat>,
|
2022-03-29 16:04:56 +00:00
|
|
|
enable_silent_video: bool,
|
2022-09-25 23:16:37 +00:00
|
|
|
enable_full_video: bool,
|
2022-10-01 00:38:11 +00:00
|
|
|
video_codec: VideoCodec,
|
|
|
|
audio_codec: Option<AudioCodec>,
|
2021-09-26 16:02:19 +00:00
|
|
|
validate: bool,
|
2021-10-23 17:35:07 +00:00
|
|
|
) -> Result<(ValidInputType, impl AsyncRead + Unpin), Error> {
|
2022-09-26 01:39:09 +00:00
|
|
|
let input_type =
|
|
|
|
if let Some(input_type) = crate::ffmpeg::input_type_bytes(bytes.clone()).await? {
|
|
|
|
input_type
|
|
|
|
} else {
|
|
|
|
crate::magick::input_type_bytes(bytes.clone()).await?
|
|
|
|
};
|
2021-09-04 00:53:53 +00:00
|
|
|
|
2021-09-26 16:02:19 +00:00
|
|
|
if !validate {
|
2021-10-23 17:35:07 +00:00
|
|
|
return Ok((input_type, Either::left(UnvalidatedBytes::new(bytes))));
|
2021-09-26 16:02:19 +00:00
|
|
|
}
|
|
|
|
|
2022-10-02 02:17:18 +00:00
|
|
|
match (input_type.to_file_format(), prescribed_format) {
|
|
|
|
(FileFormat::Video(video_format), _) => {
|
2022-09-25 23:16:37 +00:00
|
|
|
if !(enable_silent_video || enable_full_video) {
|
2022-03-29 16:04:56 +00:00
|
|
|
return Err(UploadError::SilentVideoDisabled.into());
|
|
|
|
}
|
|
|
|
Ok((
|
2022-10-01 01:00:14 +00:00
|
|
|
ValidInputType::from_video_codec(video_codec),
|
2022-10-02 03:47:52 +00:00
|
|
|
Either::right(Either::left(Either::left(
|
2022-10-01 00:38:11 +00:00
|
|
|
crate::ffmpeg::trancsocde_bytes(
|
|
|
|
bytes,
|
2022-10-02 02:17:18 +00:00
|
|
|
video_format,
|
2022-10-01 00:38:11 +00:00
|
|
|
enable_full_video,
|
|
|
|
video_codec,
|
|
|
|
audio_codec,
|
|
|
|
)
|
|
|
|
.await?,
|
2022-10-02 03:47:52 +00:00
|
|
|
))),
|
2022-09-25 23:16:37 +00:00
|
|
|
))
|
|
|
|
}
|
2022-10-02 02:17:18 +00:00
|
|
|
(FileFormat::Image(image_format), Some(format)) if image_format != format => Ok((
|
|
|
|
ValidInputType::from_format(format),
|
2022-10-02 03:47:52 +00:00
|
|
|
Either::right(Either::left(Either::right(
|
2022-10-02 02:17:18 +00:00
|
|
|
crate::magick::convert_bytes_read(bytes, format)?,
|
2021-10-21 01:13:39 +00:00
|
|
|
))),
|
2021-09-04 00:53:53 +00:00
|
|
|
)),
|
2022-10-02 03:47:52 +00:00
|
|
|
(FileFormat::Image(ImageFormat::Webp), _) => Ok((
|
|
|
|
ValidInputType::Webp,
|
|
|
|
Either::right(Either::left(Either::right(
|
|
|
|
crate::magick::convert_bytes_read(bytes, ImageFormat::Webp)?,
|
|
|
|
))),
|
|
|
|
)),
|
2022-10-15 16:13:24 +00:00
|
|
|
(FileFormat::Image(image_format), _) => {
|
|
|
|
if crate::exiftool::needs_reorienting(bytes.clone()).await? {
|
|
|
|
Ok((
|
|
|
|
ValidInputType::from_format(image_format),
|
|
|
|
Either::right(Either::left(Either::right(
|
|
|
|
crate::magick::convert_bytes_read(bytes, image_format)?,
|
|
|
|
))),
|
|
|
|
))
|
|
|
|
} else {
|
|
|
|
Ok((
|
|
|
|
ValidInputType::from_format(image_format),
|
|
|
|
Either::right(Either::right(crate::exiftool::clear_metadata_bytes_read(
|
|
|
|
bytes,
|
|
|
|
)?)),
|
|
|
|
))
|
|
|
|
}
|
|
|
|
}
|
2021-09-04 00:53:53 +00:00
|
|
|
}
|
|
|
|
}
|