82 lines
2.4 KiB
Rust
82 lines
2.4 KiB
Rust
use crate::models::{
|
|
now_sec, sanitize_filename, url_decode, AppState, IncomingTextPayload, MediaItem, TextItem,
|
|
MAX_RAM_TEXTS, MEDIA_DIR,
|
|
};
|
|
use axum::{
|
|
body::Bytes,
|
|
extract::State,
|
|
http::{header, HeaderMap, StatusCode},
|
|
Json,
|
|
};
|
|
use std::{path::PathBuf, sync::Arc};
|
|
|
|
/// Прием текста от другого устройства -> сохраняется СТРОГО В ОЗУ
|
|
pub async fn p2p_receive_text(
|
|
State(state): State<Arc<AppState>>,
|
|
Json(payload): Json<IncomingTextPayload>,
|
|
) -> StatusCode {
|
|
let mut ram_texts = state.ram_texts.write().unwrap();
|
|
if ram_texts.len() >= MAX_RAM_TEXTS {
|
|
ram_texts.pop_back();
|
|
}
|
|
ram_texts.push_front(TextItem {
|
|
sender: payload.sender,
|
|
text: payload.text,
|
|
timestamp: now_sec(),
|
|
});
|
|
StatusCode::OK
|
|
}
|
|
|
|
/// Прием медиаконтента от другого устройства -> сохраняется НА ДИСК
|
|
pub async fn p2p_receive_media(
|
|
State(state): State<Arc<AppState>>,
|
|
headers: HeaderMap,
|
|
body: Bytes,
|
|
) -> Result<StatusCode, (StatusCode, String)> {
|
|
let sender = headers
|
|
.get("X-Sender")
|
|
.and_then(|v| v.to_str().ok())
|
|
.map(url_decode)
|
|
.unwrap_or_else(|| "Unknown".to_string());
|
|
|
|
let raw_filename = headers
|
|
.get("X-Filename")
|
|
.and_then(|v| v.to_str().ok())
|
|
.unwrap_or("file.bin");
|
|
|
|
let mime = headers
|
|
.get(header::CONTENT_TYPE)
|
|
.and_then(|v| v.to_str().ok())
|
|
.unwrap_or("application/octet-stream")
|
|
.to_string();
|
|
|
|
tokio::fs::create_dir_all(MEDIA_DIR)
|
|
.await
|
|
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
|
|
|
|
let safe_name = sanitize_filename(raw_filename);
|
|
let final_filename = format!("{}_{}", now_sec(), safe_name);
|
|
let file_path = PathBuf::from(MEDIA_DIR).join(&final_filename);
|
|
|
|
tokio::fs::write(&file_path, &body)
|
|
.await
|
|
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
|
|
|
|
let abs_path = std::fs::canonicalize(&file_path)
|
|
.unwrap_or_else(|_| file_path.clone())
|
|
.display()
|
|
.to_string();
|
|
|
|
let mut media_list = state.disk_media.write().unwrap();
|
|
media_list.push_front(MediaItem {
|
|
sender,
|
|
filename: final_filename,
|
|
saved_path: abs_path,
|
|
mime,
|
|
size: body.len(),
|
|
timestamp: now_sec(),
|
|
});
|
|
|
|
Ok(StatusCode::OK)
|
|
}
|