|
|
|
@ -17,6 +17,8 @@ use crate::{config::Config, file_kind::FileKind};
|
|
|
|
|
const TEXT_VIEW_HTML: &str = include_str!("../template/text-view.html");
|
|
|
|
|
const URL_VIEW_HTML: &str = include_str!("../template/url-view.html");
|
|
|
|
|
|
|
|
|
|
const TEXT_VIEW_SIZE_LIMIT: u64 = 512 * 1024; // 512KiB
|
|
|
|
|
|
|
|
|
|
pub async fn download(
|
|
|
|
|
req: HttpRequest,
|
|
|
|
|
db: web::Data<PgPool>,
|
|
|
|
@ -29,8 +31,7 @@ pub async fn download(
|
|
|
|
|
|
|
|
|
|
let download = delete_on_download || req.query_string().contains("dl");
|
|
|
|
|
let content_type = get_content_type(&path);
|
|
|
|
|
let is_text = file_kind == FileKind::Text.to_string() || content_type.type_() == mime::TEXT;
|
|
|
|
|
let response = if is_text && !download {
|
|
|
|
|
let response = if use_text_view(&file_kind, &content_type, &path, download).await {
|
|
|
|
|
build_text_response(&path).await
|
|
|
|
|
} else {
|
|
|
|
|
build_file_response(download, &file_name, path, content_type, req)
|
|
|
|
@ -71,6 +72,25 @@ fn get_content_type(path: &Path) -> Mime {
|
|
|
|
|
.expect("tree_magic_mini should not produce invalid mime")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async fn use_text_view(
|
|
|
|
|
file_kind: &str,
|
|
|
|
|
content_type: &Mime,
|
|
|
|
|
file_path: &Path,
|
|
|
|
|
download: bool,
|
|
|
|
|
) -> bool {
|
|
|
|
|
let is_text =
|
|
|
|
|
FileKind::from_str(file_kind) == Ok(FileKind::Text) || content_type.type_() == mime::TEXT;
|
|
|
|
|
let is_not_large = get_file_size(file_path).await < TEXT_VIEW_SIZE_LIMIT;
|
|
|
|
|
is_text && is_not_large && !download
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async fn get_file_size(file_path: &Path) -> u64 {
|
|
|
|
|
fs::metadata(file_path)
|
|
|
|
|
.await
|
|
|
|
|
.map(|metadata| metadata.len())
|
|
|
|
|
.unwrap_or(0)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async fn build_text_response(path: &Path) -> Result<HttpResponse, Error> {
|
|
|
|
|
let content = fs::read_to_string(path).await.map_err(|file_err| {
|
|
|
|
|
log::error!("file could not be read {:?}", file_err);
|
|
|
|
|