.rar, fichiers .zip Type MIME

156

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 dois-je utiliser pour vérifier $_FILES[x][type]? (une liste complète s'il vous plaît)

Je vous remercie..

mrdaliri
la source
Je veux autoriser tous les fichiers compressés seuls (rar, zip, tar.gz, jar, etc.), quelle est la procédure?
Ridhuvarshan

Réponses:

258

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 ferais aussi une vérification sur le nom du fichier. Voici comment vous pouvez vérifier si le fichier est un fichier RAR ou ZIP. Je l'ai testé en créant une application de ligne de commande rapide.

<?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 ce n'est toujours pas sûr à 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
Gfy
la source
2
multipart / x-zip est également un type MIME valide pour .zip (archive PKZIP)
Sam Vloeberghs
13
en fait, il y a un autre TYPE MIME pour zip, et c'est:application/x-zip-compressed
Kiyarash
Cela ne vous garantira pas du tout un fichier zipou rar. Selon les spécifications WC3, cela sera interprété comme suit: "Je préfère un type de contenu application/zip| application/x-rar-compressed, mais si vous ne pouvez pas fournir cela, un application/octet-stream(flux de fichiers) est également très bien".
Wilt
1
Voici une liste utile des types de mime avec .zip entre autres: sitepoint.com/web-foundations/mime-types-complete-list
sstauross
1
Comment dans le monde pourrait multipart/x-zip-il être valable? Ce n'est pas en plusieurs parties. La liste SitePoint contient de nombreux types MIME inexacts et elle est loin d'être complète. Le registre officiel des types de médias IANA n'est pas (et ne le sera probablement jamais) complet à 100%.
Suncat2000
35

Pour le téléchargement:

Une liste officielle des types de mime est disponible sur The Internet Assigned Numbers Authority (IANA) . Selon leur en- Content-Typetête de liste pour zipest application/zip.

Le type de support pour les rarfichiers n'est pas officiellement enregistré auprès de l'IANA, mais la valeur de type mime couramment utilisée non officielle l'est application/x-rar-compressed.

application/octet-streamsignifie autant que: "Je vous envoie un flux de fichier et le contenu de ce flux n'est pas spécifié" (il est donc vrai qu'il peut s'agir d'un fichier zipou raraussi). 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- Content-Typetête. L'en-tête est défini sur le client et peut être défini sur n'importe quelle valeur aléatoire. Au lieu de cela, vous pouvez utiliser les fonctions d' informations de fichier php pour détecter le fichier de type mime sur le serveur.


Pour télécharger:

Si vous souhaitez télécharger un zipfichier et rien d'autre, vous ne devez définir qu'une seule Acceptvaleur d'en-tête. Toute valeur supplémentaire définie sera utilisée comme solution de secours au cas où le serveur ne peut pas satisfaire votre dans l'en- Accepttête demandé de type mime.

Selon les spécifications WC3 ceci:

application/zip, application/octet-stream 

sera interprété comme: "Je préfère un application/ziptype mime, mais si vous ne pouvez pas fournir cela, un application/octet-stream(un flux de fichiers) est également très bien".

Donc un seul:

application/zip

Vous garantira un zipfichier (ou une 406 - Not Acceptableréponse au cas où le serveur ne serait pas en mesure de satisfaire votre demande).

Se flétrir
la source
5

Vous ne devriez pas faire confiance $_FILES['upfile']['mime'], vérifiez le type MIME par vous-même. Pour cela, vous pouvez utiliser l' fileinfoextension , activée 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.iniet redémarrez votre serveur:

extension=php_fileinfo.dll
fibriZo raZiel
la source
0

Dans une question liée , il y a 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
    }
}
Wolfgang Schreurs
la source
-2

Étant donné que l'extension peut contenir plus ou moins de trois caractères, ce qui suit testera une extension quelle que soit sa longueur.

Essaye ça:

$allowedExtensions = array( 'mkv', 'mp3', 'flac' );

$temp = explode(".", $_FILES[$file]["name"]);
$extension = strtolower(end($temp));

if( in_array( $extension, $allowedExtensions ) ) { ///

pour vérifier tous les caractères après le dernier "."

theking2
la source