Skip to content

[HttpFoundation] Fix BinaryFileResponse content type detection logic #47746

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

X-Coder264
Copy link
Contributor

@X-Coder264 X-Coder264 commented Sep 30, 2022

Q A
Branch? 4.4
Bug fix? yes
New feature? no
Deprecations? no
Tickets -
License MIT
Doc PR -

I've just upgraded to 5.4.13 (from 5.4.8) and a lot of my tests started failing. Upon further debugging I've found the issue to be caused by #47516

Prior to that PR

        if (!$this->headers->has('Content-Type')) {
            $this->headers->set('Content-Type', $this->file->getMimeType() ?: 'application/octet-stream');
        }

was called before the parent::prepare($request); call.

After that PR parent::prepare($request); was called first and that would call

            // Content-type based on the Request
            if (!$headers->has('Content-Type')) {
                $format = $request->getRequestFormat(null);
                if (null !== $format && $mimeType = $request->getMimeType($format)) {
                    $headers->set('Content-Type', $mimeType);
                }
            }

which would set the content type from the request so by the time

        if (!$this->headers->has('Content-Type')) {
            $this->headers->set('Content-Type', $this->file->getMimeType() ?: 'application/octet-stream');
        }

is executed again in the BinaryFileResponse prepare method that if statement never evaluates to true because the Content-Type header was already set (to the wrong one).

This PR fixes this issue by making sure the order of the method calls is correct.

@X-Coder264 X-Coder264 force-pushed the fix-binary-file-response-content-type-detection-logic branch from 2555feb to 87f58ae Compare September 30, 2022 14:31
@fabpot
Copy link
Member

fabpot commented Sep 30, 2022

Thank you @X-Coder264.

@fabpot fabpot merged commit a91e213 into symfony:4.4 Sep 30, 2022
@X-Coder264 X-Coder264 deleted the fix-binary-file-response-content-type-detection-logic branch September 30, 2022 16:04
@junowilderness
Copy link
Contributor

@X-Coder264 Our automated tests detected this one also. You found the root cause faster than I did. Thank you.

@alcohol
Copy link
Contributor

alcohol commented Oct 4, 2022

Heh just ran into this one today when upgrading from 4.4.45 to 4.4.46; added a conflict rule for now to our composer.json - cheers for the quick fix!

@Trismegiste
Copy link

Trismegiste commented Oct 5, 2022

Same problem here with an upgrade from 5.4.11 to 5.4.13

With this simple controller which should return a PNG :

 /** @Route("/yolo") */
    public function yolo()
    {
        return new BinaryFileResponse('/www/var/storage/test/yolo.png');
    }

I get this :
image

The content-type of the picture is text/html; charset=UTF-8

It works OK when the picture is in a html page (the browser is fixing the faulty content-type on the fly) but my functional tests do not pass.

If I force the content-type with a return new BinaryFileResponse('/www/var/storage/test/yolo.png', 200, ['content-type' => 'image/png']); it works.

Will this fix be released in 5.4.14 ?

@xabbuh
Copy link
Member

xabbuh commented Oct 6, 2022

Will this fix be released in 5.4.14 ?

yes

@gimler
Copy link
Contributor

gimler commented Oct 6, 2022

@Trismegiste i had the same problem quick fix manual add mime type

/** @Route("/yolo") */
public function yolo()
{
    $response = new BinaryFileResponse('/www/var/storage/test/yolo.png');

    $mimeTypes = new MimeTypes();
    $mimeType = $mimeTypes->guessMimeType('/www/var/storage/test/yolo.png');
    $response->headers->set('Content-Type', $mimeType);

    return $response;
}

@Trismegiste
Copy link

yes

Thank you @xabbuh

@Trismegiste i had the same problem quick fix manual add mime type

Thank you @gimler but I think I'll keep 5.4.11 and upgrade later

@derrabus
Copy link
Member

derrabus commented Oct 6, 2022

Thank you @gimler but I think I'll keep 5.4.11 and upgrade later

… or use "symfony/http-foundation": "~5.4.14@dev" as version constraint for the time being. This way you can verify that the upcoming release will address your issue.

@marin246
Copy link

When will this be released?

@xabbuh
Copy link
Member

xabbuh commented Oct 11, 2022

Patch releases happen once per month.

@X-Coder264
Copy link
Contributor Author

Is there an exception to that? This is not some rare/small/obscure issue, this is a pretty big issue with a lot of impact as almost every project uses the BinaryFileResponse which can be seen by the amount of bug reports that are constantly being opened all over the place (here, on Symfony community bundles, on the Laravel framework repo etc.).

Honestly I was a bit surprised that a new patch version was not released immediately after the fix was merged.

@xabbuh
Copy link
Member

xabbuh commented Oct 12, 2022

releases for all maintained versions containing this fixed have just been released

@Trismegiste
Copy link

Tested right now.
5.4.14 release fixed my problem with BinaryFileResponse
Thanks ❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.