arquivos .rar, .zip Tipo MIME

156

Estou desenvolvendo um script de upload php simples, e os usuários podem fazer upload apenas de arquivos ZIP e RAR.

Quais tipos MIME devo usar para verificar $_FILES[x][type]? (uma lista completa, por favor)

Obrigado..

mrdaliri
fonte
Eu quero permitir todos os arquivos compactados sozinhos (rar, zip, tar.gz, jar etc), qual é o procedimento?
Ridhuvarshan

Respostas:

258

As respostas de freedompeace, Kiyarash e Sam Vloeberghs:

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

Eu também verificaria o nome do arquivo. Aqui está como você pode verificar se o arquivo é um arquivo RAR ou ZIP. Testei-o criando um aplicativo rápido de linha de comando.

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

Observe que ainda não será 100% certo, mas provavelmente é bom o suficiente.

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

Mas até o WinRAR detecta arquivos não RAR como arquivos SFX:

$ rar.exe l somefile.srr
SFX Volume somefile.srr
Gfy
fonte
2
multipart / x-zip é um tipo MIME válido para .zip bem (arquivo PKZIP)
Sam Vloeberghs
13
na verdade, há um outro tipo de MIME para zip, e que é:application/x-zip-compressed
Kiyarash
Isso não garante um arquivo zipou rararquivo. De acordo com as especificações do WC3, isso será interpretado como: "Prefiro um application/zip| application/x-rar-compressedtipo de conteúdo, mas se você não puder entregar isso, um application/octet-stream(fluxo de arquivos) também será bom".
Wilt
1
Aqui está uma lista útil de tipos MIME com .zip entre outros: sitepoint.com/web-foundations/mime-types-complete-list
sstauross
1
Como no mundo poderia multipart/x-zipser válido? Não é multi-parte. A lista SitePoint contém muitos tipos MIME imprecisos e está longe de ser concluída. O registro oficial de tipos de mídia da IANA não está (e provavelmente nunca estará) 100% completo.
precisa saber é o seguinte
35

Para upload:

Uma lista oficial de tipos de mímica pode ser encontrada na IANA (Autoridade de números atribuídos à Internet) . De acordo com o Content-Typecabeçalho da lista de zipis application/zip.

O tipo de mídia dos rararquivos não está registrado oficialmente na IANA, mas o valor não oficial do tipo MIME comumente usado éapplication/x-rar-compressed .

application/octet-streamsignifica tanto quanto: "Enviei a você um fluxo de arquivos e o conteúdo desse fluxo não foi especificado" (é verdade que também pode ser um arquivo zipou rar). O servidor deve detectar qual é o conteúdo real do fluxo.

Nota: Para upload, não é seguro confiar no tipo MIME definido no Content-Typecabeçalho. O cabeçalho é definido no cliente e pode ser definido como qualquer valor aleatório. Em vez disso, você pode usar as funções de informações do arquivo php para detectar o tipo mime de arquivo no servidor.


Para download:

Se você deseja baixar um ziparquivo e nada mais, defina apenas um único Acceptvalor de cabeçalho. Quaisquer valores adicionais configurados serão usados ​​como reserva, caso o servidor não possa satisfazer o seu noAccept tipo de mime solicitado cabeçalho.

De acordo com as especificações do WC3, isto:

application/zip, application/octet-stream 

será interpretado como: "Prefiro um application/ziptipo MIME, mas se você não puder entregar isso, um application/octet-stream(um fluxo de arquivos) também será bom".

Portanto, apenas um:

application/zip

Garantirá um ziparquivo (ou uma 406 - Not Acceptableresposta, caso o servidor não consiga atender à sua solicitação).

Wilt
fonte
5

Você não deve confiar $_FILES['upfile']['mime'], verifique o tipo MIME sozinho. Para esse propósito, você pode usar a fileinfoextensão , habilitada por padrão a partir do 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: Não se esqueça de ativar a extensão no seu php.inie reiniciar o servidor:

extension=php_fileinfo.dll
fibriZo raZiel
fonte
0

Em uma pergunta vinculada , há algum código Objective-C para obter o tipo mime para uma URL de arquivo. Eu criei uma extensão Swift com base no código Objective-C para obter o 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
fonte
-2

Como a extensão pode conter mais ou menos que três caracteres, o seguinte testará uma extensão, independentemente do seu comprimento.

Tente o seguinte:

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

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

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

para verificar todos os caracteres após o último '.'

theking2
fonte