diff --git a/backend/src/main/java/com/sshmanager/controller/SftpController.java b/backend/src/main/java/com/sshmanager/controller/SftpController.java index 4f6e80f..6800891 100644 --- a/backend/src/main/java/com/sshmanager/controller/SftpController.java +++ b/backend/src/main/java/com/sshmanager/controller/SftpController.java @@ -290,11 +290,21 @@ public class SftpController { @RequestParam String path, @RequestParam("file") MultipartFile file, Authentication authentication) { + java.io.File tempFile = null; try { Long userId = getCurrentUserId(authentication); String taskId = UUID.randomUUID().toString(); String taskKey = uploadTaskKey(userId, taskId); + // Save file to persistent location before async processing + java.io.File uploadTempDir = new java.io.File("./data/upload-temp"); + if (!uploadTempDir.exists()) { + uploadTempDir.mkdirs(); + } + tempFile = new java.io.File(uploadTempDir, taskId + "_" + file.getOriginalFilename()); + file.transferTo(tempFile); + final java.io.File savedFile = tempFile; + UploadTaskStatus status = new UploadTaskStatus(taskId, userId, connectionId, path, file.getOriginalFilename(), file.getSize()); status.setController(this); @@ -308,11 +318,11 @@ public class SftpController { try { SftpService.SftpSession session = getOrCreateSession(connectionId, userId); String remotePath = (path == null || path.isEmpty() || path.equals("/")) - ? "/" + file.getOriginalFilename() - : (path.endsWith("/") ? path + file.getOriginalFilename() : path + "/" + file.getOriginalFilename()); + ? "/" + savedFile.getName().substring(savedFile.getName().indexOf("_") + 1) + : (path.endsWith("/") ? path + savedFile.getName().substring(savedFile.getName().indexOf("_") + 1) : path + "/" + savedFile.getName().substring(savedFile.getName().indexOf("_") + 1)); AtomicLong transferred = new AtomicLong(0); - try (java.io.InputStream in = file.getInputStream()) { + try (java.io.InputStream in = new java.io.FileInputStream(savedFile)) { sftpService.upload(session, remotePath, in, new SftpService.TransferProgressListener() { @Override public void onStart(long totalBytes) { @@ -334,10 +344,19 @@ public class SftpController { existing.disconnect(); } throw new RuntimeException(e); + } finally { + // Clean up temp file after upload completes + if (savedFile.exists()) { + savedFile.delete(); + } } }); } catch (Exception e) { status.markError(e.getMessage() != null ? e.getMessage() : "Upload failed"); + // Clean up temp file on error + if (savedFile.exists()) { + savedFile.delete(); + } } }); status.setFuture(future); @@ -347,6 +366,10 @@ public class SftpController { result.put("message", "Upload started"); return ResponseEntity.ok(result); } catch (Exception e) { + // Clean up temp file if initial save failed + if (tempFile != null && tempFile.exists()) { + tempFile.delete(); + } Map error = new HashMap<>(); error.put("error", e.getMessage()); return ResponseEntity.status(500).body(error); diff --git a/backend/src/main/resources/application.yml b/backend/src/main/resources/application.yml index ad52294..81f8a8f 100644 --- a/backend/src/main/resources/application.yml +++ b/backend/src/main/resources/application.yml @@ -9,6 +9,8 @@ spring: multipart: max-file-size: 2048MB max-request-size: 2048MB + location: ./data/upload-temp + file-size-threshold: 0 datasource: url: jdbc:h2:file:./data/sshmanager;DB_CLOSE_DELAY=-1 driver-class-name: org.h2.Driver