.rar, archivos .zip Tipo MIME

156

Estoy desarrollando una secuencia de comandos de carga php simple, y los usuarios solo pueden cargar archivos ZIP y RAR.

¿Qué tipos de MIME debo usar para verificar $_FILES[x][type]? (una lista completa por favor)

Gracias..

mrdaliri
fuente
Quiero permitir todos los archivos comprimidos solos (rar, zip, tar.gz, jar, etc.), ¿cuál es el procedimiento?
Ridhuvarshan

Respuestas:

258

Las respuestas de freedompeace, Kiyarash y Sam Vloeberghs:

.rar    application/x-rar-compressed, application/octet-stream
.zip    application/zip, application/octet-stream, application/x-zip-compressed, multipart/x-zip

También verificaría el nombre del archivo. A continuación, le mostramos cómo puede verificar si el archivo es un archivo RAR o ZIP. Lo probé creando una aplicación de línea de comandos rápida.

<?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;
}

Tenga en cuenta que todavía no será 100% seguro, pero probablemente sea lo suficientemente bueno.

$ rar.exe l somefile.zip
somefile.zip is not RAR archive

Pero incluso WinRAR detecta archivos no RAR como archivos SFX:

$ rar.exe l somefile.srr
SFX Volume somefile.srr
Gfy
fuente
2
multipart / x-zip es un tipo MIME válido para .zip también (archivo PKZIP)
Sam Vloeberghs
13
en realidad hay otro TIPO MIME para zip, y ese es:application/x-zip-compressed
Kiyarash
Esto no le garantizará un archivo zipo rarnada. De acuerdo con las especificaciones de WC3, esto se interpretará como: "Prefiero un application/zip| application/x-rar-compressedtipo de contenido, pero si no puede entregar esto, un application/octet-stream(flujo de archivos) también está bien".
Marchitez
1
Aquí hay una lista útil de tipos mime con .zip, entre otros: sitepoint.com/web-foundations/mime-types-complete-list
sstauross
1
¿Cómo podría multipart/x-zipser válido en el mundo ? No es de varias partes. La lista de SitePoint contiene muchos tipos MIME inexactos y está lejos de estar completa. El registro oficial de tipos de medios de la IANA no está (ni probablemente lo estará) 100% completo.
Suncat2000
35

Para subir:

Puede encontrar una lista oficial de los tipos mime en la Autoridad de Números Asignados de Internet (IANA) . Según su Content-Typeencabezado de lista para zipes application/zip.

El tipo de medio para rararchivos no está registrado oficialmente en IANA, pero el valor no oficial de tipo mime comúnmente utilizado sí lo es application/x-rar-compressed.

application/octet-streamsignifica tanto como: "Te envío una secuencia de archivos y el contenido de esta secuencia no está especificado" (por lo que es cierto que puede ser un archivo zipo rartambién). Se supone que el servidor detecta cuál es el contenido real de la transmisión.

Nota: Para cargar, no es seguro confiar en el tipo mime establecido en el Content-Typeencabezado. El encabezado se establece en el cliente y se puede establecer en cualquier valor aleatorio. En su lugar, puede usar las funciones de información del archivo php para detectar el tipo mime en el servidor.


Para descargar:

Si desea descargar un ziparchivo y nada más, solo debe establecer un único Acceptvalor de encabezado. Cualquier valor adicional establecido se utilizará como reserva en caso de que el servidor no pueda satisfacerlo en el Acceptencabezado tipo mime solicitado.

De acuerdo con las especificaciones WC3 esto:

application/zip, application/octet-stream 

se interpretará como: "Prefiero un application/ziptipo mime, pero si no puede entregar esto, un application/octet-stream(una secuencia de archivos) también está bien".

Entonces solo uno:

application/zip

Le garantizará un ziparchivo (o una 406 - Not Acceptablerespuesta en caso de que el servidor no pueda satisfacer su solicitud).

Marchitar
fuente
5

No debe confiar $_FILES['upfile']['mime'], verifique el tipo MIME usted mismo. Para ese propósito, puede usar la fileinfoextensión , habilitada por defecto a 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.');

NOTA: No olvide habilitar la extensión en su php.iniy reiniciar su servidor:

extension=php_fileinfo.dll
raziel fibriZo
fuente
0

En una pregunta vinculada , hay un código Objective-C para obtener el tipo mime para una URL de archivo. He creado una extensión Swift basada en ese código Objective-C para obtener el tipo 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
fuente
-2

Como la extensión puede contener más o menos de tres caracteres, lo siguiente probará una extensión, independientemente de su longitud.

Prueba esto:

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

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

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

para buscar todos los caracteres después del último '.'

theking2
fuente