diff --git a/src/main/java/com/madeu/config/WebConfig.java b/src/main/java/com/madeu/config/WebConfig.java index 5addc04..395aef5 100644 --- a/src/main/java/com/madeu/config/WebConfig.java +++ b/src/main/java/com/madeu/config/WebConfig.java @@ -1,19 +1,17 @@ package com.madeu.config; -import java.io.File; -import java.io.IOException; -import java.nio.charset.StandardCharsets; - import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.Resource; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.resource.PathResourceResolver; -import org.springframework.web.util.UriUtils; import lombok.extern.slf4j.Slf4j; +import java.io.File; +import java.io.IOException; + @Slf4j @Configuration public class WebConfig implements WebMvcConfigurer { @@ -24,89 +22,97 @@ public class WebConfig implements WebMvcConfigurer { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { log.info("=== WebConfig 초기화 시작 ==="); - log.info("Upload Path: {}", uploadPath); + log.info("Upload Path 설정값: {}", uploadPath); + + File uploadDir = new File(uploadPath); + log.info("Upload 디렉토리 절대 경로: {}", uploadDir.getAbsolutePath()); + log.info("Upload 디렉토리 존재: {}", uploadDir.exists()); + log.info("Upload 디렉토리 읽기 권한: {}", uploadDir.canRead()); registry.addResourceHandler("/cdn/**") .addResourceLocations("file:" + uploadPath + "/") - .setCachePeriod(3600) // 1시간 캐싱 + .setCachePeriod(3600) .resourceChain(true) .addResolver(new PathResourceResolver() { @Override protected Resource getResource(String resourcePath, Resource location) throws IOException { - log.info("=== Resource 요청 받음 ==="); - log.info("원본 Resource Path (인코딩됨): {}", resourcePath); + log.info("========================================"); + log.info("요청 Resource Path: {}", resourcePath); + log.info("Base Location URI: {}", location.getURI()); - // URL 디코딩 처리 (한글 파일명 지원) - String decodedResourcePath = UriUtils.decode(resourcePath, StandardCharsets.UTF_8); - log.info("디코딩된 Resource Path: {}", decodedResourcePath); - log.info("Location: {}", location.getURI()); + Resource requestedResource = location.createRelative(resourcePath); - - - Resource requestedResource = location.createRelative(decodedResourcePath); - // 상세 파일 정보 로깅 + // 핵심: 실제 조합된 전체 경로 확인 try { File file = requestedResource.getFile(); - log.info("실제 파일 경로: {}", file.getAbsolutePath()); - log.info("파일 존재 여부: {}", file.exists()); - log.info("파일 읽기 권한: {}", file.canRead()); - log.info("파일 크기: {} bytes", file.length()); - log.info("파일인지 여부: {}", file.isFile()); - log.info("디렉토리인지 여부: {}", file.isDirectory()); + log.info(">>> 조합된 전체 파일 경로: {}", file.getAbsolutePath()); + log.info(">>> 파일 존재 여부: {}", file.exists()); + + if (!file.exists()) { + // 파일이 없을 때 부모 디렉토리 확인 + File parentDir = file.getParentFile(); + log.info(">>> 부모 디렉토리: {}", parentDir.getAbsolutePath()); + log.info(">>> 부모 디렉토리 존재: {}", parentDir.exists()); + + if (parentDir.exists()) { + log.info(">>> 부모 디렉토리 내 파일 목록:"); + File[] files = parentDir.listFiles(); + if (files != null) { + for (File f : files) { + log.info(" - {}", f.getName()); + } + } + } + } else { + log.info(">>> 파일 읽기 권한: {}", file.canRead()); + log.info(">>> 파일 크기: {} bytes", file.length()); + } } catch (Exception e) { - log.error("파일 정보 조회 실패", e); + log.error(">>> 파일 정보 조회 실패", e); } boolean exists = requestedResource.exists(); boolean readable = exists && requestedResource.isReadable(); - log.info("Requested Resource URI: {}", requestedResource.getURI()); - log.info("Requested Resource exists: {}", exists); - log.info("Requested Resource readable: {}", readable); + log.info("Resource exists: {}", exists); + log.info("Resource readable: {}", readable); - // 보안 검증: 허용된 파일 타입만 if (exists && readable) { boolean allowed = isAllowedResource(requestedResource); - log.info("Resource allowed: {}", allowed); if (allowed) { - log.info("✓ 파일 반환 성공: {}", decodedResourcePath); + log.info("✓✓✓ 파일 반환 성공 ✓✓✓"); return requestedResource; } else { - log.info("✗ 허용되지 않은 파일 타입: {}", decodedResourcePath); + log.info("✗ 허용되지 않은 파일 타입"); } } else { - log.info("✗ 파일 없음 또는 읽을 수 없음: {}", decodedResourcePath); - log.info(" - exists: {}, readable: {}", exists, readable); + log.info("✗✗✗ 파일 없음 또는 읽을 수 없음 ✗✗✗"); } + log.info("========================================"); return null; } private boolean isAllowedResource(Resource resource) { try { String filename = resource.getFilename(); - log.info("Checking filename: {}", filename); if (filename == null) { - log.info("파일명이 null입니다"); return false; } String lowerFilename = filename.toLowerCase(); - boolean isAllowed = lowerFilename.endsWith(".jpg") || - lowerFilename.endsWith(".jpeg") || - lowerFilename.endsWith(".png") || - lowerFilename.endsWith(".gif") || - lowerFilename.endsWith(".webp") || - lowerFilename.endsWith(".bmp") || - lowerFilename.endsWith(".svg"); - - log.info("파일 타입 검증 결과 - 파일명: {}, 허용: {}", filename, isAllowed); - return isAllowed; + return lowerFilename.endsWith(".jpg") || + lowerFilename.endsWith(".jpeg") || + lowerFilename.endsWith(".png") || + lowerFilename.endsWith(".gif") || + lowerFilename.endsWith(".webp") || + lowerFilename.endsWith(".bmp") || + lowerFilename.endsWith(".svg"); } catch (Exception e) { - log.error("파일 타입 검증 중 오류 발생", e); + log.error("파일 타입 검증 중 오류", e); return false; } }