.rar、.zip 文件 MIME 类型

发布于 2024-11-28 06:40:50 字数 114 浏览 7 评论 0原文

我正在开发一个简单的 php 上传脚本,用户只能上传 ZIP 和 RAR 文件。

我应该使用什么 MIME 类型来检查 $_FILES[x][type]? (请提供完整清单)

I'm developing a simple php upload script, and users can upload only ZIP and RAR files.

What MIME types I should use to check $_FILES[x][type]? (a complete list please)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

一身骄傲 2024-12-05 06:40:50

Freedompeace、Kiyarash 和 Sam Vloeberghs 的回答:

.rar    application/vnd.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

The answers from freedompeace, Kiyarash and Sam Vloeberghs:

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

I would do a check on the file name too. Here is how you could check if the file is a RAR or ZIP file. I tested it by creating a quick command line application.

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

Notice that it still won't be 100% certain, but it is probably good enough.

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

But even WinRAR detects non RAR files as SFX archives:

$ rar.exe l somefile.srr
SFX Volume somefile.srr
魄砕の薆 2024-12-05 06:40:50

如需上传:

mime 类型的官方列表可在 The Internet Assigned Numbers 中找到权威机构 (IANA)。根据他们的列表,zipContent-Type 标头是 application/zip

rar 文件的媒体类型于 2016 年在 IANA 注册,为 application/vnd.rar(请参阅 https://www.iana.org/assignments/media-types/application/vnd.rar)。 mime-type 值 application/x-rar-compressed 在此之前已使用,并且仍然常用,尽管它在上面的文档中被标记为已弃用。

application/octet-stream 的含义与:“我向您发送一个文件流,但未指定该流的内容”(因此确实可以一个 ziprar 文件)。服务器应该检测流的实际内容是什么。

注意: 对于上传,依赖 Content-Type 标头中设置的 mime 类型并不安全。标头在客户端设置,可以设置为任意随机值。相反,您可以使用 php 文件信息 函数来检测文件 mime-在服务器上输入。


用于下载:

如果您想下载 zip 文件而不下载其他文件,则只需设置一个 Accept 标头值。如果服务器无法满足您在 Accept 标头中请求的 mime 类型,则设置的任何其他值都将用作后备。

根据 WC3 规范,此:

application/zip, application/octet-stream 

将解释为: “我更喜欢 application/zip mime 类型,但如果您无法提供该 application/octet-stream (文件流)很好”。

因此只有一个:

application/zip

将保证您获得一个zip文件(或者在服务器无法满足您的请求时返回一个406 - Not Acceptable响应)。

For upload:

An official list of mime types can be found at The Internet Assigned Numbers Authority (IANA) . According to their list Content-Type header for zip is application/zip.

The media type for rar files, registered at IANA in 2016, is application/vnd.rar (see https://www.iana.org/assignments/media-types/application/vnd.rar). The mime-type value, application/x-rar-compressed, was used before that and is still commonly used even though it is marked as deprecated in the document above.

application/octet-stream means as much as: "I send you a file stream and the content of this stream is not specified" (so it is true that it can be a zip or rar file as well). The server is supposed to detect what the actual content of the stream is.

Note: For upload it is not safe to rely on the mime type set in the Content-Type header. The header is set on the client and can be set to any random value. Instead you can use the php file info functions to detect the file mime-type on the server.


For download:

If you want to download a zip file and nothing else you should only set one single Accept header value. Any additional values set will be used as a fallback in case the server cannot satisfy your in the Accept header requested mime-type.

According to the WC3 specifications this:

application/zip, application/octet-stream 

will be intrepreted as: "I prefer a application/zip mime-type, but if you cannot deliver this an application/octet-stream (a file stream) is also fine".

So only a single:

application/zip

Will guarantee you a zip file (or a 406 - Not Acceptable response in case the server is unable to satisfy your request).

过气美图社 2024-12-05 06:40:50

您不应该信任 $_FILES['upfile']['mime'],请自行检查 MIME 类型。为此,您可以使用 fileinfo 扩展,从 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

You should not trust $_FILES['upfile']['mime'], check MIME type by yourself. For that purpose, you may use fileinfo extension, enabled by default as of 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.');

NOTE: Don't forget to enable the extension in your php.ini and restart your server:

extension=php_fileinfo.dll
最舍不得你 2024-12-05 06:40:50

我看到许多答案分别报告了 zip 和 rar 媒体类型 application/zipapplication/x-rar-compressed

虽然前一个匹配是正确的,但对于后一个 IANA 报告,请参见此处 https:// /www.iana.org/assignments/media-types/application/vnd.rar 对于 rar application/x-rar-compressed 是一个已弃用的别名,而是application/vnd.rar 是官方的。
因此,2020 年 IANA 发布的正确媒体类型为:

  1. zipapplication/zip
  2. rarapplication/vnd.rar

I see many answer reporting for zip and rar the Media Types application/zip and application/x-rar-compressed, respectively.

While the former matching is correct, for the latter IANA reports here https://www.iana.org/assignments/media-types/application/vnd.rar that for rar application/x-rar-compressed is a deprecated alias name and instead application/vnd.rar is the official one.
So, right Media Types from IANA in 2020 are:

  1. zip: application/zip
  2. rar: application/vnd.rar
鹤舞 2024-12-05 06:40:50

链接的问题中,有一些 Objective-C 代码可以获取文件 URL 的 mime 类型。我基于 Objective-C 代码创建了一个 Swift 扩展来获取 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
    }
}

In a linked question, there's some Objective-C code to get the mime type for a file URL. I've created a Swift extension based on that Objective-C code to get the mime type:

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
    }
}
空名 2024-12-05 06:40:50

由于扩展名可能包含多于或少于三个字符,因此以下内容将测试扩展名,无论其长度如何。

试试这个:

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

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

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

检查最后一个“.”之后的所有字符

As extension might contain more or less that three characters the following will test for an extension regardless of the length of it.

Try this:

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

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

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

to check for all characters after the last '.'

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文