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..
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..
Respuestas:
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
application/x-zip-compressed
zip
o rar
nada. De acuerdo con las especificaciones de WC3, esto se interpretará como: "Prefiero un application/zip
| application/x-rar-compressed
tipo de contenido, pero si no puede entregar esto, un application/octet-stream
(flujo de archivos) también está bien".
multipart/x-zip
ser 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.
Puede encontrar una lista oficial de los tipos mime en la Autoridad de Números Asignados de Internet (IANA) . Según su Content-Type
encabezado de lista para zip
es application/zip
.
El tipo de medio para rar
archivos 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-stream
significa 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 zip
o rar
tambié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-Type
encabezado. 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.
Si desea descargar un zip
archivo y nada más, solo debe establecer un único Accept
valor de encabezado. Cualquier valor adicional establecido se utilizará como reserva en caso de que el servidor no pueda satisfacerlo en el Accept
encabezado tipo mime solicitado.
De acuerdo con las especificaciones WC3 esto:
application/zip, application/octet-stream
se interpretará como: "Prefiero un application/zip
tipo 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 zip
archivo (o una 406 - Not Acceptable
respuesta en caso de que el servidor no pueda satisfacer su solicitud).
No debe confiar $_FILES['upfile']['mime']
, verifique el tipo MIME usted mismo. Para ese propósito, puede usar la fileinfo
extensió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.ini
y reiniciar su servidor:
extension=php_fileinfo.dll
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
}
}
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 '.'