Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django: Unicode Filenames with ASCII headers?

I have a list of strangely encoded files: 02 - Charlie, Woody and You/Study #22.mp3 which I suppose isn't so bad but there are a few particular characters which Django OR nginx seem to be snagging on.

>>> test = u'02 - Charlie, Woody and You/Study #22.mp3'
>>> test
u'02 - Charlie, Woody and You\uff0fStudy #22.mp3'

I am using nginx as a reverse proxy to connect to django's built in webserver (still in development stages) and postgresql for my database. My database and tables are all en_US.UTF-8 and I am using pgadmin3 to view my tables outside of django. My issue goes a little beyond my title, firstly how should I be saving possibly whacky filenames in my database? My current method is

'path': smart_unicode(path.lstrip(MUSIC_PATH)),
'filename': smart_unicode(file)

and when I pprint out the values they do show u'whateverthecrap'

I am not sure if that is how I should be doing it but assuming it is now I have issues trying to spit out the download.

My download view looks something like this:

def song_download(request, song_id):
    song = get_object_or_404(Song, pk=song_id)
    url = u'/static_music/%s/%s' % (song.path, song.filename)

    print url

    response = HttpResponse()
    response['X-Accel-Redirect'] = url
    response['Content-Type'] = 'audio/mpeg'
    response['Content-Disposition'] = "attachment; filename=test.mp3"

    return response

and most files will download but when I get to 02 - Charlie, Woody and You/Study #22.mp3 I receive this from django: 'ascii' codec can't encode character u'\uff0f' in position 118: ordinal not in range(128), HTTP response headers must be in US-ASCII format.

How can I use an ASCII acceptable string if my filename is out of bounds? 02 - Charlie, Woody and You\uff0fStudy #22.mp3 doesn't seem to work...

EDIT 1

I am using Ubuntu for my OS.

like image 748
TheLizardKing Avatar asked Feb 28 '23 02:02

TheLizardKing


1 Answers

Although is an unusual and undesirable character, your script will break for any non-ASCII character.

response['X-Accel-Redirect'] = url

url is Unicode (and it isn't a URL, it's a filepath). Response headers are bytes. You'll need to encode it.

response['X-Accel-Redirect'] = url.encode('utf-8')

that's assuming you're running on a server with UTF-8 as the filesystem encoding.

(Now, how to encode the filename in the Content-Disposition header... that's an altogether trickier question!)

like image 69
bobince Avatar answered Mar 05 '23 16:03

bobince