Django FileResponse Content-Disposition заголовок не работает для имени файла
Я использую заголовок Content-Disposition, потому что хранимое имя файлов отличается от имени, с которым они обслуживаются. Но заголовок работает не во всех файлах корректно, я напрямую передаю имя файла в заголовок. Имена файлов содержат символы, отличные от символов ASCII.
Вот вид загрузки, который я использую:
@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
Вот правильный заголовок ответа, который мне нужен (имя файла не содержит символов, отличных от ASCII)
content-disposition: attachment; filename=jinekolojik aciller.ppt
Но некоторые файлы дают такие заголовки (оригинальное имя файла: 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?=
Я нашел решение для этого.
Я заметил, что когда имя содержит любой не легальный символ, 'Content Disposition' ответа путается и браузер не может получить имя файла из него.
Решением для меня было
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