From 6e5fcb39c81b4f2ad507b7f29e87bca44161dc55 Mon Sep 17 00:00:00 2001 From: Gregor Lohaus Date: Fri, 5 Jun 2026 15:39:21 +0200 Subject: [PATCH] cleanup incomplete uploads --- .../controller/DownloadController.java | 4 ++++ .../controller/UploadController.java | 21 ++++++++++++++++++- .../gregor_lohaus/gtransfer/model/File.java | 8 +++++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/Backend/src/main/java/com/gregor_lohaus/gtransfer/controller/DownloadController.java b/Backend/src/main/java/com/gregor_lohaus/gtransfer/controller/DownloadController.java index 5770a05..122e0a0 100644 --- a/Backend/src/main/java/com/gregor_lohaus/gtransfer/controller/DownloadController.java +++ b/Backend/src/main/java/com/gregor_lohaus/gtransfer/controller/DownloadController.java @@ -101,6 +101,10 @@ public class DownloadController { } File file = fileOpt.get(); + if (!file.isCompleted()) { + return AvailableFile.notFound(); + } + if (file.getExpireyDateTime() != null && LocalDateTime.now().isAfter(file.getExpireyDateTime())) { deleteStoredFile(file); fileRepository.delete(file); diff --git a/Backend/src/main/java/com/gregor_lohaus/gtransfer/controller/UploadController.java b/Backend/src/main/java/com/gregor_lohaus/gtransfer/controller/UploadController.java index 6bffd9f..ae5fe31 100644 --- a/Backend/src/main/java/com/gregor_lohaus/gtransfer/controller/UploadController.java +++ b/Backend/src/main/java/com/gregor_lohaus/gtransfer/controller/UploadController.java @@ -10,6 +10,7 @@ import org.springframework.http.ResponseEntity; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; +import org.springframework.transaction.annotation.Transactional; import org.springframework.web.server.ResponseStatusException; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; @@ -45,6 +46,7 @@ public class UploadController { } @PostMapping("/upload") + @Transactional public String upload( @RequestParam("hash") String hash, @RequestParam("name") String name, @@ -58,15 +60,24 @@ public class UploadController { int days = expiryDays != null ? Math.min(expiryDays, maxExpiryDays) : maxExpiryDays; Integer limit = downloadLimit != null ? Math.min(downloadLimit, maxDownloadLimit) : null; - File f = new File(hash, hash, name, LocalDateTime.now().plusDays(days)); + File f = fileRepository.findById(hash) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.BAD_REQUEST, "Upload has no chunks")); + if (f.getChunkCount() < chunkCount) { + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Upload is missing chunks"); + } + f.setName(name); + f.setPath(hash); + f.setExpireyDateTime(LocalDateTime.now().plusDays(days)); f.setChunkCount(chunkCount); f.setDownloadLimit(limit); + f.setCompleted(true); fileRepository.save(f); return "upload/result :: view"; } @PostMapping("/upload/chunk") + @Transactional public ResponseEntity uploadChunk( @RequestParam("chunk") MultipartFile chunk, @RequestParam("hash") String hash, @@ -80,6 +91,14 @@ public class UploadController { return ResponseEntity.internalServerError().build(); } + File f = fileRepository.findById(hash) + .orElseGet(() -> new File(hash, hash, hash, LocalDateTime.now().plusDays(maxExpiryDays))); + f.setChunkCount(Math.max(f.getChunkCount(), index + 1)); + if (!f.isCompleted()) { + f.setCompleted(false); + } + fileRepository.save(f); + return ResponseEntity.noContent().build(); } diff --git a/Backend/src/main/java/com/gregor_lohaus/gtransfer/model/File.java b/Backend/src/main/java/com/gregor_lohaus/gtransfer/model/File.java index 66fb118..b21cc6b 100644 --- a/Backend/src/main/java/com/gregor_lohaus/gtransfer/model/File.java +++ b/Backend/src/main/java/com/gregor_lohaus/gtransfer/model/File.java @@ -14,6 +14,8 @@ public class File { private String path; private String name; private Integer chunkCount; + @Column(columnDefinition = "boolean default false") + private Boolean completed = false; private LocalDateTime expireyDateTime; private Integer downloadLimit; @Column(columnDefinition = "integer default 0") @@ -48,6 +50,12 @@ public class File { public void setChunkCount(Integer chunkCount) { this.chunkCount = chunkCount; } + public boolean isCompleted() { + return Boolean.TRUE.equals(completed); + } + public void setCompleted(Boolean completed) { + this.completed = completed; + } public Integer getDownloadLimit() { return downloadLimit; }