Skip to content

Incompatibility of MimeTypeGuesserInterface implementation on Windows / fallback to fileinfo only #41

@BriceFab

Description

@BriceFab

Hello ,

We use the JoliCode\MediaBundle\Binary\MimeTypeGuesser class, which is constructed with:

new MimeTypeGuesser(
    MimeTypesInterface $mimeTypes,
    MimeTypeGuesserInterface $mimeTypeGuesser
)

On Windows the injected MimeTypeGuesserInterface resolves to Symfony\Component\Mime\FileBinaryMimeTypeGuesser, whose isGuesserSupported() returns false on Windows (because DIRECTORY_SEPARATOR === '\\') — hence the exception:

The "Symfony\Component\Mime\FileBinaryMimeTypeGuesser" guesser is not supported.

Image

While we can work around this by injecting only MimeTypesInterface and bypassing MimeTypeGuesserInterface, it would be helpful if the bundle either:

  • Detected Windows and defaulted to MimeTypesInterface::guessMimeType() (via fileinfo) automatically, or
  • Provided configuration option to disable binary-based guesser and force fileinfo fallback, or
  • Documented the Windows limitation clearly in the README.

Environnement

  • OS: Windows
  • PHP version: 8.2
  • Symfony version: 7.4
  • JoliMediaBundle version: v0.1.1

Expected
The bundle should run seamlessly on Windows by using fileinfo-based detection rather than fail with unsupported binary guesser.

Actual
Exception thrown by FileBinaryMimeTypeGuesser::guessMimeType() when used on Windows.

Suggested improvement

  1. Update MimeTypeGuesser class to check isGuesserSupported() and if false fallback to $this->mimeTypes->guessMimeType().
  2. Add config option e.g. joli_media.mime_type.guesser: fileinfo_only or similar.
  3. Add documentation note about Windows behaviour.

Working example on Windows
Replacing the bundle’s MimeTypeGuesser implementation with the following version works correctly on Windows, as it relies exclusively on MimeTypesInterface::guessMimeType() (which uses the PHP fileinfo extension):

<?php

namespace JoliCode\MediaBundle\Binary;

// use Symfony\Component\Mime\MimeTypeGuesserInterface;
use Symfony\Component\Mime\MimeTypesInterface;

class MimeTypeGuesser
{
    public function __construct(
        private readonly MimeTypesInterface $mimeTypes,
        // private readonly MimeTypeGuesserInterface $mimeTypeGuesser,
    ) {
    }

    public function getPossibleExtension(string $mimeType): string
    {
        $possibleExtensions = $this->mimeTypes->getExtensions($mimeType);

        return $possibleExtensions[0] ?? $mimeType;
    }

    public function guessMimeTypeFromContent(string $content): string
    {
        $temporaryFile = tempnam(sys_get_temp_dir(), 'media');
        file_put_contents($temporaryFile, $content);
        //$mimeType = $this->mimeTypeGuesser->guessMimeType($temporaryFile);
        $mimeType = $this->mimeTypes->guessMimeType($temporaryFile);
        unlink($temporaryFile);

        return $mimeType ?? 'application/octet-stream';
    }
}

Thank

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions