Skip to content

BinaryFileResponse attachment doesn't work with non-ascii filenames #16603

@Yannik

Description

@Yannik

Hi everyone,

at the moment, it is impossible to create a BinaryFileResponse with a file which has a non-ascii filename:

<?php
function test_can_create_utf8_file_attachment_response() {
    touch('Täst');
    new Symfony\Component\HttpFoundation\BinaryFileResponse('Täst', 200, [], true, 'attachment');
}

This results in a InvalidArgumentException with message 'The filename fallback must only contain ASCII characters.'

The stacktrace for the exception is:

#0 symfony\http-foundation\BinaryFileResponse.php(161): Symfony\Component\HttpFoundation\ResponseHeaderBag->makeDisposition('attachment', 'T\xC3\xA4st', '')
#1 symfony\http-foundation\BinaryFileResponse.php(110): Symfony\Component\HttpFoundation\BinaryFileResponse->setContentDisposition('attachment')
#2 symfony\http-foundation\BinaryFileResponse.php(50): Symfony\Component\HttpFoundation\BinaryFileResponse->setFile('T\xC3\xA4st', 'attachment', false, true)
#3 test.php(3) : Symfony\Component\HttpFoundation\BinaryFileResponse->__construct('T\xC3\xA4st', 200, Array, true, 'attachment')

However, it is not possible to instantiate a BinaryFileResponse and pass a filename fallback.
In fact, when setContentDisposition is called without a fallback filename (as is done by setFile), according to the DocBlock:

     * @param string $filenameFallback A fallback filename, containing only ASCII characters. Defaults to an automatically encoded filename

the fallback filename should default to a automatically created ascii version.
However, this does not happen:

    public function  setContentDisposition($disposition, $filename = '', $filenameFallback = '')
    {
        if ($filename === '') {
            $filename = $this->file->getFilename();
        }

        $dispositionHeader = $this->headers->makeDisposition($disposition, $filename, $filenameFallback);
    }

$filenameFallback is just left to be a empty string.
makeDisposition then sets the fallback filename to the (possibly utf8) filename gotten though getFilename():

        if ('' == $filenameFallback) {
            $filenameFallback = $filename;
        }

which then causes the exception.

Possible solutions:

  1. Let setContentDisposition act as it's docblock describes and set the fallback filename to an automatically encoded version of the filename if no other fallback filename is given
  2. Pass filename and fallback filename in the constructur and change the docblock of setContentDisposition
  3. both

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions