Skip to content

Commit 35433a7

Browse files
authored
Fix content type and filename for resized image attachments (#8894)
* Fix content type returned in resized attachmetns If the attachment is a image and it's resized it is always converted to PNG. Send the `image/png` content type header and change the file name to .png extension. It also add the Content-Length header to the response. Fixes #8558. * Use constants for the Respose headers names
1 parent ef89e5d commit 35433a7

File tree

1 file changed

+31
-5
lines changed

1 file changed

+31
-5
lines changed

services/src/main/java/org/fao/geonet/api/records/attachments/AttachmentsApi.java

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* =============================================================================
3-
* === Copyright (C) 2001-2024 Food and Agriculture Organization of the
3+
* === Copyright (C) 2001-2025 Food and Agriculture Organization of the
44
* === United Nations (FAO-UN), United Nations World Food Programme (WFP)
55
* === and United Nations Environment Programme (UNEP)
66
* ===
@@ -46,6 +46,7 @@
4646
import org.fao.geonet.events.history.AttachmentDeletedEvent;
4747
import org.fao.geonet.util.ImageUtil;
4848
import org.springframework.context.ApplicationContext;
49+
import org.springframework.http.HttpHeaders;
4950
import org.springframework.http.HttpStatus;
5051
import org.springframework.http.MediaType;
5152
import org.springframework.security.access.prepost.PreAuthorize;
@@ -67,6 +68,7 @@
6768
import javax.servlet.http.HttpServletRequest;
6869
import javax.servlet.http.HttpServletResponse;
6970
import java.awt.image.BufferedImage;
71+
import java.io.ByteArrayOutputStream;
7072
import java.io.IOException;
7173
import java.io.InputStream;
7274
import java.net.URL;
@@ -275,22 +277,46 @@ public void getResource(
275277

276278
ApiUtils.canViewRecord(metadataUuid, request);
277279

278-
response.setHeader("Content-Disposition", "inline; filename=\"" + file.getMetadata().getFilename() + "\"");
279-
response.setHeader("Cache-Control", "no-cache");
280+
String originalFilename = file.getMetadata().getFilename();
280281
String contentType = getFileContentType(file.getPath());
281-
response.setHeader("Content-Type", contentType);
282+
String dispositionFilename = originalFilename;
282283

284+
// If the image is being resized, always return as PNG and update
285+
// filename and content-type accordingly
283286
if (contentType.startsWith("image/") && size != null) {
284287
if (size >= MIN_IMAGE_SIZE && size <= MAX_IMAGE_SIZE) {
288+
// Set content type to PNG
289+
contentType = "image/png";
290+
// Change file extension to .png
291+
int dotIdx = originalFilename.lastIndexOf('.');
292+
if (dotIdx > 0) {
293+
dispositionFilename = originalFilename.substring(0, dotIdx) + ".png";
294+
} else {
295+
dispositionFilename = originalFilename + ".png";
296+
}
297+
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "inline; filename=\"" + dispositionFilename + "\"");
298+
response.setHeader(HttpHeaders.CACHE_CONTROL, "no-cache");
299+
response.setHeader(HttpHeaders.CONTENT_TYPE, contentType);
300+
301+
// Read, resize, and write the image as PNG, and set Content-Length
285302
BufferedImage image = ImageIO.read(file.getPath().toFile());
286303
BufferedImage resized = ImageUtil.resize(image, size);
287-
ImageIO.write(resized, "png", response.getOutputStream());
304+
// Write to a byte array first to get the length
305+
ByteArrayOutputStream baos = new ByteArrayOutputStream();
306+
ImageIO.write(resized, "png", baos);
307+
byte[] pngBytes = baos.toByteArray();
308+
response.setContentLengthLong(pngBytes.length);
309+
response.getOutputStream().write(pngBytes);
288310
} else {
289311
throw new IllegalArgumentException(String.format(
290312
"Image can only be resized from %d to %d. You requested %d.",
291313
MIN_IMAGE_SIZE, MAX_IMAGE_SIZE, size));
292314
}
293315
} else {
316+
// For all other files, use the original content type and filename
317+
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "inline; filename=\"" + dispositionFilename + "\"");
318+
response.setHeader(HttpHeaders.CACHE_CONTROL, "no-cache");
319+
response.setHeader(HttpHeaders.CONTENT_TYPE, contentType);
294320
response.setContentLengthLong(Files.size(file.getPath()));
295321

296322
try (InputStream inputStream = Files.newInputStream(file.getPath())) {

0 commit comments

Comments
 (0)