Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set filename containing spaces in Content-Disposition header

I have this piece of code:

resp.addHeader("Content-Disposition", "inline; filename=" + fileName);

When the file name is "a_b_c.doc" or "abc.doc" the name of the downloaded file is displayed correctly. However, when the file name is "a b c .doc" the name of the downloaded file is only "a".

How can we solve this?

like image 438
Huy Than Avatar asked Sep 05 '13 10:09

Huy Than


People also ask

What is content-disposition filename?

Content-Disposition is an optional header and allows the sender to indicate a default archival disposition; a filename. The optional "filename" parameter provides for this. This header field definition is based almost verbatim on Experimental RFC 1806 by R. Troost and S.

Is content-disposition a header?

In a regular HTTP response, the Content-Disposition response header is a header indicating if the content is expected to be displayed inline in the browser, that is, as a Web page or as part of a Web page, or as an attachment, that is downloaded and saved locally.

What is content-disposition in Java?

The MIME Content-disposition header provides presentation information for the body-part. It is often added to attachments specifying whether the attachment body part should be displayed (inline) or presented as a file name to be copied (attachment).


3 Answers

Use quotes:

resp.addHeader("Content-Disposition", "inline; filename=\"" + fileName + "\"");
like image 59
Moritz Petersen Avatar answered Oct 23 '22 15:10

Moritz Petersen


According to the HTTP standard you surround the string with double-quotes, and escape any quotes or backslashes within by preceding them with a single backslash.

Content-Disposition: attachment; filename="Very \"interesting\" file \\ files.txt"

This will prompt to save as Very "interesting" file \ files.txt. Note that the presence of a backslash does not suggest a folder, it suggests the backslash is part of the filename (which is perfectly valid on Linux and some other platforms, but not on Windows.)

like image 43
Malvineous Avatar answered Oct 23 '22 15:10

Malvineous


Following steps are required:

  • URI-encode the filename
  • Replace the spaces in the encoded filename (we're using an URL encoder instead of URI encoder, but URL encoding uses + as encoded space instead of %20, so we need to manually replace them with %20).
  • Set the encoded file name in the header. Here we have two variants: one which specifices the encoding, and one that doesn't. For maximal compatibility we can specify both.

Code:

String fileName = ...;
String encodedFileName = URLEncoder.encode(fileName, 
    StandardCharsets.UTF_8.name()).replace("+", "%20");

response.setHeader("Content-Disposition", 
    String.format("inline; filename*=UTF-8''%1$s; filename=%1$s", encodedFileName));

Example header: inline; filename*=UTF-8''Hello%20World.doc; filename=Hello%20World.doc

Successfully tested with

  • Firefox ✔
  • Chrome ✔
  • Edge ✔
  • Internet Explorer ✔
like image 2
Peter Walser Avatar answered Oct 23 '22 16:10

Peter Walser