diff options
author | Anna Miroshnik <anna.miroshnik@arcadia.spb.ru> | 2015-03-12 18:56:10 +0300 |
---|---|---|
committer | Vaadin Code Review <review@vaadin.com> | 2015-06-05 14:03:47 +0000 |
commit | d7284ccfe40f7028e880328566bb825ea31ad619 (patch) | |
tree | 6f1f4b4a676aa7e2bd57ed12162ab1860bd959ea /server/src | |
parent | c4d006d0c6098b1047adb56c0fc7df6f71fe620c (diff) | |
download | vaadin-framework-d7284ccfe40f7028e880328566bb825ea31ad619.tar.gz vaadin-framework-d7284ccfe40f7028e880328566bb825ea31ad619.zip |
Format UTF-8 filenames correctly for download (#16556)
The code is the same for both FileDownloader and DownloadStream except
that FileDownloader forces the content-type to be an "attachment".
Change-Id: I50abf3b0f019b773bc0a44b16536a9479f9f472f
Diffstat (limited to 'server/src')
-rw-r--r-- | server/src/com/vaadin/server/DownloadStream.java | 44 | ||||
-rw-r--r-- | server/src/com/vaadin/server/FileDownloader.java | 14 |
2 files changed, 45 insertions, 13 deletions
diff --git a/server/src/com/vaadin/server/DownloadStream.java b/server/src/com/vaadin/server/DownloadStream.java index 681c438967..0dfd9e42c3 100644 --- a/server/src/com/vaadin/server/DownloadStream.java +++ b/server/src/com/vaadin/server/DownloadStream.java @@ -20,9 +20,12 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.Serializable; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; import java.util.HashMap; import java.util.Iterator; import java.util.Map; +import java.util.logging.Logger; import javax.servlet.http.HttpServletResponse; @@ -40,6 +43,8 @@ import javax.servlet.http.HttpServletResponse; @SuppressWarnings("serial") public class DownloadStream implements Serializable { + public static final String CONTENT_DISPOSITION = "Content-Disposition"; + /** * Maximum cache time. */ @@ -280,17 +285,14 @@ public class DownloadStream implements Serializable { } } - // suggest local filename from DownloadStream if - // Content-Disposition - // not explicitly set - String contentDispositionValue = getParameter("Content-Disposition"); - if (contentDispositionValue == null) { - contentDispositionValue = "filename=\"" + getFileName() - + "\""; - response.setHeader("Content-Disposition", - contentDispositionValue); + // Content-Disposition: attachment generally forces download + String contentDisposition = getParameter(CONTENT_DISPOSITION); + if (contentDisposition == null) { + contentDisposition = getContentDispositionFilename(getFileName()); } + response.setHeader(CONTENT_DISPOSITION, contentDisposition); + int bufferSize = getBufferSize(); if (bufferSize <= 0 || bufferSize > Constants.MAX_BUFFER_SIZE) { bufferSize = Constants.DEFAULT_BUFFER_SIZE; @@ -318,6 +320,30 @@ public class DownloadStream implements Serializable { } /** + * Returns the filename formatted for inclusion in a Content-Disposition + * header. Includes both a plain version of the name and a UTF-8 version + * + * @since + * @param filename + * The filename to include + * @return A value for inclusion in a Content-Disposition header + */ + public static String getContentDispositionFilename(String filename) { + try { + String encodedFilename = URLEncoder.encode(filename, "UTF-8"); + return String.format("filename=\"%s\"; filename*=utf-8''%s", + encodedFilename, encodedFilename); + } catch (UnsupportedEncodingException e) { + return null; + } + + } + + public static Logger getLogger() { + return Logger.getLogger(DownloadStream.class.getName()); + } + + /** * Helper method that tries to close an output stream and ignores any * exceptions. * diff --git a/server/src/com/vaadin/server/FileDownloader.java b/server/src/com/vaadin/server/FileDownloader.java index 42c2f76e1a..b0c3bb1120 100644 --- a/server/src/com/vaadin/server/FileDownloader.java +++ b/server/src/com/vaadin/server/FileDownloader.java @@ -141,12 +141,17 @@ public class FileDownloader extends AbstractExtension { } stream = ((ConnectorResource) resource).getStream(); - if (stream.getParameter("Content-Disposition") == null) { - // Content-Disposition: attachment generally forces download - stream.setParameter("Content-Disposition", - "attachment; filename=\"" + stream.getFileName() + "\""); + String contentDisposition = stream + .getParameter(DownloadStream.CONTENT_DISPOSITION); + if (contentDisposition == null) { + contentDisposition = "attachment; " + + DownloadStream.getContentDispositionFilename(stream + .getFileName()); } + stream.setParameter(DownloadStream.CONTENT_DISPOSITION, + contentDisposition); + // Content-Type to block eager browser plug-ins from hijacking // the file if (isOverrideContentType()) { @@ -158,4 +163,5 @@ public class FileDownloader extends AbstractExtension { stream.writeResponse(request, response); return true; } + } |