Skip to content

Commit 69fd8f5

Browse files
authored
fix: Deduce content type from file name (#21611)
1 parent f32df2a commit 69fd8f5

File tree

3 files changed

+56
-3
lines changed

3 files changed

+56
-3
lines changed

flow-server/src/main/java/com/vaadin/flow/server/streams/DownloadResponse.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,16 +52,17 @@ public class DownloadResponse implements Serializable {
5252
* Content-Disposition header to 'attachment' if the value is not
5353
* <code>null</code>, otherwise the header is not set
5454
* @param contentType
55-
* content type
55+
* content type or a value determined from fileName if
56+
* {@code null}
5657
* @param contentLength
5758
* byte size of a stream or <code>-1</code> if unknown
5859
*/
5960
public DownloadResponse(InputStream inputStream, String fileName,
6061
String contentType, long contentLength) {
6162
this.inputStream = inputStream;
6263
this.fileName = fileName;
63-
this.contentType = contentType;
6464
this.contentLength = contentLength;
65+
this.contentType = contentType;
6566
}
6667

6768
/**
@@ -86,6 +87,10 @@ public String getFileName() {
8687

8788
/**
8889
* Get the content type.
90+
* <p>
91+
* For a {@code null} value the type should be gotten from
92+
* {@code VaadinService.getMimeType(fileName)} or be set to default value
93+
* {@code application/octet-stream}
8994
*
9095
* @return content type
9196
*/

flow-server/src/main/java/com/vaadin/flow/server/streams/InputStreamDownloadHandler.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,11 @@ public void handleDownloadRequest(DownloadEvent downloadEvent)
5555
}
5656

5757
String downloadName = download.getFileName();
58-
downloadEvent.setContentType(getContentType(downloadName, response));
58+
String contentType = download.getContentType() == null
59+
? getContentType(downloadName, response)
60+
: download.getContentType();
61+
downloadEvent.setContentType(contentType);
62+
5963
if (!isInline()) {
6064
downloadEvent.setFileName(downloadName);
6165
}

flow-server/src/test/java/com/vaadin/flow/server/streams/InputStreamDownloadHandlerTest.java

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,50 @@ public void inputStreamDownloadCallback_doesNotRequireCatch() {
252252
});
253253
}
254254

255+
@Test
256+
public void downloadResponseHasContentType_contentTypeUsed()
257+
throws IOException {
258+
String contentType = "custom";
259+
InputStreamDownloadHandler handler = new InputStreamDownloadHandler(
260+
event -> {
261+
InputStream stream = Mockito.mock(InputStream.class);
262+
Mockito.when(stream.read(Mockito.any(), Mockito.anyInt(),
263+
Mockito.anyInt())).thenReturn(-1);
264+
return new DownloadResponse(stream, "report.pdf",
265+
contentType, 0);
266+
});
267+
268+
DownloadEvent event = new DownloadEvent(request, response, session,
269+
new Element("div"));
270+
271+
handler.handleDownloadRequest(event);
272+
273+
Mockito.verify(response).setContentType(contentType);
274+
}
275+
276+
@Test
277+
public void downloadResponseNullContentType_fileTypeIsUsed()
278+
throws IOException {
279+
String contentType = "file/pdf";
280+
281+
Mockito.when(service.getMimeType("report.pdf")).thenReturn(contentType);
282+
283+
InputStreamDownloadHandler handler = new InputStreamDownloadHandler(
284+
event -> {
285+
InputStream stream = Mockito.mock(InputStream.class);
286+
Mockito.when(stream.read(Mockito.any(), Mockito.anyInt(),
287+
Mockito.anyInt())).thenReturn(-1);
288+
return new DownloadResponse(stream, "report.pdf", null, 0);
289+
});
290+
291+
DownloadEvent event = new DownloadEvent(request, response, session,
292+
new Element("div"));
293+
294+
handler.handleDownloadRequest(event);
295+
296+
Mockito.verify(response).setContentType(contentType);
297+
}
298+
255299
private static byte[] getBytes() {
256300
// Simulate a download of 165000 bytes
257301
byte[] data = new byte[165000];

0 commit comments

Comments
 (0)