23
23
24
24
import java .io .ByteArrayOutputStream ;
25
25
import java .io .PrintWriter ;
26
+ import java .io .UnsupportedEncodingException ;
27
+ import java .net .URLEncoder ;
26
28
import java .util .Enumeration ;
27
29
import java .util .regex .Matcher ;
28
30
import java .util .regex .Pattern ;
@@ -546,6 +548,8 @@ protected static final String toHex(byte b)
546
548
** Sadly, Safari has a known bug where doesn't correctly translate encoding for user
547
549
**
548
550
** This method require inclusion of the javamail mail package.
551
+ ** @deprecated It is now possible to specify encoded filenames for the browser
552
+ ** see @link{Web#buildContentDisposition}
549
553
**/
550
554
public static String encodeFileName (HttpServletRequest req , String fileName )
551
555
{
@@ -567,9 +571,38 @@ else if ( agent != null && agent.indexOf("Mozilla")>=0 && agent.indexOf("Safari"
567
571
return fileName ;
568
572
}
569
573
574
+ /**
575
+ * This attempts to build the value of the content disposition header. It provides a ISO-8859-1 representation
576
+ * and a full UTF-8 version. This allows browser that understand the full version to use that and
577
+ * for mainly IE 8 the old limited one.
578
+ * @param filename The filename to encode
579
+ * @param isDownload Whether the file is a download, will use "attachment" if true and "inline" if false.
580
+ * @return The value of the content disposition header specifying it's inline content.
581
+ */
582
+ public static String buildContentDisposition (String filename , boolean isDownload ) {
583
+ try {
584
+ // This will replace all non US-ASCII characters with '?'
585
+ // Although this behaviour is unspecified doing it manually is overkill (too much work).
586
+ // Make sure we escape double quotes.
587
+ String iso8859Filename = new String (filename .getBytes ("ISO-8859-1" ), "ISO-8859-1" )
588
+ .replace ("\\ " , "\\ \\ " )
589
+ .replace ("\" " , "\\ \" " );
590
+ String utf8Filename = URLEncoder .encode (filename , "UTF-8" ).replace ("+" , "%20" );
591
+ return new StringBuilder ()
592
+ .append (isDownload ? "attachment; " : "inline; " )
593
+ .append ("filename=\" " ).append (iso8859Filename ).append ("\" ; " )
594
+ // For sensible browser give them a full UTF-8 encoded string.
595
+ .append ("filename*=UTF-8''" ).append (utf8Filename )
596
+ .toString ();
597
+ } catch (UnsupportedEncodingException shouldNeverHappen ) {
598
+ throw new RuntimeException (shouldNeverHappen );
599
+ }
600
+ }
601
+
570
602
private static String internalEscapeHtml (String value , boolean escapeNewlines ) {
571
603
// FIXME this method needs to be removed entirely and is only here as a reference of how this used to work
572
604
605
+
573
606
if (value == null ) return "" ;
574
607
575
608
try {
0 commit comments