From f19ff6691d5225d377bdf0b72aec4d8b2674224f Mon Sep 17 00:00:00 2001 From: Anthony Stirling <77850077+Frooodle@users.noreply.github.com.> Date: Thu, 10 Jul 2025 14:34:43 +0100 Subject: [PATCH] cleanups --- .../software/common/service/TaskManager.java | 11 +++++++- .../common/controller/JobController.java | 27 ++++++++++++++----- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/common/src/main/java/stirling/software/common/service/TaskManager.java b/common/src/main/java/stirling/software/common/service/TaskManager.java index e2a9a1574..33e2a3ddb 100644 --- a/common/src/main/java/stirling/software/common/service/TaskManager.java +++ b/common/src/main/java/stirling/software/common/service/TaskManager.java @@ -1,6 +1,7 @@ package stirling.software.common.service; import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; @@ -358,7 +359,15 @@ public class TaskManager { ZipEntry entry; while ((entry = zipIn.getNextEntry()) != null) { if (!entry.isDirectory()) { - byte[] fileContent = zipIn.readAllBytes(); + // Use buffered reading for memory safety + ByteArrayOutputStream out = new ByteArrayOutputStream(); + byte[] buffer = new byte[4096]; + int bytesRead; + while ((bytesRead = zipIn.read(buffer)) != -1) { + out.write(buffer, 0, bytesRead); + } + byte[] fileContent = out.toByteArray(); + String contentType = determineContentType(entry.getName()); String individualFileId = fileStorage.storeBytes(fileContent, entry.getName()); diff --git a/stirling-pdf/src/main/java/stirling/software/common/controller/JobController.java b/stirling-pdf/src/main/java/stirling/software/common/controller/JobController.java index 6b49052fb..1853962ab 100644 --- a/stirling-pdf/src/main/java/stirling/software/common/controller/JobController.java +++ b/stirling-pdf/src/main/java/stirling/software/common/controller/JobController.java @@ -1,5 +1,7 @@ package stirling.software.common.controller; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Map; @@ -99,9 +101,7 @@ public class JobController { byte[] fileContent = fileStorage.retrieveBytes(singleFile.getFileId()); return ResponseEntity.ok() .header("Content-Type", singleFile.getContentType()) - .header( - "Content-Disposition", - "attachment; filename=\"" + singleFile.getFileName() + "\"") + .header("Content-Disposition", createContentDispositionHeader(singleFile.getFileName())) .body(fileContent); } catch (Exception e) { log.error("Error retrieving file for job {}: {}", jobId, e.getMessage(), e); @@ -276,9 +276,7 @@ public class JobController { return ResponseEntity.ok() .header("Content-Type", contentType) - .header( - "Content-Disposition", - "attachment; filename=\"" + fileName + "\"") + .header("Content-Disposition", createContentDispositionHeader(fileName)) .body(fileContent); } catch (Exception e) { log.error("Error retrieving file {}: {}", fileId, e.getMessage(), e); @@ -301,4 +299,21 @@ public class JobController { // TODO: Consider adding a fileId -> ResultFile mapping in TaskManager return taskManager.findResultFileByFileId(fileId); } + + /** + * Create Content-Disposition header with UTF-8 filename support + * + * @param fileName The filename to encode + * @return Content-Disposition header value + */ + private String createContentDispositionHeader(String fileName) { + try { + String encodedFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8) + .replace("+", "%20"); // URLEncoder uses + for spaces, but we want %20 + return "attachment; filename=\"" + fileName + "\"; filename*=UTF-8''" + encodedFileName; + } catch (Exception e) { + // Fallback to basic filename if encoding fails + return "attachment; filename=\"" + fileName + "\""; + } + } }