diff --git a/src/app_state.rs b/src/app_state.rs index 896bc90..9bec9ad 100644 --- a/src/app_state.rs +++ b/src/app_state.rs @@ -92,17 +92,17 @@ impl AppState { let mut redis = self.redis.clone(); // Запрашиваем список файлов из Storj S3 - let filekeyed_list = get_s3_filelist(&self.storj_client, &self.storj_bucket).await; + let filelist = get_s3_filelist(&self.storj_client, &self.storj_bucket).await; - for [filekey, filepath] in filekeyed_list.clone() { + for [filename, filepath] in filelist.clone() { // Сохраняем список файлов в Redis, используя HSET для каждого файла let _: () = redis - .hset(PATH_MAPPING_KEY, filekey.clone(), filepath) + .hset(PATH_MAPPING_KEY, filename.clone(), filepath) .await - .expect(&format!("Failed to cache file {} in Redis", filekey)); + .expect(&format!("Failed to cache file {} in Redis", filename)); } - info!("cached {} files", filekeyed_list.len()); + info!("cached {} files", filelist.len()); } /// Получает кэшированный список файлов из Redis. @@ -117,10 +117,10 @@ impl AppState { } /// Получает путь в Storj из ключа (имени файла) в Redis. - pub async fn get_path(&self, file_key: &str) -> Result, actix_web::Error> { + pub async fn get_path(&self, filename: &str) -> Result, actix_web::Error> { let mut redis = self.redis.clone(); let new_path: Option = redis - .hget(PATH_MAPPING_KEY, file_key) + .hget(PATH_MAPPING_KEY, filename) .await .map_err(|_| ErrorInternalServerError("Failed to get path mapping from Redis"))?; Ok(new_path) diff --git a/src/auth.rs b/src/auth.rs index e6c4c17..11150fc 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -85,11 +85,11 @@ pub async fn get_id_by_token(token: &str) -> Result> { pub async fn user_added_file( redis: &mut MultiplexedConnection, user_id: &str, - file_key: &str, + filename: &str, ) -> Result<(), actix_web::Error> { redis - .sadd::<&str, &str, ()>(user_id, file_key) + .sadd::<&str, &str, ()>(user_id, filename) .await - .map_err(|_| ErrorInternalServerError("Failed to save file_key in Redis"))?; // Добавляем имя файла в набор пользователя + .map_err(|_| ErrorInternalServerError(format!("Failed to save {} in Redis", filename)))?; // Добавляем имя файла в набор пользователя Ok(()) } diff --git a/src/handlers/proxy.rs b/src/handlers/proxy.rs index 009dcd7..9d9fafa 100644 --- a/src/handlers/proxy.rs +++ b/src/handlers/proxy.rs @@ -13,11 +13,14 @@ pub async fn proxy_handler( state: web::Data, ) -> Result { info!("req.path: {}", req.path()); + let requested_path = requested_res.replace("/webp", ""); + let parts = requested_path.split('/').collect::>(); // Explicit type annotation + let filename = parts[parts.len()-1]; - let requested_path = match state.get_path(&requested_res).await { + let requested_path = match state.get_path(&filename).await { Ok(Some(path)) => path, Ok(None) => { - warn!("wrong request: {}", req.path()); + warn!("wrong filename: {}", filename); return Ok(HttpResponse::NotFound().finish()); } Err(e) => { @@ -35,12 +38,12 @@ pub async fn proxy_handler( // Находим ближайший подходящий размер let closest_width = find_closest_width(requested_width); - let thumb_filekey = format!("{}_{}", base_filename, closest_width); - info!("closest width: {}, thumb_filekey: {}", closest_width, thumb_filekey); + let thumb_filename = format!("{}_{}.jpg", base_filename, closest_width); + info!("closest width: {}, thumb_filename: {}", closest_width, thumb_filename); // Проверяем наличие миниатюры в кэше let cached_files = state.get_cached_file_list().await; - if !cached_files.contains(&thumb_filekey) { + if !cached_files.contains(&thumb_filename) { info!("no thumb found"); if cached_files.contains(&base_filename) { info!("no original file found"); @@ -60,7 +63,7 @@ pub async fn proxy_handler( upload_to_s3( &state.storj_client, &state.storj_bucket, - &thumb_filekey, + &thumb_filename, thumbnail_bytes.clone(), "image/jpeg", ) @@ -74,7 +77,7 @@ pub async fn proxy_handler( } } else { info!("thumb was found"); - return serve_file(&thumb_filekey, &state).await; + return serve_file(&thumb_filename, &state).await; } } diff --git a/src/handlers/serve_file.rs b/src/handlers/serve_file.rs index cff1475..f6c2855 100644 --- a/src/handlers/serve_file.rs +++ b/src/handlers/serve_file.rs @@ -11,16 +11,14 @@ pub async fn serve_file(file_path: &str, state: &AppState) -> Result file_path, }; let mut parts = filepath.split('/').collect::>(); // Explicit type annotation - let filename = parts.pop().unwrap(); - let mut filename_parts = filename.split('.').collect::>(); - let _ext = filename_parts.pop().unwrap(); - let filekey = filename_parts.pop().unwrap(); - - let file_path_in_storj = state.get_path(filekey).await.unwrap().unwrap(); + let mut file_fullpath = String::new(); + if let Some(filename) = parts.pop() { + file_fullpath = state.get_path(filename).await.unwrap().unwrap(); + } // Проверяем наличие файла в Storj S3 - if !check_file_exists(&state.storj_client, &state.storj_bucket, &file_path_in_storj).await? { - return Err(ErrorInternalServerError(format!("File {} not found in Storj", file_path_in_storj))); + if !check_file_exists(&state.storj_client, &state.storj_bucket, &file_fullpath).await? { + return Err(ErrorInternalServerError(format!("File {} not found in Storj", file_fullpath))); } // Получаем объект из Storj S3 @@ -28,10 +26,10 @@ pub async fn serve_file(file_path: &str, state: &AppState) -> Result Result Strin mime::Mime::from_str(&mime_type).unwrap_or(mime::APPLICATION_OCTET_STREAM); if let Some(extensions) = mime_guess::get_mime_extensions_str(mime.as_ref()) { if let Some(extension) = extensions.first() { - return format!("{}.{}", base_key, extension); + return format!("{}.{}", base_key, extension.to_lowercase()); } } base_key @@ -77,7 +77,7 @@ pub fn generate_key_with_extension(base_key: String, mime_type: String) -> Strin /// список файлов из S3 pub async fn get_s3_filelist(client: &S3Client, bucket: &str) -> Vec<[std::string::String; 2]> { - let mut filekeys = Vec::new(); + let mut filenames = Vec::new(); // Запрашиваем список файлов из S3 let list_objects_v2 = client.list_objects_v2(); let list_response = list_objects_v2 @@ -94,14 +94,11 @@ pub async fn get_s3_filelist(client: &S3Client, bucket: &str) -> Vec<[std::strin false => s3_filepath, }; let mut parts = filepath.split('/').collect::>(); // Explicit type annotation - let filename = parts.pop().unwrap(); - let mut filename_parts = filename.split('.').collect::>(); - let _ext = filename_parts.pop().unwrap_or_default(); - if let Some(filekey) = filename_parts.pop() { - filekeys.push([filekey.to_string(), s3_filepath.to_string()]); + if let Some(filename) = parts.pop() { + filenames.push([filename.to_string(), s3_filepath.to_string()]); } } } } - filekeys + filenames } \ No newline at end of file