summaryrefslogtreecommitdiff
path: root/src/types/extract.rs
diff options
context:
space:
mode:
authorTyler Murphy <tylermurphy534@gmail.com>2023-01-31 22:21:19 -0500
committerTyler Murphy <tylermurphy534@gmail.com>2023-01-31 22:21:19 -0500
commitd9125314809e7f03cb155f91d535e94da583a365 (patch)
treef34bc2e978d5e79f0dc62aa7a5faa8f096b46dc5 /src/types/extract.rs
parentfix admin (diff)
downloadxssbook-d9125314809e7f03cb155f91d535e94da583a365.tar.gz
xssbook-d9125314809e7f03cb155f91d535e94da583a365.tar.bz2
xssbook-d9125314809e7f03cb155f91d535e94da583a365.zip
custosm avatars and banners
Diffstat (limited to 'src/types/extract.rs')
-rw-r--r--src/types/extract.rs74
1 files changed, 70 insertions, 4 deletions
diff --git a/src/types/extract.rs b/src/types/extract.rs
index 50c413b..54f250a 100644
--- a/src/types/extract.rs
+++ b/src/types/extract.rs
@@ -1,4 +1,4 @@
-use std::io::Read;
+use std::io::{Read, Cursor};
use axum::{
async_trait,
@@ -10,6 +10,7 @@ use axum::{
};
use axum_client_ip::ClientIp;
use bytes::Bytes;
+use image::{io::Reader, ImageFormat, DynamicImage};
use serde::de::DeserializeOwned;
use tower_cookies::Cookies;
@@ -99,6 +100,36 @@ where
}
}
+pub struct Png(pub DynamicImage);
+
+#[async_trait]
+impl<S, B> FromRequest<S, B> for Png
+where
+ B: HttpBody + Sync + Send + 'static,
+ B::Data: Send,
+ B::Error: Into<BoxError>,
+ S: Send + Sync,
+{
+ type Rejection = Response;
+
+ async fn from_request(req: Request<B>, state: &S) -> Result<Self> {
+
+ let bytes = match read_body(req, state).await {
+ Ok(body) => body,
+ Err(err) => return Err(err),
+ };
+
+ let mut reader = Reader::new(Cursor::new(bytes));
+ reader.set_format(ImageFormat::Png);
+
+ let Ok(img) = reader.decode() else {
+ return Err(ResponseCode::BadRequest.text("Failed to decode png image"))
+ };
+
+ Ok(Self(img))
+ }
+}
+
pub struct Json<T>(pub T);
#[async_trait]
@@ -150,7 +181,43 @@ pub trait Check {
}
}
-pub async fn parse_body<S, B>(mut req: Request<B>, state: &S) -> Result<String>
+async fn read_body<S, B>(mut req: Request<B>, state: &S) -> Result<Vec<u8>>
+where
+ B: HttpBody + Sync + Send + 'static,
+ B::Data: Send,
+ B::Error: Into<BoxError>,
+ S: Send + Sync,
+{
+
+ let Ok(ClientIp(ip)) = req.extract_parts::<ClientIp>().await else {
+ tracing::error!("Failed to read client ip");
+ return Err(ResponseCode::InternalServerError.text("Failed to read client ip"));
+ };
+
+ let method = req.method().clone();
+ let uri = req.uri().clone();
+ let path = req
+ .extensions()
+ .get::<RouterURI>()
+ .map_or("", |path| path.0);
+
+ let Ok(bytes) = Bytes::from_request(req, state).await else {
+ return Err(ResponseCode::BadRequest.text("Request can be at most 512kb"));
+ };
+
+ console::log(
+ ip,
+ method,
+ uri,
+ Some(path.to_string()),
+ None,
+ )
+ .await;
+
+ Ok(bytes.bytes().flatten().collect())
+}
+
+async fn parse_body<S, B>(mut req: Request<B>, state: &S) -> Result<String>
where
B: HttpBody + Sync + Send + 'static,
B::Data: Send,
@@ -170,8 +237,7 @@ where
.map_or("", |path| path.0);
let Ok(bytes) = Bytes::from_request(req, state).await else {
- tracing::error!("Failed to read request body");
- return Err(ResponseCode::InternalServerError.text("Failed to read request body"));
+ return Err(ResponseCode::BadRequest.text("Request can be at most 512kb"));
};
let Ok(body) = String::from_utf8(bytes.bytes().flatten().collect()) else {