2
0
Fork 0
mirror of https://git.asonix.dog/asonix/pict-rs synced 2024-11-10 06:25:00 +00:00

Update to actix-web 4.0.0-beta.3

This commit is contained in:
asonix 2021-02-10 16:57:42 -06:00
parent d51a73cee9
commit 79b26a1dda
8 changed files with 376 additions and 748 deletions

927
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
[package] [package]
name = "pict-rs" name = "pict-rs"
description = "A simple image hosting service" description = "A simple image hosting service"
version = "0.3.0-alpha.6" version = "0.3.0-alpha.7"
authors = ["asonix <asonix@asonix.dog>"] authors = ["asonix <asonix@asonix.dog>"]
license = "AGPL-3.0" license = "AGPL-3.0"
readme = "README.md" readme = "README.md"
@ -11,24 +11,23 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
actix-form-data = "0.5.0" actix-form-data = "0.6.0-beta.1"
actix-fs = { git = "https://git.asonix.dog/asonix/actix-fs", branch = "main" } actix-fs = { git = "https://git.asonix.dog/asonix/actix-fs", branch = "asonix/actix-rt-2" }
actix-rt = "1.1.1" actix-rt = "2.0.2"
actix-web = { version = "3.0.1", default-features = false, features = ["rustls"] } actix-web = { version = "4.0.0-beta.3", default-features = false, features = ["rustls", "compress"] }
anyhow = "1.0" anyhow = "1.0"
async-stream = "0.3.0" async-stream = "0.3.0"
base64 = "0.13.0" base64 = "0.13.0"
bytes = "0.5"
futures = "0.3.4" futures = "0.3.4"
magick_rust = { version = "0.14.0", git = "https://github.com/nlfiedler/magick-rust" } magick_rust = { version = "0.14.0", git = "https://github.com/nlfiedler/magick-rust" }
mime = "0.3.1" mime = "0.3.1"
once_cell = "1.4.0" once_cell = "1.4.0"
rand = "0.7.3" rand = "0.8.0"
rexiv2 = "0.9.1" rexiv2 = "0.9.1"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0" serde_json = "1.0"
sha2 = "0.9.0" sha2 = "0.9.0"
sled = { version = "0.34.4" } sled = { version = "0.34.6" }
structopt = "0.3.14" structopt = "0.3.14"
thiserror = "1.0" thiserror = "1.0"
time = { version = "0.2.23", features = ["serde"] } time = { version = "0.2.23", features = ["serde"] }
@ -44,3 +43,7 @@ features = ["codec", "filter", "device", "format", "resampling", "postprocessing
[dependencies.ffmpeg-sys-next] [dependencies.ffmpeg-sys-next]
version = "4.3.5" version = "4.3.5"
git = "https://github.com/baadc0de/rust-ffmpeg-sys"
[patch.crates-io]
ffmpeg-sys-next = { git = "https://github.com/baadc0de/rust-ffmpeg-sys", branch = "master" }

View file

@ -100,15 +100,9 @@ impl From<actix_form_data::Error> for UploadError {
} }
} }
impl<T> From<actix_web::error::BlockingError<T>> for UploadError impl From<actix_web::error::BlockingError> for UploadError {
where fn from(_: actix_web::error::BlockingError) -> Self {
T: Into<UploadError> + std::fmt::Debug, UploadError::Canceled
{
fn from(e: actix_web::error::BlockingError<T>) -> Self {
match e {
actix_web::error::BlockingError::Error(e) => e.into(),
_ => UploadError::Canceled,
}
} }
} }
@ -128,6 +122,7 @@ impl ResponseError for UploadError {
} }
fn error_response(&self) -> HttpResponse { fn error_response(&self) -> HttpResponse {
HttpResponse::build(self.status_code()).json(serde_json::json!({ "msg": self.to_string() })) HttpResponse::build(self.status_code())
.json(&serde_json::json!({ "msg": self.to_string() }))
} }
} }

View file

@ -7,7 +7,6 @@ use actix_web::{
middleware::{Compress, Logger}, middleware::{Compress, Logger},
web, App, HttpResponse, HttpServer, web, App, HttpResponse, HttpServer,
}; };
use bytes::Bytes;
use futures::stream::{once, Stream, TryStreamExt}; use futures::stream::{once, Stream, TryStreamExt};
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use std::{ use std::{
@ -50,6 +49,7 @@ static TMP_DIR: Lazy<PathBuf> = Lazy::new(|| {
let tmp_nonce = Alphanumeric let tmp_nonce = Alphanumeric
.sample_iter(&mut rng) .sample_iter(&mut rng)
.take(7) .take(7)
.map(char::from)
.collect::<String>(); .collect::<String>();
let mut path = std::env::temp_dir(); let mut path = std::env::temp_dir();
@ -93,7 +93,7 @@ async fn safe_create_parent(path: PathBuf) -> Result<(), UploadError> {
// Try writing to a file // Try writing to a file
#[instrument(skip(bytes))] #[instrument(skip(bytes))]
async fn safe_save_file(path: PathBuf, bytes: bytes::Bytes) -> Result<(), UploadError> { async fn safe_save_file(path: PathBuf, bytes: web::Bytes) -> Result<(), UploadError> {
if let Some(path) = path.parent() { if let Some(path) = path.parent() {
// create the directory for the file // create the directory for the file
debug!("Creating directory {:?}", path); debug!("Creating directory {:?}", path);
@ -132,7 +132,11 @@ pub(crate) fn tmp_file() -> PathBuf {
let limit: usize = 10; let limit: usize = 10;
let rng = rand::thread_rng(); let rng = rand::thread_rng();
let s: String = Alphanumeric.sample_iter(rng).take(limit).collect(); let s: String = Alphanumeric
.sample_iter(rng)
.take(limit)
.map(char::from)
.collect();
let name = format!("{}.tmp", s); let name = format!("{}.tmp", s);
@ -203,7 +207,7 @@ async fn upload(
} }
} }
Ok(HttpResponse::Created().json(serde_json::json!({ Ok(HttpResponse::Created().json(&serde_json::json!({
"msg": "ok", "msg": "ok",
"files": files "files": files
}))) })))
@ -250,7 +254,7 @@ async fn download(
new_details new_details
}; };
Ok(HttpResponse::Created().json(serde_json::json!({ Ok(HttpResponse::Created().json(&serde_json::json!({
"msg": "ok", "msg": "ok",
"files": [{ "files": [{
"file": alias, "file": alias,
@ -334,7 +338,7 @@ async fn process_details(
let details = details.ok_or(UploadError::NoFiles)?; let details = details.ok_or(UploadError::NoFiles)?;
Ok(HttpResponse::Ok().json(details)) Ok(HttpResponse::Ok().json(&details))
} }
/// Process files /// Process files
@ -447,7 +451,7 @@ async fn process(
let range = range_header.ranges().next().unwrap(); let range = range_header.ranges().next().unwrap();
let mut builder = HttpResponse::PartialContent(); let mut builder = HttpResponse::PartialContent();
builder.set(range.to_content_range(img_bytes.len() as u64)); builder.insert_header(range.to_content_range(img_bytes.len() as u64));
(builder, range.chop_bytes(img_bytes)) (builder, range.chop_bytes(img_bytes))
} else { } else {
return Err(UploadError::Range); return Err(UploadError::Range);
@ -499,7 +503,7 @@ async fn details(
new_details new_details
}; };
Ok(HttpResponse::Ok().json(details)) Ok(HttpResponse::Ok().json(&details))
} }
/// Serve files /// Serve files
@ -550,7 +554,7 @@ async fn ranged_file_resp(
let range = range_header.ranges().next().unwrap(); let range = range_header.ranges().next().unwrap();
let mut builder = HttpResponse::PartialContent(); let mut builder = HttpResponse::PartialContent();
builder.set(range.to_content_range(meta.len())); builder.insert_header(range.to_content_range(meta.len()));
(builder, range.chop_file(file).await?) (builder, range.chop_file(file).await?)
} else { } else {
@ -562,7 +566,8 @@ async fn ranged_file_resp(
let stream = actix_fs::read_to_stream(path) let stream = actix_fs::read_to_stream(path)
.await? .await?
.map_err(UploadError::from); .map_err(UploadError::from);
let stream: Pin<Box<dyn Stream<Item = Result<Bytes, UploadError>>>> = Box::pin(stream); let stream: Pin<Box<dyn Stream<Item = Result<web::Bytes, UploadError>>>> =
Box::pin(stream);
(HttpResponse::Ok(), stream) (HttpResponse::Ok(), stream)
} }
}; };
@ -585,18 +590,18 @@ fn srv_response<S, E>(
modified: SystemTime, modified: SystemTime,
) -> HttpResponse ) -> HttpResponse
where where
S: Stream<Item = Result<bytes::Bytes, E>> + Unpin + 'static, S: Stream<Item = Result<web::Bytes, E>> + Unpin + 'static,
E: 'static, E: 'static,
actix_web::Error: From<E>, actix_web::Error: From<E>,
{ {
builder builder
.set(LastModified(modified.into())) .insert_header(LastModified(modified.into()))
.set(CacheControl(vec![ .insert_header(CacheControl(vec![
CacheDirective::Public, CacheDirective::Public,
CacheDirective::MaxAge(expires), CacheDirective::MaxAge(expires),
CacheDirective::Extension("immutable".to_owned(), None), CacheDirective::Extension("immutable".to_owned(), None),
])) ]))
.set_header(ACCEPT_RANGES, "bytes") .insert_header((ACCEPT_RANGES, "bytes"))
.content_type(ext.to_string()) .content_type(ext.to_string())
.streaming(stream) .streaming(stream)
} }
@ -623,7 +628,7 @@ async fn purge(
.await?; .await?;
} }
Ok(HttpResponse::Ok().json(serde_json::json!({ Ok(HttpResponse::Ok().json(&serde_json::json!({
"msg": "ok", "msg": "ok",
"aliases": aliases "aliases": aliases
}))) })))
@ -638,7 +643,7 @@ async fn aliases(
FileOrAlias::Alias { alias } => upload_manager.aliases_by_alias(alias).await?, FileOrAlias::Alias { alias } => upload_manager.aliases_by_alias(alias).await?,
}; };
Ok(HttpResponse::Ok().json(serde_json::json!({ Ok(HttpResponse::Ok().json(&serde_json::json!({
"msg": "ok", "msg": "ok",
"aliases": aliases, "aliases": aliases,
}))) })))
@ -655,7 +660,7 @@ async fn filename_by_alias(
) -> Result<HttpResponse, UploadError> { ) -> Result<HttpResponse, UploadError> {
let filename = upload_manager.from_alias(query.into_inner().alias).await?; let filename = upload_manager.from_alias(query.into_inner().alias).await?;
Ok(HttpResponse::Ok().json(serde_json::json!({ Ok(HttpResponse::Ok().json(&serde_json::json!({
"msg": "ok", "msg": "ok",
"filename": filename, "filename": filename,
}))) })))

View file

@ -26,16 +26,16 @@ impl ResponseError for ApiError {
} }
fn error_response(&self) -> HttpResponse { fn error_response(&self) -> HttpResponse {
HttpResponse::build(self.status_code()).json(serde_json::json!({ "msg": self.to_string() })) HttpResponse::build(self.status_code())
.json(&serde_json::json!({ "msg": self.to_string() }))
} }
} }
impl<S> Transform<S> for Tracing impl<S, Request> Transform<S, Request> for Tracing
where where
S: Service, S: Service<Request>,
S::Future: 'static, S::Future: 'static,
{ {
type Request = S::Request;
type Response = S::Response; type Response = S::Response;
type Error = S::Error; type Error = S::Error;
type InitError = (); type InitError = ();
@ -47,21 +47,20 @@ where
} }
} }
impl<S> Service for TracingMiddleware<S> impl<S, Request> Service<Request> for TracingMiddleware<S>
where where
S: Service, S: Service<Request>,
S::Future: 'static, S::Future: 'static,
{ {
type Request = S::Request;
type Response = S::Response; type Response = S::Response;
type Error = S::Error; type Error = S::Error;
type Future = Instrumented<S::Future>; type Future = Instrumented<S::Future>;
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { fn poll_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
self.inner.poll_ready(cx) self.inner.poll_ready(cx)
} }
fn call(&mut self, req: S::Request) -> Self::Future { fn call(&self, req: Request) -> Self::Future {
let uuid = Uuid::new_v4(); let uuid = Uuid::new_v4();
self.inner self.inner
@ -70,12 +69,11 @@ where
} }
} }
impl<S> Transform<S> for Internal impl<S> Transform<S, ServiceRequest> for Internal
where where
S: Service<Request = ServiceRequest, Error = actix_web::Error>, S: Service<ServiceRequest, Error = actix_web::Error>,
S::Future: 'static, S::Future: 'static,
{ {
type Request = S::Request;
type Response = S::Response; type Response = S::Response;
type Error = S::Error; type Error = S::Error;
type InitError = (); type InitError = ();
@ -87,21 +85,20 @@ where
} }
} }
impl<S> Service for InternalMiddleware<S> impl<S> Service<ServiceRequest> for InternalMiddleware<S>
where where
S: Service<Request = ServiceRequest, Error = actix_web::Error>, S: Service<ServiceRequest, Error = actix_web::Error>,
S::Future: 'static, S::Future: 'static,
{ {
type Request = S::Request;
type Response = S::Response; type Response = S::Response;
type Error = S::Error; type Error = S::Error;
type Future = LocalBoxFuture<'static, Result<S::Response, S::Error>>; type Future = LocalBoxFuture<'static, Result<S::Response, S::Error>>;
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { fn poll_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
self.1.poll_ready(cx) self.1.poll_ready(cx)
} }
fn call(&mut self, req: S::Request) -> Self::Future { fn call(&self, req: ServiceRequest) -> Self::Future {
if let Some(value) = req.headers().get("x-api-token") { if let Some(value) = req.headers().get("x-api-token") {
if value.to_str().is_ok() && value.to_str().ok() == self.0.as_deref() { if value.to_str().is_ok() && value.to_str().ok() == self.0.as_deref() {
let fut = self.1.call(req); let fut = self.1.call(req);

View file

@ -4,7 +4,6 @@ use crate::{
validate::{ptos, Op}, validate::{ptos, Op},
}; };
use actix_web::web; use actix_web::web;
use bytes::Bytes;
use magick_rust::MagickWand; use magick_rust::MagickWand;
use std::path::PathBuf; use std::path::PathBuf;
use tracing::{debug, error, instrument, Span}; use tracing::{debug, error, instrument, Span};
@ -372,7 +371,7 @@ pub(crate) async fn prepare_image(
transcode(orig_path, tmpfile, Target::Jpeg).map_err(UploadError::Transcode) transcode(orig_path, tmpfile, Target::Jpeg).map_err(UploadError::Transcode)
}) })
.await; .await?;
if let Err(e) = res { if let Err(e) = res {
error!("transcode error: {:?}", e); error!("transcode error: {:?}", e);
@ -395,7 +394,7 @@ pub(crate) async fn process_image(
original_file: PathBuf, original_file: PathBuf,
chain: ProcessChain, chain: ProcessChain,
format: Format, format: Format,
) -> Result<Bytes, UploadError> { ) -> Result<web::Bytes, UploadError> {
let original_path_str = ptos(&original_file)?; let original_path_str = ptos(&original_file)?;
let span = Span::current(); let span = Span::current();
@ -414,9 +413,9 @@ pub(crate) async fn process_image(
let vec = wand.op(|w| w.write_image_blob(format.to_magick_format()))?; let vec = wand.op(|w| w.write_image_blob(format.to_magick_format()))?;
drop(entered); drop(entered);
Ok(Bytes::from(vec)) as Result<Bytes, UploadError> Ok(web::Bytes::from(vec)) as Result<web::Bytes, UploadError>
}) })
.await?; .await??;
Ok(bytes) Ok(bytes)
} }

View file

@ -44,7 +44,7 @@ impl std::fmt::Debug for UploadManager {
} }
} }
type UploadStream<E> = Pin<Box<dyn Stream<Item = Result<bytes::Bytes, E>>>>; type UploadStream<E> = Pin<Box<dyn Stream<Item = Result<web::Bytes, E>>>>;
#[derive(Clone)] #[derive(Clone)]
pub(crate) struct Serde<T> { pub(crate) struct Serde<T> {
@ -134,7 +134,7 @@ impl Details {
}) })
}) })
}) })
.await?; .await??;
Ok(Details::now(width as usize, height as usize, mime_type)) Ok(Details::now(width as usize, height as usize, mime_type))
} }
@ -213,7 +213,7 @@ impl UploadManager {
) -> Result<Self, UploadError> { ) -> Result<Self, UploadError> {
let root_clone = root_dir.clone(); let root_clone = root_dir.clone();
// sled automatically creates it's own directories // sled automatically creates it's own directories
let db = web::block(move || LatestDb::exists(root_clone).migrate()).await?; let db = web::block(move || LatestDb::exists(root_clone).migrate()).await??;
root_dir.push("files"); root_dir.push("files");
@ -245,13 +245,13 @@ impl UploadManager {
let fname_tree = self.inner.filename_tree.clone(); let fname_tree = self.inner.filename_tree.clone();
debug!("Getting hash"); debug!("Getting hash");
let hash: sled::IVec = web::block(move || fname_tree.get(filename.as_bytes())) let hash: sled::IVec = web::block(move || fname_tree.get(filename.as_bytes()))
.await? .await??
.ok_or(UploadError::MissingFilename)?; .ok_or(UploadError::MissingFilename)?;
let key = variant_key(&hash, &path_string); let key = variant_key(&hash, &path_string);
let main_tree = self.inner.main_tree.clone(); let main_tree = self.inner.main_tree.clone();
debug!("Storing variant"); debug!("Storing variant");
web::block(move || main_tree.insert(key, path_string.as_bytes())).await?; web::block(move || main_tree.insert(key, path_string.as_bytes())).await??;
debug!("Stored variant"); debug!("Stored variant");
Ok(()) Ok(())
@ -268,13 +268,13 @@ impl UploadManager {
let fname_tree = self.inner.filename_tree.clone(); let fname_tree = self.inner.filename_tree.clone();
debug!("Getting hash"); debug!("Getting hash");
let hash: sled::IVec = web::block(move || fname_tree.get(filename.as_bytes())) let hash: sled::IVec = web::block(move || fname_tree.get(filename.as_bytes()))
.await? .await??
.ok_or(UploadError::MissingFilename)?; .ok_or(UploadError::MissingFilename)?;
let key = variant_details_key(&hash, &path_string); let key = variant_details_key(&hash, &path_string);
let main_tree = self.inner.main_tree.clone(); let main_tree = self.inner.main_tree.clone();
debug!("Getting details"); debug!("Getting details");
let opt = match web::block(move || main_tree.get(key)).await? { let opt = match web::block(move || main_tree.get(key)).await?? {
Some(ivec) => match serde_json::from_slice(&ivec) { Some(ivec) => match serde_json::from_slice(&ivec) {
Ok(details) => Some(details), Ok(details) => Some(details),
Err(_) => None, Err(_) => None,
@ -297,14 +297,14 @@ impl UploadManager {
let fname_tree = self.inner.filename_tree.clone(); let fname_tree = self.inner.filename_tree.clone();
debug!("Getting hash"); debug!("Getting hash");
let hash: sled::IVec = web::block(move || fname_tree.get(filename.as_bytes())) let hash: sled::IVec = web::block(move || fname_tree.get(filename.as_bytes()))
.await? .await??
.ok_or(UploadError::MissingFilename)?; .ok_or(UploadError::MissingFilename)?;
let key = variant_details_key(&hash, &path_string); let key = variant_details_key(&hash, &path_string);
let main_tree = self.inner.main_tree.clone(); let main_tree = self.inner.main_tree.clone();
let details_value = serde_json::to_string(details)?; let details_value = serde_json::to_string(details)?;
debug!("Storing details"); debug!("Storing details");
web::block(move || main_tree.insert(key, details_value.as_bytes())).await?; web::block(move || main_tree.insert(key, details_value.as_bytes())).await??;
debug!("Stored details"); debug!("Stored details");
Ok(()) Ok(())
@ -317,7 +317,7 @@ impl UploadManager {
) -> Result<Vec<String>, UploadError> { ) -> Result<Vec<String>, UploadError> {
let fname_tree = self.inner.filename_tree.clone(); let fname_tree = self.inner.filename_tree.clone();
let hash = web::block(move || fname_tree.get(filename.as_bytes())) let hash = web::block(move || fname_tree.get(filename.as_bytes()))
.await? .await??
.ok_or(UploadError::MissingAlias)?; .ok_or(UploadError::MissingAlias)?;
self.aliases_by_hash(&hash).await self.aliases_by_hash(&hash).await
@ -327,7 +327,7 @@ impl UploadManager {
pub(crate) async fn aliases_by_alias(&self, alias: String) -> Result<Vec<String>, UploadError> { pub(crate) async fn aliases_by_alias(&self, alias: String) -> Result<Vec<String>, UploadError> {
let alias_tree = self.inner.alias_tree.clone(); let alias_tree = self.inner.alias_tree.clone();
let hash = web::block(move || alias_tree.get(alias.as_bytes())) let hash = web::block(move || alias_tree.get(alias.as_bytes()))
.await? .await??
.ok_or(UploadError::MissingFilename)?; .ok_or(UploadError::MissingFilename)?;
self.aliases_by_hash(&hash).await self.aliases_by_hash(&hash).await
@ -342,7 +342,7 @@ impl UploadManager {
.values() .values()
.collect::<Result<Vec<_>, _>>() .collect::<Result<Vec<_>, _>>()
}) })
.await?; .await??;
debug!("Got {} aliases for hash", aliases.len()); debug!("Got {} aliases for hash", aliases.len());
let aliases = aliases let aliases = aliases
@ -362,7 +362,7 @@ impl UploadManager {
let token_key = delete_key(&alias); let token_key = delete_key(&alias);
let alias_tree = self.inner.alias_tree.clone(); let alias_tree = self.inner.alias_tree.clone();
let token = web::block(move || alias_tree.get(token_key.as_bytes())) let token = web::block(move || alias_tree.get(token_key.as_bytes()))
.await? .await??
.ok_or(UploadError::MissingAlias)?; .ok_or(UploadError::MissingAlias)?;
self.delete(alias, String::from_utf8(token.to_vec())?).await self.delete(alias, String::from_utf8(token.to_vec())?).await
@ -415,7 +415,7 @@ impl UploadManager {
Ok(hash) Ok(hash)
}) })
}) })
.await?; .await??;
// -- CHECK IF ANY OTHER ALIASES EXIST -- // -- CHECK IF ANY OTHER ALIASES EXIST --
let main_tree = self.inner.main_tree.clone(); let main_tree = self.inner.main_tree.clone();
@ -424,7 +424,7 @@ impl UploadManager {
let any_aliases = web::block(move || { let any_aliases = web::block(move || {
Ok(main_tree.range(start..end).next().is_some()) as Result<bool, UploadError> Ok(main_tree.range(start..end).next().is_some()) as Result<bool, UploadError>
}) })
.await?; .await??;
// Bail if there are existing aliases // Bail if there are existing aliases
if any_aliases { if any_aliases {
@ -437,7 +437,7 @@ impl UploadManager {
let hash2 = hash.clone(); let hash2 = hash.clone();
debug!("Deleting hash -> filename mapping"); debug!("Deleting hash -> filename mapping");
let filename = web::block(move || main_tree.remove(&hash2)) let filename = web::block(move || main_tree.remove(&hash2))
.await? .await??
.ok_or(UploadError::MissingFile)?; .ok_or(UploadError::MissingFile)?;
// -- DELETE FILES -- // -- DELETE FILES --
@ -468,7 +468,11 @@ impl UploadManager {
debug!("Generating delete token"); debug!("Generating delete token");
use rand::distributions::{Alphanumeric, Distribution}; use rand::distributions::{Alphanumeric, Distribution};
let rng = rand::thread_rng(); let rng = rand::thread_rng();
let s: String = Alphanumeric.sample_iter(rng).take(10).collect(); let s: String = Alphanumeric
.sample_iter(rng)
.take(10)
.map(char::from)
.collect();
let delete_token = s.clone(); let delete_token = s.clone();
debug!("Saving delete token"); debug!("Saving delete token");
@ -481,7 +485,7 @@ impl UploadManager {
Some(s.as_bytes()), Some(s.as_bytes()),
) )
}) })
.await?; .await??;
if let Err(sled::CompareAndSwapError { if let Err(sled::CompareAndSwapError {
current: Some(ivec), current: Some(ivec),
@ -579,13 +583,13 @@ impl UploadManager {
let tree = self.inner.alias_tree.clone(); let tree = self.inner.alias_tree.clone();
debug!("Getting hash from alias"); debug!("Getting hash from alias");
let hash = web::block(move || tree.get(alias.as_bytes())) let hash = web::block(move || tree.get(alias.as_bytes()))
.await? .await??
.ok_or(UploadError::MissingAlias)?; .ok_or(UploadError::MissingAlias)?;
let main_tree = self.inner.main_tree.clone(); let main_tree = self.inner.main_tree.clone();
debug!("Getting filename from hash"); debug!("Getting filename from hash");
let filename = web::block(move || main_tree.get(hash)) let filename = web::block(move || main_tree.get(hash))
.await? .await??
.ok_or(UploadError::MissingFile)?; .ok_or(UploadError::MissingFile)?;
let filename = String::from_utf8(filename.to_vec())?; let filename = String::from_utf8(filename.to_vec())?;
@ -610,7 +614,7 @@ impl UploadManager {
let fname_tree = self.inner.filename_tree.clone(); let fname_tree = self.inner.filename_tree.clone();
debug!("Deleting filename -> hash mapping"); debug!("Deleting filename -> hash mapping");
let hash = web::block(move || fname_tree.remove(filename)) let hash = web::block(move || fname_tree.remove(filename))
.await? .await??
.ok_or(UploadError::MissingFile)?; .ok_or(UploadError::MissingFile)?;
let (start, end) = variant_key_bounds(&hash); let (start, end) = variant_key_bounds(&hash);
@ -624,13 +628,13 @@ impl UploadManager {
Ok(keys) as Result<Vec<sled::IVec>, UploadError> Ok(keys) as Result<Vec<sled::IVec>, UploadError>
}) })
.await?; .await??;
debug!("{} files prepared for deletion", keys.len()); debug!("{} files prepared for deletion", keys.len());
for key in keys { for key in keys {
let main_tree = self.inner.main_tree.clone(); let main_tree = self.inner.main_tree.clone();
if let Some(path) = web::block(move || main_tree.remove(key)).await? { if let Some(path) = web::block(move || main_tree.remove(key)).await?? {
let s = String::from_utf8_lossy(&path); let s = String::from_utf8_lossy(&path);
debug!("Deleting {}", s); debug!("Deleting {}", s);
// ignore json objects // ignore json objects
@ -685,12 +689,12 @@ impl UploadManager {
hasher.update(&bytes); hasher.update(&bytes);
Ok(hasher) as Result<_, UploadError> Ok(hasher) as Result<_, UploadError>
}) })
.await?; .await??;
} }
let hash = let hash =
web::block(move || Ok(hasher.finalize_reset().to_vec()) as Result<_, UploadError>) web::block(move || Ok(hasher.finalize_reset().to_vec()) as Result<_, UploadError>)
.await?; .await??;
Ok(Hash::new(hash)) Ok(Hash::new(hash))
} }
@ -715,7 +719,7 @@ impl UploadManager {
Some(filename2.as_bytes()), Some(filename2.as_bytes()),
) )
}) })
.await?; .await??;
if let Err(sled::CompareAndSwapError { if let Err(sled::CompareAndSwapError {
current: Some(ivec), current: Some(ivec),
@ -730,7 +734,7 @@ impl UploadManager {
let fname_tree = self.inner.filename_tree.clone(); let fname_tree = self.inner.filename_tree.clone();
let filename2 = filename.clone(); let filename2 = filename.clone();
debug!("Saving filename -> hash relation"); debug!("Saving filename -> hash relation");
web::block(move || fname_tree.insert(filename2, hash.inner)).await?; web::block(move || fname_tree.insert(filename2, hash.inner)).await??;
Ok((Dup::New, filename)) Ok((Dup::New, filename))
} }
@ -741,11 +745,15 @@ impl UploadManager {
let image_dir = self.image_dir(); let image_dir = self.image_dir();
use rand::distributions::{Alphanumeric, Distribution}; use rand::distributions::{Alphanumeric, Distribution};
let mut limit: usize = 10; let mut limit: usize = 10;
let rng = rand::thread_rng(); let mut rng = rand::thread_rng();
loop { loop {
debug!("Filename generation loop"); debug!("Filename generation loop");
let mut path = image_dir.clone(); let mut path = image_dir.clone();
let s: String = Alphanumeric.sample_iter(rng).take(limit).collect(); let s: String = Alphanumeric
.sample_iter(&mut rng)
.take(limit)
.map(char::from)
.collect();
let filename = file_name(s, content_type.clone())?; let filename = file_name(s, content_type.clone())?;
@ -799,7 +807,7 @@ impl UploadManager {
loop { loop {
debug!("hash -> alias save loop"); debug!("hash -> alias save loop");
let db = self.inner.db.clone(); let db = self.inner.db.clone();
let id = web::block(move || db.generate_id()).await?.to_string(); let id = web::block(move || db.generate_id()).await??.to_string();
let key = alias_key(&hash.inner, &id); let key = alias_key(&hash.inner, &id);
let main_tree = self.inner.main_tree.clone(); let main_tree = self.inner.main_tree.clone();
@ -808,13 +816,13 @@ impl UploadManager {
let res = web::block(move || { let res = web::block(move || {
main_tree.compare_and_swap(key, None as Option<sled::IVec>, Some(alias2.as_bytes())) main_tree.compare_and_swap(key, None as Option<sled::IVec>, Some(alias2.as_bytes()))
}) })
.await?; .await??;
if res.is_ok() { if res.is_ok() {
let alias_tree = self.inner.alias_tree.clone(); let alias_tree = self.inner.alias_tree.clone();
let key = alias_id_key(&alias); let key = alias_id_key(&alias);
debug!("Saving alias -> id mapping"); debug!("Saving alias -> id mapping");
web::block(move || alias_tree.insert(key.as_bytes(), id.as_bytes())).await?; web::block(move || alias_tree.insert(key.as_bytes(), id.as_bytes())).await??;
break; break;
} }
@ -834,10 +842,14 @@ impl UploadManager {
) -> Result<String, UploadError> { ) -> Result<String, UploadError> {
use rand::distributions::{Alphanumeric, Distribution}; use rand::distributions::{Alphanumeric, Distribution};
let mut limit: usize = 10; let mut limit: usize = 10;
let rng = rand::thread_rng(); let mut rng = rand::thread_rng();
loop { loop {
debug!("Alias gen loop"); debug!("Alias gen loop");
let s: String = Alphanumeric.sample_iter(rng).take(limit).collect(); let s: String = Alphanumeric
.sample_iter(&mut rng)
.take(limit)
.map(char::from)
.collect();
let alias = file_name(s, content_type.clone())?; let alias = file_name(s, content_type.clone())?;
let res = self.save_alias(hash, &alias).await?; let res = self.save_alias(hash, &alias).await?;
@ -866,7 +878,7 @@ impl UploadManager {
let res = web::block(move || { let res = web::block(move || {
tree.compare_and_swap(alias.as_bytes(), None as Option<sled::IVec>, Some(vec)) tree.compare_and_swap(alias.as_bytes(), None as Option<sled::IVec>, Some(vec))
}) })
.await?; .await??;
if res.is_err() { if res.is_err() {
warn!("Duplicate alias"); warn!("Duplicate alias");

View file

@ -199,7 +199,7 @@ pub(crate) async fn validate_image(
drop(entered); drop(entered);
Ok(content_type) as Result<mime::Mime, UploadError> Ok(content_type) as Result<mime::Mime, UploadError>
}) })
.await?; .await??;
Ok(content_type) Ok(content_type)
} }