I use the Content-Disposition header because the stored name of the files is different from the name they are served. But header not working in all files correctly, i'm directly passing filename to header. Filenames contains non-ASCII characters.
Here is the download view i'm using:
@api_view(['GET'])
def download_streamer(request, **kwargs):
dlo = DownloadLink.objects.get(token=kwargs['token'])
if dlo.is_expired:
return Response({'link_expired': 'Download link expired, try again'},
status=status.HTTP_410_GONE)
else:
mimetype, _ = mimetypes.guess_type(dlo.file_cache.stored_at)
f_response = FileResponse(open(dlo.file_cache.stored_at, 'rb'), content_type=mimetype)
f_response['Content-Disposition'] = f'attachment; filename={dlo.file_cache.origin.name}'
f_response['Access-Control-Expose-Headers'] = 'Content-Disposition'
FileActivity.objects.create(subject=dlo.file_cache.origin, action='GET', user=dlo.owner)
return f_response
Here is the valid response header which i want (file name not containing non-ASCII chars)
content-disposition: attachment; filename=jinekolojik aciller.ppt
But some files gives this headers (original filename: türkiyede sağlık politikaları.pdf)
content-disposition: =?utf-8?q?attachment=3B_filename=3Dt=C3=BCrkiyede_sa=C4=9Fl=C4=B1k_politikalar=C4=B1=2Epdf?=
I've found a solution for this.
I noticed that when name contains any non legal character response's 'Content Disposition' guess messed up and the browser cannot get the file name out of it.
solution for me was
from django.utils.text import slugify
@api_view(['GET'])
def download_streamer(request, **kwargs):
dlo = DownloadLink.objects.get(token=kwargs['token'])
if dlo.is_expired:
return Response({'link_expired': 'Download link expired, try again'},
status=status.HTTP_410_GONE)
else:
mimetype, _ = mimetypes.guess_type(dlo.file_cache.stored_at)
f_response = FileResponse(open(dlo.file_cache.stored_at, 'rb'), content_type=mimetype)
f_response['Content-Disposition'] = f'attachment; filename={slugify(dlo.file_cache.origin.name)}'
f_response['Access-Control-Expose-Headers'] = 'Content-Disposition'
FileActivity.objects.create(subject=dlo.file_cache.origin, action='GET', user=dlo.owner)
return f_response