66 lines
1.8 KiB
Rust
66 lines
1.8 KiB
Rust
use axum::{
|
|
extract::{Form, Path, State},
|
|
http::HeaderMap,
|
|
http::StatusCode,
|
|
response::{Html, IntoResponse, Response},
|
|
};
|
|
|
|
use std::{path::PathBuf, sync::Arc};
|
|
use tokio::fs;
|
|
use uuid::Uuid;
|
|
|
|
#[derive(Clone)]
|
|
pub struct AppState {
|
|
pub paste_dir: Arc<PathBuf>,
|
|
}
|
|
|
|
#[derive(serde::Deserialize)]
|
|
pub struct PasteForm {
|
|
body: String,
|
|
}
|
|
|
|
pub async fn index() -> Html<&'static str> {
|
|
Html(include_str!("../templates/index.html"))
|
|
}
|
|
|
|
pub async fn create_paste(
|
|
State(state): State<AppState>,
|
|
headers: HeaderMap,
|
|
Form(form): Form<PasteForm>,
|
|
) -> Response {
|
|
let ip = headers
|
|
.get("x-real-ip")
|
|
.and_then(|v| v.to_str().ok())
|
|
.unwrap_or("unknown");
|
|
let id = Uuid::new_v4().to_string()[..8].to_string();
|
|
let path = state.paste_dir.join(&id);
|
|
fs::write(&path, &form.body).await.unwrap();
|
|
tracing::info!(
|
|
"paste created: id={} size={} bytes ip={}",
|
|
id,
|
|
&form.body.len(),
|
|
ip
|
|
);
|
|
(StatusCode::SEE_OTHER, [("location", format!("/{id}"))]).into_response()
|
|
}
|
|
pub async fn get_paste(State(state): State<AppState>, Path(id): Path<String>) -> Response {
|
|
let path = state.paste_dir.join(&id);
|
|
match fs::read_to_string(&path).await {
|
|
Ok(content) => Html(format!(
|
|
include_str!("../templates/paste.html"),
|
|
id = id,
|
|
content = content
|
|
))
|
|
.into_response(),
|
|
Err(_) => (StatusCode::NOT_FOUND, "paste not found").into_response(),
|
|
}
|
|
}
|
|
|
|
pub async fn get_paste_raw(State(state): State<AppState>, Path(id): Path<String>) -> Response {
|
|
let path = state.paste_dir.join(&id);
|
|
match fs::read_to_string(&path).await {
|
|
Ok(content) => ([("content-type", "text/plain; charset=utf-8")], content).into_response(),
|
|
Err(_) => (StatusCode::NOT_FOUND, "paste not found").into_response(),
|
|
}
|
|
}
|