views:

1243

answers:

5

Hi, I have problem with HTTP headers, they're encoded in ASCII and I want to provided a view for downloading files that names can be non ASCII.

response['Content-Disposition'] = 'attachment; filename="%s"' % (vo.filename.encode("ASCII","replace"), )

I don't want to use static files serving for same issue with non ASCII file names but in this case there would be a problem with File system and it's file name encoding. (I don't know target os.)

I've already tried urllib.quote(), but it raises KeyError exception.

Possibly I'm doing something wrong but maybe it's impossible.

+11  A: 

This is a FAQ.

There is no interoperable way to do this. Some browsers implement proprietary extensions (IE, Chrome), other implement RFC 2231 (Firefox, Opera).

See test cases at http://greenbytes.de/tech/tc2231/.

Julian Reschke
Thanks! Easiest things are the hardest to find ;)
Chris Ciesielski
More recently, Julian has put together a profile of RFC2231 for this purpose: http://datatracker.ietf.org/doc/draft-reschke-rfc2231-in-http/
Mark Nottingham
Now published as http://greenbytes.de/tech/webdav/rfc5987.html
Julian Reschke
A: 

Some browsers support Url Encoding (aka Percent Encoding) in headers.

gimel
A: 

Take a look at this snippets to encode non ascii filenames http://www.djangosnippets.org/snippets/1710/

Pierre-Jean Coudert
+3  A: 

Don't send a filename in Content-Disposition. There is no way to make non-ASCII header parameters work cross-browser(*).

Instead, send just “Content-Disposition: attachment”, and leave the filename as a URL-encoded UTF-8 string in the trailing (PATH_INFO) part of your URL, for the browser to pick up and use by default. UTF-8 URLs are handled much more reliably by browsers than anything to do with Content-Disposition.

(*: actually, there's not even a current standard that says how it should be done as the relationships between RFCs 2616, 2231 and 2047 are pretty dysfunctional, something that Julian is trying to get cleared up at a spec level. Consistent browser support is in the distant future.)

bobince
The top answer contains some great information, but you've actually solved the problem. Thanks!
Brandon Bloom
Great answer...
cherouvim
@Brandon I totally agree. Sadly, this answer has fewer votes, and is not the accepted one (at least as of now). On the other hand, the link provided in Julian's answer is pretty valuable.
allyourcode
A: 

A hack:

if (Request.UserAgent.Contains("IE"))
{
  // IE will accept URL encoding, but spaces don't need to be, and since they're so common..
  filename = filename.Replace("%", "%25").Replace(";", "%3B").Replace("#", "%23").Replace("&", "%26");
}
anon