[파일 업로드] tusHook 작업
- 리줌 키로 다른 파일 올릴때 막기
This commit is contained in:
@@ -64,6 +64,8 @@ public class FileController {
|
||||
public ResponseEntity<ApiResponse<String>> uploadAuth(
|
||||
@RequestHeader(value = "Authorization", required = false) String uploadToken
|
||||
, @RequestHeader(value = "x-File-Uuid", required = false) String fileUuid
|
||||
, @RequestHeader(value = "Upload-Metadata", required = false) String uploadMetadata
|
||||
, @RequestHeader(value = "Upload-Length", required = false) String uploadLength
|
||||
) {
|
||||
if (uploadToken == null || !uploadToken.startsWith("Bearer ")) {
|
||||
return ApiResponse.entity("", ApiResponseCode.CODE_401);
|
||||
@@ -75,6 +77,8 @@ public class FileController {
|
||||
UploadTokenDto uploadTokenDto = new UploadTokenDto();
|
||||
uploadTokenDto.setUploadToken(uploadToken.substring(7).trim());
|
||||
uploadTokenDto.setFileUuid(fileUuid.trim());
|
||||
uploadTokenDto.setUploadMetadataRaw(uploadMetadata);
|
||||
uploadTokenDto.setUploadLengthRaw(uploadLength);
|
||||
|
||||
UploadTokenDto uploadTokenCheck = fileService.isUploadTokenCheck(uploadTokenDto);
|
||||
|
||||
|
||||
@@ -11,6 +11,13 @@ public class UploadTokenDto {
|
||||
private String fileUuid;
|
||||
private String uploadToken;
|
||||
|
||||
private String uploadMetadataRaw;
|
||||
private String uploadLengthRaw;
|
||||
|
||||
private String originName;
|
||||
private Long sizeBytes;
|
||||
private String contentType;
|
||||
|
||||
@JsonIgnore
|
||||
private int resultCode;
|
||||
}
|
||||
|
||||
@@ -88,7 +88,9 @@ public class FileService {
|
||||
return uploadTokenDto;
|
||||
}
|
||||
|
||||
String cacheKey = buildAuthCacheKey(uploadTokenDto.getFileUuid(), uploadTokenDto.getUploadToken());
|
||||
applyTusMeta(uploadTokenDto);
|
||||
|
||||
String cacheKey = buildAuthCacheKey(uploadTokenDto);
|
||||
|
||||
try {
|
||||
String cached = stringRedisTemplate.opsForValue().get(cacheKey);
|
||||
@@ -122,6 +124,34 @@ public class FileService {
|
||||
return uploadTokenDto;
|
||||
}
|
||||
|
||||
private void applyTusMeta(UploadTokenDto dto) {
|
||||
String len = dto.getUploadLengthRaw();
|
||||
if (len != null && !len.isBlank()) {
|
||||
try { dto.setSizeBytes(Long.parseLong(len.trim())); } catch (Exception ignored) {}
|
||||
}
|
||||
|
||||
String raw = dto.getUploadMetadataRaw();
|
||||
if (raw == null || raw.isBlank()) return;
|
||||
|
||||
for (String part : raw.split(",")) {
|
||||
String p = part.trim();
|
||||
int sp = p.indexOf(' ');
|
||||
if (sp <= 0) continue;
|
||||
|
||||
String key = p.substring(0, sp).trim();
|
||||
String val = p.substring(sp + 1).trim();
|
||||
String decoded;
|
||||
try {
|
||||
decoded = new String(java.util.Base64.getDecoder().decode(val), java.nio.charset.StandardCharsets.UTF_8);
|
||||
} catch (Exception e) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ("filename".equals(key)) dto.setOriginName(decoded);
|
||||
else if ("filetype".equals(key)) dto.setContentType(decoded);
|
||||
}
|
||||
}
|
||||
|
||||
public UploadStatusDto getUploadStatus(UploadStatusDto uploadStatusDto) {
|
||||
String key = buildUploadStatusKey(uploadStatusDto.getFileUuid());
|
||||
Map<Object, Object> map = stringRedisTemplate.opsForHash().entries(key);
|
||||
@@ -341,8 +371,24 @@ public class FileService {
|
||||
}
|
||||
}
|
||||
|
||||
private String buildAuthCacheKey(String fileUuid, String uploadToken) {
|
||||
return "upload:alist:auth:" + fileUuid + ":" + sha256(uploadToken);
|
||||
private String buildAuthCacheKey(UploadTokenDto dto) {
|
||||
String normalizedName = normalize(dto.getOriginName());
|
||||
String normalizedType = normalize(dto.getContentType());
|
||||
String normalizedSize = (dto.getSizeBytes() == null) ? "" : String.valueOf(dto.getSizeBytes());
|
||||
|
||||
String raw = String.join("|",
|
||||
normalize(dto.getFileUuid()),
|
||||
dto.getUploadToken() == null ? "" : dto.getUploadToken(),
|
||||
normalizedName,
|
||||
normalizedType,
|
||||
normalizedSize
|
||||
);
|
||||
|
||||
return "upload:alist:auth:" + sha256(raw);
|
||||
}
|
||||
|
||||
private String normalize(String v) {
|
||||
return (v == null) ? "" : v.trim().toLowerCase();
|
||||
}
|
||||
|
||||
private String sha256(String value) {
|
||||
@@ -355,18 +401,6 @@ public class FileService {
|
||||
}
|
||||
}
|
||||
|
||||
private void evictUploadAuthCacheByFileUuid(String fileUuid) {
|
||||
try {
|
||||
String pattern = "upload:alist:auth:" + fileUuid + ":*";
|
||||
var keys = stringRedisTemplate.keys(pattern);
|
||||
if (!keys.isEmpty()) {
|
||||
stringRedisTemplate.delete(keys);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("uploadAuth cache evict fail. fileUuid={}", fileUuid, e);
|
||||
}
|
||||
}
|
||||
|
||||
private long safeTtlSeconds() {
|
||||
// 설정 실수 방어: 0/음수면 기본값 20초 사용
|
||||
return (uploadAuthCacheTtlSeconds > 0) ? uploadAuthCacheTtlSeconds : 20L;
|
||||
|
||||
@@ -130,12 +130,18 @@
|
||||
/*FileMapper.selectFileDetailCountByFileUuidUserToKenIdx*/
|
||||
SELECT COUNT(*)
|
||||
FROM ALISTLMS.FILE_DETAIL LFD
|
||||
INNER JOIN ALISTLMS.test_user_token LTUT
|
||||
ON LTUT.user_idx = LFD.CREATE_MEMBER
|
||||
INNER JOIN ALISTLMS.test_user_token LTUT ON LTUT.user_idx = LFD.CREATE_MEMBER
|
||||
WHERE LFD.DEL_YN = 'N'
|
||||
AND LFD.FILE_UUID = #{fileUuid}
|
||||
AND LFD.STATUS IN (0,1,2,3) <!-- 정책에 맞게 조정 -->
|
||||
AND LTUT.user_token_idx = #{userTokenIdx}
|
||||
AND LFD.STATUS IN (0,1,2,3)
|
||||
AND (#{sizeBytes} IS NULL OR LFD.SIZE_BYTES = #{sizeBytes})
|
||||
AND (#{originName} IS NULL OR #{originName} = '' OR LFD.ORIGIN_NAME = #{originName})
|
||||
AND (
|
||||
#{contentType} IS NULL OR #{contentType} = ''
|
||||
OR LFD.CONTENT_TYPE IS NULL OR LFD.CONTENT_TYPE = ''
|
||||
OR LOWER(LFD.CONTENT_TYPE) = LOWER(#{contentType})
|
||||
)
|
||||
</select>
|
||||
<select id="selectFileUploadMetaByFileUuid" resultType="com.alist.api.common.modules.file.dto.FileUploadMetaDto">
|
||||
/*FileMapper.selectFileUploadMetaByFileUuid*/
|
||||
|
||||
Reference in New Issue
Block a user