diff --git a/src/main/java/ru/soune/nocopy/controller/FileController.java b/src/main/java/ru/soune/nocopy/controller/FileController.java index 4ebdb10..3ffd0cd 100644 --- a/src/main/java/ru/soune/nocopy/controller/FileController.java +++ b/src/main/java/ru/soune/nocopy/controller/FileController.java @@ -3,9 +3,7 @@ package ru.soune.nocopy.controller; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.Resource; -import org.springframework.http.HttpHeaders; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; +import org.springframework.http.*; import org.springframework.web.bind.annotation.*; import ru.soune.nocopy.dto.file.CheckStatus; import ru.soune.nocopy.entity.file.FileEntity; @@ -16,12 +14,15 @@ import ru.soune.nocopy.repository.FileEntityRepository; import ru.soune.nocopy.repository.UserRepository; import ru.soune.nocopy.service.file.CheckCounterService; import ru.soune.nocopy.service.file.FileStorageService; -import org.springframework.http.ContentDisposition; +import java.io.FileNotFoundException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; @RestController @RequestMapping("/api/files") @@ -40,23 +41,81 @@ public class FileController { @Autowired private UserRepository userRepository; +// @GetMapping("/public/{fileId}") +// public ResponseEntity getPublicFile( +// @PathVariable String fileId) throws IOException { +// +// FileEntity fileEntity = fileRepository.findById(fileId) +// .orElseThrow(() -> new RuntimeException("File not found")); +// +// Resource resource = fileStorageService.loadFileAsResource(fileEntity.getFilePath()); +// +// ContentDisposition contentDisposition = ContentDisposition.inline() +// .filename(fileEntity.getOriginalFileName(), StandardCharsets.UTF_8) +// .build(); +// +// return ResponseEntity.ok() +// .contentType(new MediaType(fileEntity.getMimeType(), fileEntity.getFileExtension())) +// .header(HttpHeaders.CONTENT_DISPOSITION, contentDisposition.toString()) +// .body(resource); +// } + @GetMapping("/public/{fileId}") - public ResponseEntity getPublicFile( - @PathVariable String fileId) throws IOException { + public ResponseEntity getPublicFile(@PathVariable String fileId) { + try { + FileEntity fileEntity = fileRepository.findById(fileId) + .orElseThrow(() -> new FileNotFoundException("Not found: " + fileId)); - FileEntity fileEntity = fileRepository.findById(fileId) - .orElseThrow(() -> new RuntimeException("File not found")); + Path filePath = Paths.get(fileEntity.getFilePath()); + if (!Files.exists(filePath)) { + log.error("Not on disk: {}", fileEntity.getFilePath()); + return ResponseEntity.notFound().build(); + } - Resource resource = fileStorageService.loadFileAsResource(fileEntity.getFilePath()); + Resource resource = fileStorageService.loadFileAsResource(fileEntity.getFilePath()); - ContentDisposition contentDisposition = ContentDisposition.inline() - .filename(fileEntity.getOriginalFileName(), StandardCharsets.UTF_8) - .build(); + MediaType mediaType = getMediaType(fileEntity); - return ResponseEntity.ok() - .contentType(new MediaType(fileEntity.getMimeType(), fileEntity.getFileExtension())) - .header(HttpHeaders.CONTENT_DISPOSITION, contentDisposition.toString()) - .body(resource); + ContentDisposition contentDisposition = ContentDisposition.inline() + .filename(fileEntity.getOriginalFileName(), StandardCharsets.UTF_8) + .build(); + + return ResponseEntity.ok() + .contentType(mediaType) + .contentLength(Files.size(filePath)) + .header(HttpHeaders.CONTENT_DISPOSITION, contentDisposition.toString()) + .header(HttpHeaders.CACHE_CONTROL, "public, max-age=3600") + .body(resource); + + } catch (FileNotFoundException e) { + log.warn("Not on disk: {}", fileId); + return ResponseEntity.notFound().build(); + } catch (IOException e) { + log.error("Read file exception: {}", fileId, e); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); + } + } + + private MediaType getMediaType(FileEntity fileEntity) { + try { + return MediaType.parseMediaType(fileEntity.getMimeType()); + } catch (InvalidMediaTypeException e) { + // Если MIME тип некорректен, определяем по расширению + String extension = fileEntity.getFileExtension().toLowerCase(); + switch (extension) { + case "jpg": + case "jpeg": + return MediaType.IMAGE_JPEG; + case "png": + return MediaType.IMAGE_PNG; + case "gif": + return MediaType.IMAGE_GIF; + case "pdf": + return MediaType.APPLICATION_PDF; + default: + return MediaType.APPLICATION_OCTET_STREAM; + } + } } @GetMapping("/protected/{fileId}")