about summary refs log tree commit diff
path: root/src/media/mod.rs
diff options
context:
space:
mode:
authorVika <vika@fireburn.ru>2025-04-09 23:31:02 +0300
committerVika <vika@fireburn.ru>2025-04-09 23:31:57 +0300
commit8826d9446e6c492db2243b9921e59ce496027bef (patch)
tree63738aa9001cb73b11cb0e974e93129bcdf1adbb /src/media/mod.rs
parent519cadfbb298f50cbf819dde757037ab56e2863e (diff)
downloadkittybox-8826d9446e6c492db2243b9921e59ce496027bef.tar.zst
cargo fmt
Change-Id: I80e81ebba3f0cdf8c094451c9fe3ee4126b8c888
Diffstat (limited to 'src/media/mod.rs')
-rw-r--r--src/media/mod.rs83
1 files changed, 47 insertions, 36 deletions
diff --git a/src/media/mod.rs b/src/media/mod.rs
index 6f263b6..7e52414 100644
--- a/src/media/mod.rs
+++ b/src/media/mod.rs
@@ -1,22 +1,23 @@
+use crate::indieauth::{backend::AuthBackend, User};
 use axum::{
-    extract::{multipart::Multipart, FromRef, Path, State}, response::{IntoResponse, Response}
+    extract::{multipart::Multipart, FromRef, Path, State},
+    response::{IntoResponse, Response},
 };
-use axum_extra::headers::{ContentLength, HeaderMapExt, HeaderValue, IfNoneMatch};
 use axum_extra::extract::Host;
+use axum_extra::headers::{ContentLength, HeaderMapExt, HeaderValue, IfNoneMatch};
 use axum_extra::TypedHeader;
-use kittybox_util::micropub::{Error as MicropubError, ErrorKind as ErrorType};
 use kittybox_indieauth::Scope;
-use crate::indieauth::{backend::AuthBackend, User};
+use kittybox_util::micropub::{Error as MicropubError, ErrorKind as ErrorType};
 
 pub mod storage;
-use storage::{MediaStore, MediaStoreError, Metadata, ErrorKind};
 pub use storage::file::FileStore;
+use storage::{ErrorKind, MediaStore, MediaStoreError, Metadata};
 
 impl From<MediaStoreError> for MicropubError {
     fn from(err: MediaStoreError) -> Self {
         Self::new(
             ErrorType::InternalServerError,
-            format!("media store error: {}", err)
+            format!("media store error: {}", err),
         )
     }
 }
@@ -25,13 +26,14 @@ impl From<MediaStoreError> for MicropubError {
 pub(crate) async fn upload<S: MediaStore, A: AuthBackend>(
     State(blobstore): State<S>,
     user: User<A>,
-    mut upload: Multipart
+    mut upload: Multipart,
 ) -> Response {
     if !user.check_scope(&Scope::Media) {
         return MicropubError::from_static(
             ErrorType::NotAuthorized,
-            "Interacting with the media storage requires the \"media\" scope."
-        ).into_response();
+            "Interacting with the media storage requires the \"media\" scope.",
+        )
+        .into_response();
     }
     let host = user.me.authority();
     let field = match upload.next_field().await {
@@ -39,27 +41,31 @@ pub(crate) async fn upload<S: MediaStore, A: AuthBackend>(
         Ok(None) => {
             return MicropubError::from_static(
                 ErrorType::InvalidRequest,
-                "Send multipart/form-data with one field named file"
-            ).into_response();
-        },
+                "Send multipart/form-data with one field named file",
+            )
+            .into_response();
+        }
         Err(err) => {
             return MicropubError::new(
                 ErrorType::InternalServerError,
-                format!("Error while parsing multipart/form-data: {}", err)
-            ).into_response();
-        },
+                format!("Error while parsing multipart/form-data: {}", err),
+            )
+            .into_response();
+        }
     };
     let metadata: Metadata = (&field).into();
     match blobstore.write_streaming(host, metadata, field).await {
         Ok(filename) => IntoResponse::into_response((
             axum::http::StatusCode::CREATED,
-            [
-                ("Location", user.me.join(
-                    &format!(".kittybox/media/uploads/{}", filename)
-                ).unwrap().as_str())
-            ]
+            [(
+                "Location",
+                user.me
+                    .join(&format!(".kittybox/media/uploads/{}", filename))
+                    .unwrap()
+                    .as_str(),
+            )],
         )),
-        Err(err) => MicropubError::from(err).into_response()
+        Err(err) => MicropubError::from(err).into_response(),
     }
 }
 
