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
Вернуться на верх