Je développe un simple script de téléchargement php, et les utilisateurs ne peuvent télécharger que des fichiers Zip et RAR.
Quels types MIME je devrais utiliser pour vérifier $_FILES[x][type]
? (une liste complète s'il vous plaît)
Je vous remercie..
Les réponses de freedompeace, Kiyarash et Sam Vloeberghs:
.rar application/x-rar-compressed, application/octet-stream
.Zip application/Zip, application/octet-stream, application/x-Zip-compressed, multipart/x-Zip
Je voudrais aussi vérifier le nom du fichier. Voici comment vérifier si le fichier est un fichier RAR ou Zip. Je l'ai testé en créant une application rapide en ligne de commande.
<?php
if (isRarOrZip($argv[1])) {
echo 'It is probably a RAR or Zip file.';
} else {
echo 'It is probably not a RAR or Zip file.';
}
function isRarOrZip($file) {
// get the first 7 bytes
$bytes = file_get_contents($file, FALSE, NULL, 0, 7);
$ext = strtolower(substr($file, - 4));
// RAR magic number: Rar!\x1A\x07\x00
// http://en.wikipedia.org/wiki/RAR
if ($ext == '.rar' and bin2hex($bytes) == '526172211a0700') {
return TRUE;
}
// Zip magic number: none, though PK\003\004, PK\005\006 (empty archive),
// or PK\007\008 (spanned archive) are common.
// http://en.wikipedia.org/wiki/Zip_(file_format)
if ($ext == '.Zip' and substr($bytes, 0, 2) == 'PK') {
return TRUE;
}
return FALSE;
}
Notez que cela ne sera toujours pas certain à 100%, mais c'est probablement suffisant.
$ rar.exe l somefile.Zip
somefile.Zip is not RAR archive
Mais même WinRAR détecte les fichiers non RAR en tant qu’archives SFX:
$ rar.exe l somefile.srr
SFX Volume somefile.srr
Une liste officielle des types de mime est disponible sur Autorité IANA (Internet Assigned Numbers Authority) . Selon leur liste, Content-Type
, l'en-tête de Zip
est application/Zip
.
Le type de support pour les fichiers rar
n'est pas officiellement enregistré auprès de l'IANA, mais la valeur non officielle de type mime couramment utilisée est application/x-rar-compressed
.
application/octet-stream
signifie autant que: "Je vous envoie un flux de fichiers et le contenu de ce flux n'est pas spécifié" _ (il est donc vrai qu'il peut s'agir également d'un fichier Zip
ou rar
). Le serveur est censé détecter le contenu réel du flux.
Remarque: Pour le téléchargement, il n'est pas sûr de s'appuyer sur le type MIME défini dans l'en-tête Content-Type
. L'en-tête est défini sur le client et peut être défini sur n'importe quelle valeur aléatoire. À la place, vous pouvez utiliser les informations de fichier php functions pour détecter le type de fichier mime sur le serveur.
Si vous souhaitez télécharger un fichier Zip
et rien d'autre, vous ne devez définir qu'une seule valeur d'en-tête Accept
. Toute valeur supplémentaire définie sera utilisée comme solution de secours au cas où le serveur ne pourrait pas satisfaire votre type mime demandé dans l'en-tête Accept
.
Selon les spécifications WC3 this:
application/Zip, application/octet-stream
sera interprété comme: "Je préfère un type mime application/Zip
, mais si vous ne pouvez pas le fournir, un application/octet-stream
(un flux de fichier) convient également".
Donc, un seul:
application/Zip
Vous garantira un fichier Zip
(ou une réponse 406 - Not Acceptable
au cas où le serveur ne pourrait pas répondre à votre demande).
Vous ne devez pas faire confiance à $_FILES['upfile']['mime']
, vérifiez le type MIME vous-même. Pour cela, vous pouvez utiliser fileinfo
extension , activé par défaut à partir de PHP 5.3.0.
$fileInfo = new finfo(FILEINFO_MIME_TYPE);
$fileMime = $fileInfo->file($_FILES['upfile']['tmp_name']);
$validMimes = array(
'Zip' => 'application/Zip',
'rar' => 'application/x-rar',
);
$fileExt = array_search($fileMime, $validMimes, true);
if($fileExt != 'Zip' && $fileExt != 'rar')
throw new RuntimeException('Invalid file format.');
REMARQUE: N'oubliez pas d'activer l'extension dans votre php.ini
et de redémarrer votre serveur:
extension=php_fileinfo.dll
Dans une question liée , il existe du code Objective-C pour obtenir le type mime d'une URL de fichier. J'ai créé une extension Swift basée sur ce code Objective-C pour obtenir le type mime:
import Foundation
import MobileCoreServices
extension URL {
var mimeType: String? {
guard self.pathExtension.count != 0 else {
return nil
}
let pathExtension = self.pathExtension as CFString
if let preferredIdentifier = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, pathExtension, nil) {
guard let mimeType = UTTypeCopyPreferredTagWithClass(preferredIdentifier.takeRetainedValue(), kUTTagClassMIMEType) else {
return nil
}
return mimeType.takeRetainedValue() as String
}
return nil
}
}