cleanup incomplete uploads
All checks were successful
Deploy / Explore-Gitea-Actions (push) Successful in 8m14s

This commit is contained in:
2026-06-05 15:39:21 +02:00
parent 8b9b3a0ff8
commit 6e5fcb39c8
3 changed files with 32 additions and 1 deletions

View File

@@ -101,6 +101,10 @@ public class DownloadController {
} }
File file = fileOpt.get(); File file = fileOpt.get();
if (!file.isCompleted()) {
return AvailableFile.notFound();
}
if (file.getExpireyDateTime() != null && LocalDateTime.now().isAfter(file.getExpireyDateTime())) { if (file.getExpireyDateTime() != null && LocalDateTime.now().isAfter(file.getExpireyDateTime())) {
deleteStoredFile(file); deleteStoredFile(file);
fileRepository.delete(file); fileRepository.delete(file);

View File

@@ -10,6 +10,7 @@ import org.springframework.http.ResponseEntity;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; import org.springframework.ui.Model;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.server.ResponseStatusException; import org.springframework.web.server.ResponseStatusException;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
@@ -45,6 +46,7 @@ public class UploadController {
} }
@PostMapping("/upload") @PostMapping("/upload")
@Transactional
public String upload( public String upload(
@RequestParam("hash") String hash, @RequestParam("hash") String hash,
@RequestParam("name") String name, @RequestParam("name") String name,
@@ -58,15 +60,24 @@ public class UploadController {
int days = expiryDays != null ? Math.min(expiryDays, maxExpiryDays) : maxExpiryDays; int days = expiryDays != null ? Math.min(expiryDays, maxExpiryDays) : maxExpiryDays;
Integer limit = downloadLimit != null ? Math.min(downloadLimit, maxDownloadLimit) : null; 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.setChunkCount(chunkCount);
f.setDownloadLimit(limit); f.setDownloadLimit(limit);
f.setCompleted(true);
fileRepository.save(f); fileRepository.save(f);
return "upload/result :: view"; return "upload/result :: view";
} }
@PostMapping("/upload/chunk") @PostMapping("/upload/chunk")
@Transactional
public ResponseEntity<Void> uploadChunk( public ResponseEntity<Void> uploadChunk(
@RequestParam("chunk") MultipartFile chunk, @RequestParam("chunk") MultipartFile chunk,
@RequestParam("hash") String hash, @RequestParam("hash") String hash,
@@ -80,6 +91,14 @@ public class UploadController {
return ResponseEntity.internalServerError().build(); 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(); return ResponseEntity.noContent().build();
} }

View File

@@ -14,6 +14,8 @@ public class File {
private String path; private String path;
private String name; private String name;
private Integer chunkCount; private Integer chunkCount;
@Column(columnDefinition = "boolean default false")
private Boolean completed = false;
private LocalDateTime expireyDateTime; private LocalDateTime expireyDateTime;
private Integer downloadLimit; private Integer downloadLimit;
@Column(columnDefinition = "integer default 0") @Column(columnDefinition = "integer default 0")
@@ -48,6 +50,12 @@ public class File {
public void setChunkCount(Integer chunkCount) { public void setChunkCount(Integer chunkCount) {
this.chunkCount = chunkCount; this.chunkCount = chunkCount;
} }
public boolean isCompleted() {
return Boolean.TRUE.equals(completed);
}
public void setCompleted(Boolean completed) {
this.completed = completed;
}
public Integer getDownloadLimit() { public Integer getDownloadLimit() {
return downloadLimit; return downloadLimit;
} }