web-dev-qa-db-fra.com

Pourquoi la méthode getMimeType () de Laravel identifie-t-elle un fichier comme "application / octet-stream" alors que le fichier a l'attribut type "audio / mpeg"?

J'essaie de télécharger un fichier MP3 dans une application Laravel et j'ai rencontré un problème où même si le fichier a un attribut défini sur "audio/mpeg", il est téléchargé en tant qu'application "/octet-stream "(.bin). Lorsque j'essaie de mourir et de vider le fichier sur le code côté serveur avec:

dd($request->file('file'));

Je reçois:

UploadedFile {#187 ▼
  -test: false
  -originalName: "CUS12309821-20-AUG-2016-13-48-13.mp3"
  -mimeType: "audio/mpeg"
  -size: 47000471
  -error: 0
  path: "/private/var/folders/c7/6ws0lxy95dd_lhz1k067_zkc0000gn/T"
  filename: "phpyZCsbU"
  basename: "phpyZCsbU"
  pathname: "/private/var/folders/c7/6ws0lxy95dd_lhz1k067_zkc0000gn/T/phpyZCsbU"
  extension: ""
  realPath: "/private/var/folders/c7/6ws0lxy95dd_lhz1k067_zkc0000gn/T/phpyZCsbU"
  aTime: 2016-09-20 12:56:00
  mTime: 2016-09-20 12:56:00
  cTime: 2016-09-20 12:56:00
  inode: 4565593
  size: 47000471
  perms: 0100600
  owner: 501
  group: 20
  type: "file"
  writable: true
  readable: true
  executable: false
  file: true
  dir: false
  link: false
}

Regardez comment lorsque j'utilise cette méthode, cela dit en effet que l'attribut de fichier pour mimeType est le format "audio/mpeg" correct. Cependant, lorsque j'appelle la méthode getMimeType () sur le fichier après son téléchargement, j'obtiens:

"application/octet-stream"

Voici le code de la méthode routée:

/**
 * Store a newly created resource in storage.
 *
 * @param  \Illuminate\Http\Request  $request
 * @return \Illuminate\Http\Response
 */
public function store(Request $request)
{
    $file = $request->all();

    $filePath = Storage::putFile('file', $request->file('files'));

    dd($request->file('file')->getMimeType());

    $file['path'] = Storage::url($filePath);
    $file['size'] = Storage::size($filePath);
    $file['type'] = $request->file('file')->getMimeType();

    return $file;
}

Ce problème est apparemment unique en ce sens que j'utilise le cadre Laravel, où d'autres personnes ayant ce problème utilisent Vanilla PHP. De plus, le fichier Excel que d'autres peuvent nous avoir signalé comme une application/octet-stream au lieu d'un fichier Excel. Enfin, je pense que cela peut être un problème avec la méthode guess (), qui est appelée par le getMethodType (). Quelqu'un avec plus Laravel expérience pourrait probablement confirmez cela.

15
Kirkland

L'objet UploadedFile est finalement étendu à partir de Symfony\Component\HttpFoundation\File\UploadedFile Qui obtient/définit le mimeType à partir de The type of the file as provided by PHP.

Pour accéder à ce mimeType, vous devez appeler $file->getClientMimeType()

Cependant, dans le docblock Symfony pour la fonction, il suggère:

Le type MIME client est extrait de la demande à partir de laquelle le fichier a été téléchargé, il ne doit donc pas être considéré comme une valeur sûre.

Pour un type MIME approuvé, utilisez plutôt getMimeType () (qui devine le type MIME en fonction du contenu du fichier).

Dans votre cas cependant $file->getMimeType() qui devrait être approuvé et devine le type mime à partir du contenu, mais il retourne quelque chose comme s'il ne pouvait pas déterminer le type mime, étant "application/octet-stream"

Informations supplémentaires

Pour vous aider à décider. Fondamentalement, getClientMimeType() retournerait le type MIME défini par le navigateur.

L'appel getMimeType devine le type mime en utilisant deux techniques différentes que je peux voir:

  1. Utilisation d'une technique de type mime binaire en regardant la sortie de la commande suivante file -b --mime %s 2>/dev/null Si elle est prise en charge.

  2. La deuxième technique utilise la commande finfo_open Si elle existe à l'intérieur de php.

Si les deux 1. et 2. existent sur votre système, d'après ce que je vois 2. aura la préférence, et 1. sera la solution de rechange.

Personnellement, je préférerais les résultats de getMimeType() pour des raisons de sécurité. Cependant, ce serait une autre question intéressante à se poser "Quelle est la fiabilité de la détection de type mime du navigateur et quelles techniques sont utilisées" :-)

exemple mis à jour

J'inclus un exemple pour vous.

Pour moi faisant une vérification sur un "DropboxInstalled.dmg", voici mes résultats:

  1. l'utilisation de file -b --mime DropboxInstaller.dmg à partir d'une ligne de commande (terminal) renvoie application/octet-stream

  2. en utilisant la fonctionnalité finfo_open

$finfo = new \finfo(FILEINFO_MIME_TYPE);
echo $finfo->file('./DropboxInstaller.dmg');

renvoie application/x-iso9660-image

16
Leon Vismer

J'avais ce problème avec Laravel 5.4. J'ai résolu en définissant post_max_size et upload_max_filesize dans mon php.ini à une valeur supérieure.

Après cela, j'ai dû faire un redémarrage dur d'OSX avant qu'il ne se reflète correctement dans l'application.

6
james2doyle