@@ -68,7 +74,7 @@ pub(crate) async fn serve<S: MediaStore>(
     Host(host): Host,
     Path(path): Path<String>,
     if_none_match: Option<TypedHeader<IfNoneMatch>>,
-    State(blobstore): State<S>
+    State(blobstore): State<S>,
 ) -> Response {
     use axum::http::StatusCode;
     tracing::debug!("Searching for file...");
@@ -77,7 +83,9 @@ pub(crate) async fn serve<S: MediaStore>(
             tracing::debug!("Metadata: {:?}", metadata);
 
             let etag = if let Some(etag) = metadata.etag {
-                let etag = format!("\"{}\"", etag).parse::<axum_extra::headers::ETag>().unwrap();
+                let etag = format!("\"{}\"", etag)
+                    .parse::<axum_extra::headers::ETag>()
+                    .unwrap();
 
                 if let Some(TypedHeader(if_none_match)) = if_none_match {
                     tracing::debug!("If-None-Match: {:?}", if_none_match);
@@ -85,12 +93,14 @@ pub(crate) async fn serve<S: MediaStore>(
                     // returns 304 when it doesn't match because it
                     // only matches when file is different
                     if !if_none_match.precondition_passes(&etag) {
-                        return StatusCode::NOT_MODIFIED.into_response()
+                        return StatusCode::NOT_MODIFIED.into_response();
                     }
                 }
 
                 Some(etag)
-            } else { None };
+            } else {
+                None
+            };
 
             let mut r = Response::builder();
             {
@@ -98,14 +108,16 @@ pub(crate) async fn serve<S: MediaStore>(
                 headers.insert(
                     "Content-Type",
                     HeaderValue::from_str(
-                        metadata.content_type
+                        metadata
+                            .content_type
                             .as_deref()
-                            .unwrap_or("application/octet-stream")
-                    ).unwrap()
+                            .unwrap_or("application/octet-stream"),
+                    )
+                    .unwrap(),
                 );
                 headers.insert(
                     axum::http::header::X_CONTENT_TYPE_OPTIONS,
-                    axum::http::HeaderValue::from_static("nosniff")
+                    axum::http::HeaderValue::from_static("nosniff"),
                 );
                 if let Some(length) = metadata.length {
                     headers.typed_insert(ContentLength(length.get().try_into().unwrap()));
@@ -117,23 +129,22 @@ pub(crate) async fn serve<S: MediaStore>(
             r.body(axum::body::Body::from_stream(stream))
                 .unwrap()
                 .into_response()
-        },
+        }
         Err(err) => match err.kind() {
-            ErrorKind::NotFound => {
-                IntoResponse::into_response(StatusCode::NOT_FOUND)
-            },
+            ErrorKind::NotFound => IntoResponse::into_response(StatusCode::NOT_FOUND),
             _ => {
                 tracing::error!("{}", err);
                 IntoResponse::into_response(StatusCode::INTERNAL_SERVER_ERROR)
             }
-        }
+        },
     }
 }
 
-pub fn router<St, A, M>() -> axum::Router<St> where
+pub fn router<St, A, M>() -> axum::Router<St>
+where
     A: AuthBackend + FromRef<St>,
     M: MediaStore + FromRef<St>,
-    St: Clone + Send + Sync + 'static
+    St: Clone + Send + Sync + 'static,
 {
     axum::Router::new()
         .route("/", axum::routing::post(upload::<M, A>))