web-dev-qa-db-ja.com

.rar、.ZipファイルMIMEタイプ

シンプルなphpアップロードスクリプトを開発しています。ユーザーはZipファイルとRARファイルのみをアップロードできます。

$_FILES[x][type]の確認に使用するMIMEタイプは何ですか? (完全なリストをご覧ください)

ありがとうございました..

127
mrdaliri

フリーダムピース、キヤラシュ、サム・ヴロバーグの回答:

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

ファイル名もチェックします。ファイルがRARまたはZipファイルであるかどうかを確認する方法は次のとおりです。クイックコマンドラインアプリケーションを作成してテストしました。

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

それでも100%確実ではないことに注意してください。しかし、おそらくそれで十分です。

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

ただし、WinRARでさえ、非RARファイルをSFXアーカイブとして検出します。

$ rar.exe l somefile.srr
SFX Volume somefile.srr
220
Gfy

アップロードの場合:

MIMEタイプの公式リストは The Internet Assigned Numbers Authority(IANA) にあります。リストによると、ZipContent-Typeヘッダーはapplication/Zipです。

rarファイルのメディアタイプはIANAで正式に登録されていませんが、一般的に使用される非公式のmime-type値はapplication/x-rar-compressedです。

application/octet-streamは次のことを意味します: "ファイルストリームを送信しますが、このストリームのコンテンツは指定されていません"(したがって、Zipまたはrarファイルにできることは事実ですまあ)。サーバーは、ストリームの実際のコンテンツを検出することになっています。

注:アップロードの場合、Content-Typeヘッダーに設定されているMIMEタイプに依存することは安全ではありません。ヘッダーはクライアントに設定され、任意のランダムな値に設定できます。代わりに、 phpファイル情報 関数を使用して、サーバー上のファイルmime-typeを検出できます。


ダウンロード用:

Zipファイルをダウンロードし、他に何もダウンロードしたくない場合は、1つのAcceptヘッダー値のみを設定する必要があります。追加の値セットは、サーバーがAcceptヘッダーでリクエストされたmime-typeで満たすことができない場合のフォールバックとして使用されます。

WC3仕様 これによると:

application/Zip, application/octet-stream 

「私はapplication/Zip mime-typeを好みますが、これを配信できない場合はapplication/octet-stream(ファイルストリーム)も問題ありません」

したがって、単一の:

application/Zip

Zipファイル(またはサーバーが要求を満たすことができない場合は406 - Not Acceptable応答)を保証します。

29
Wilt

$_FILES['upfile']['mime']を信頼すべきではありません。自分でMIMEタイプを確認してください。そのために、 fileinfo extension を使用できます。これは、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.');

注:php.iniで拡張機能を有効にして、サーバーを再起動することを忘れないでください。

extension=php_fileinfo.dll
4
fibriZo raZiel

リンクされた質問 には、ファイルURLのMIMEタイプを取得するためのいくつかのObjective-Cコードがあります。 MIMEタイプを取得するために、そのObjective-Cコードに基づいてSwift拡張を作成しました。

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
    }
}
0