jmserver/src/cdn/mod.rs

79 lines
2 KiB
Rust
Raw Normal View History

2021-12-29 18:33:31 +01:00
use axum::{
body::Body,
extract::{Extension, Path},
handler::get,
http::HeaderMap,
response::IntoResponse,
routing::BoxRoute,
Router,
};
2021-12-18 20:04:34 +01:00
use headers::{ContentType, HeaderMapExt};
2021-12-29 18:33:31 +01:00
use reqwest::{
header::{HeaderName, CONTENT_LENGTH},
StatusCode,
};
2021-12-18 20:04:34 +01:00
2022-01-16 22:43:45 +01:00
use crate::JMService;
2021-12-18 20:04:34 +01:00
2021-12-29 18:33:31 +01:00
use self::{
2022-01-05 23:46:19 +01:00
error::CDNError,
2021-12-29 18:33:31 +01:00
templates::{DirTemplate, HtmlTemplate},
};
2021-12-18 21:15:06 +01:00
2021-12-29 18:33:31 +01:00
mod error;
2021-12-18 20:04:34 +01:00
mod sql;
2021-12-18 21:15:06 +01:00
mod templates;
2021-12-18 20:04:34 +01:00
pub fn routes() -> Router<BoxRoute> {
Router::new()
2021-12-29 18:33:31 +01:00
.route("/", get(users))
.route("/:user/", get(memes))
.route("/:user/:filename", get(image))
.boxed()
2021-12-18 20:04:34 +01:00
}
2021-12-29 18:33:31 +01:00
async fn image(
Path((user, filename)): Path<(String, String)>,
2022-01-16 22:43:45 +01:00
Extension(service): Extension<JMService>,
2022-01-05 23:46:19 +01:00
) -> Result<impl IntoResponse, CDNError> {
2021-12-29 18:33:31 +01:00
let filename = urlencoding::decode(&filename)?.into_owned();
2022-07-19 21:11:13 +02:00
let cid = sql::get_cid(user, filename.clone(), &service.db_pool).await?;
let res = service.ipfs_cat(cid).await?;
2021-12-29 18:33:31 +01:00
let clength = res
.headers()
2022-01-05 23:46:19 +01:00
.get(HeaderName::from_static("x-content-length"))
.ok_or(CDNError::Internal)?;
2021-12-29 18:33:31 +01:00
2022-01-05 23:46:19 +01:00
let mut headers = HeaderMap::new();
let ctype = ContentType::from(new_mime_guess::from_path(filename).first_or_octet_stream());
headers.typed_insert(ctype);
headers.insert(CONTENT_LENGTH, clength.clone());
Ok((
StatusCode::OK,
headers,
Body::wrap_stream(res.bytes_stream()),
))
2021-12-18 21:15:06 +01:00
}
2022-07-19 21:11:13 +02:00
async fn users(Extension(service): Extension<JMService>) -> Result<impl IntoResponse, CDNError> {
let users = sql::get_users(&service.db_pool).await?;
2022-01-05 23:46:19 +01:00
Ok(HtmlTemplate(DirTemplate {
entries: users,
2022-01-16 22:43:45 +01:00
prefix: service.cdn_url(),
2022-01-05 23:46:19 +01:00
suffix: "/".to_string(),
}))
2021-12-18 21:15:06 +01:00
}
2021-12-29 18:33:31 +01:00
async fn memes(
Path(user): Path<String>,
2022-07-19 21:11:13 +02:00
Extension(service): Extension<JMService>,
2022-01-05 23:46:19 +01:00
) -> Result<impl IntoResponse, CDNError> {
2022-07-19 21:11:13 +02:00
let memes = sql::get_memes(user, &service.db_pool).await?;
2022-01-05 23:46:19 +01:00
Ok(HtmlTemplate(DirTemplate {
entries: memes,
prefix: ".".to_string(),
suffix: "".to_string(),
}))
2021-12-29 18:33:31 +01:00
}