My question is a duplicate of How to encode the filename parameter of Content-Disposition header in HTTP? But since that question was asked a long time ago and there is still no satisfying answer (in my opinion), I would like to ask again.
I develop a C++ CGI application that delivers files that can contain special characters in their names like
"weird # € = { } ; filename.txt"
There seems to be no possibility to set the HTTP Content-Dispostion in a way that it works for every browser like
I would be happy with a different solution for every browser.
Now that is how far I came:
Internet Explorer (added double quotes and replaced # and ; )
Content-Disposition: attachment; filename="weird %23 € = { } %3B filename.txt"
Firefox (double quotes seem to work. nothing more to do):
Content-Disposition: attachment; filename="weird # € = { } ; filename.txt"
Another working alternative:
Content-Disposition: attachment; filename*=UTF-8''weird%20%23%20%e2%82%ac%20%3D%20%7B%20%7D%20%3B%20filename.txt
Chrome
when using only double quotes these problems arise:
but this works:
Content-Disposition: attachment; filename*=UTF-8''weird%20%23%20%e2%82%ac%20%3D%20%7B%20%7D%20%3B%20filename.txt
Opera
Using duoble quotes or using the syntax: filename*=UTF-8''... produces the following problems:
EDIT 2: This was because of filename length limitations. This syntax works with Opera:
Content-Disposition: attachment; filename*=UTF-8''weird%20%23%20%e2%82%ac%20%3D%20%7B%20%7D%20%3B%20filename.txt
Safari
€ will be replaced by an invisble character (using double quotes)
no solution that prevents that little problem
The suggestion from the other thread (mentioned above) using
Content-Disposition: attachment; filename*=UTF-8''weird%20%23%20%80%20%3D%20%7B%20%7D%20%3B%20filename.txt
didn't work for me. The escape characters won't be translated back or the browser wants to save to file with the name of my cgi application. That was because my encoding was wrong. I did not encode according to RFC 5987. But Safari isn't using this encoding anyway. So no solution for the € character so far.
BTW: An UTF-8 converter http://www.rishida.net/tools/conversion/
I used the latest version of every browser fo these tests:
PS: I tried all special characters on my keyboard. I used in this thread only the ones that made trouble.
I also tried a filename with all special characters on my keyboard (that are possible in a filename) and that did not work as it did with the test string above:
Complete Test string:
0 ! § $ % & ( ) = ` ´ { } [ ] ² ³ @ € µ ^ ° ~ + ' # - _ . , ; ü ä ö ß 9.jpg
Encoded Test String:
0%20%21%20%C2%A7%20%24%20%25%20%26%20%28%20%29%20%3D%20%60%20%C2%B4%20%7B%20%7D%20%20%20%20%5B%20%5D%20%C2%B2%20%C2%B3%20%40%20%E2%82%AC%20%C2%B5%20%5E%20%C2%B0%20~%20%2B%20%27%20%23%20-%20_%20.%20%2C%20%3B%20%C3%BC%20%C3%A4%20%C3%B6%20%C3%9F%209.jpg
Using this method:
Content-Disposition: attachment; filename*=UTF-8''0%20%21%20%C2%A7%20%24%20%25%20%26%20%28%20%29%20%3D%20%60%20%C2%B4%20%7B%20%7D%20%20%20%20%5B%20%5D%20%C2%B2%20%C2%B3%20%40%20%E2%82%AC%20%C2%B5%20%5E%20%C2%B0%20~%20%2B%20%27%20%23%20-%20_%20.%20%2C%20%3B%20%C3%BC%20%C3%A4%20%C3%B6%20%C3%9F%209.jpg
I had the following results:
Status so far is, that the syntax filename*=UTF-8''filname escape sequence" works with every browser except Safari. And the only character that is getting replaced with Safari is the €. I guess I can live with that. Thank you!
I noticed some filename length issues.
Firefox, MSIE (starting with version 9), Opera, Konq and Chrome support; MSIE8 and Safari not support; others support is unknown - the encoding defined in RFC 5987.
Note that in
Content-Disposition: attachment; filename*=UTF-8''weird%20%23%20%80%20%3D%20%7B%20%7D%20%3B%20filename.txt
you got the encoding for the Euro character wrong; it's unicode code point is not %80, fixing this should make it work everywhere except Safari (the correct encoding being %e2%82%ac).
Test case at: