Func
This commit is contained in:
21 files changed
+590
-70
No files matched your search
@@ -0,0 +1,80 @@
|
||||
use std::time::UNIX_EPOCH;
|
||||
|
||||
use axum::{
|
||||
Form,
|
||||
extract::{FromRequest, Request},
|
||||
http::{HeaderValue, StatusCode, Uri, header::CONTENT_TYPE},
|
||||
response::{IntoResponse, Response},
|
||||
};
|
||||
use serde::Deserialize;
|
||||
|
||||
#[derive(Default, Deserialize)]
|
||||
pub struct PasteInput {
|
||||
#[serde(alias = "href")]
|
||||
pub content: String,
|
||||
pub language: Option<String>,
|
||||
pub expires: Option<i64>,
|
||||
pub max_views: Option<i64>,
|
||||
}
|
||||
|
||||
impl PasteInput {
|
||||
pub fn validate_url(&mut self) -> Result<(), StatusCode> {
|
||||
self.content = self.content.trim().to_owned();
|
||||
let uri: Uri = self.content.parse().map_err(|_| StatusCode::BAD_REQUEST)?;
|
||||
if !matches!(uri.scheme_str(), Some("http" | "https"))
|
||||
|| uri.host().is_none()
|
||||
|| HeaderValue::from_str(&self.content).is_err()
|
||||
{
|
||||
return Err(StatusCode::BAD_REQUEST);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn expiration(&self) -> Result<Option<i64>, StatusCode> {
|
||||
self.expires
|
||||
.map(|expires| {
|
||||
let now = UNIX_EPOCH
|
||||
.elapsed()
|
||||
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?
|
||||
.as_secs() as i64;
|
||||
now.checked_add(expires).ok_or(StatusCode::BAD_REQUEST)
|
||||
})
|
||||
.transpose()
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Send + Sync> FromRequest<S> for PasteInput {
|
||||
type Rejection = Response;
|
||||
|
||||
async fn from_request(request: Request, state: &S) -> Result<Self, Self::Rejection> {
|
||||
let form = request
|
||||
.headers()
|
||||
.get(CONTENT_TYPE)
|
||||
.and_then(|value| value.to_str().ok())
|
||||
.and_then(|value| value.split(';').next())
|
||||
.is_some_and(|value| {
|
||||
value
|
||||
.trim()
|
||||
.eq_ignore_ascii_case("application/x-www-form-urlencoded")
|
||||
});
|
||||
let input = if form {
|
||||
Form::<Self>::from_request(request, state)
|
||||
.await
|
||||
.map_err(IntoResponse::into_response)?
|
||||
.0
|
||||
} else {
|
||||
Self {
|
||||
content: String::from_request(request, state)
|
||||
.await
|
||||
.map_err(IntoResponse::into_response)?,
|
||||
..Self::default()
|
||||
}
|
||||
};
|
||||
if input.expires.is_some_and(|expires| expires < 0)
|
||||
|| input.max_views.is_some_and(|max| max < 1)
|
||||
{
|
||||
return Err(StatusCode::BAD_REQUEST.into_response());
|
||||
}
|
||||
Ok(input)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user