.rar, .zip files MIME Type
Asked Answered
T

6

188

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)

Thiouracil answered 8/8, 2011 at 3:45 Comment(2)
possible duplicate of How to set max file upload size and allow only certain file types on PHP upload?Watermark
I want to allow all compressed files alone(rar,zip,tar.gz,jar etc), what is the procedure?Insolvent
N
314

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
Niddering answered 11/8, 2011 at 14:22 Comment(8)
multipart/x-zip is a valid mimetype for .zip as well ( PKZIP archive )Kymberlykymograph
actually there's another MIME TYPE for zip, and that's: application/x-zip-compressedMorsel
This won't guarantee you a zip or rar file at all. According to the WC3 specifications this will be intrepreted as: "I prefer a application/zip|application/x-rar-compressed content type, but if you cannot deliver this an application/octet-stream (file stream) is also fine".Listing
Here is a usefull list of mime types with .zip among others: sitepoint.com/web-foundations/mime-types-complete-listWillpower
How in the world could multipart/x-zip possibly be valid? It's not multi-part. The SitePoint list contains many inaccurate MIME types and it's far from complete. The official IANA Media Types registry isn't (nor will it likely ever be) 100% complete.Runck
Although a splendid solution now, not a very sustainable one. Who knows how the header might change or other new header content might be added in the future.Gracchus
The headers are fixed. See en.wikipedia.org/wiki/Magic_number_(programming) and en.wikipedia.org/wiki/RAR_(file_format)Niddering
Since WinRAR version 5 there is a new file format for RAR archives available. To differentiate between them a new header is used: '526172211a070100'Niddering
L
49

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).

Listing answered 9/4, 2015 at 13:22 Comment(0)
S
7

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
Sarcoma answered 6/11, 2015 at 13:31 Comment(0)
S
4

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
Spitball answered 7/9, 2020 at 14:24 Comment(4)
Well, not sure about that. Their entry about zip is from 1993...Cockney
@Cockney not sure that .zip has application/zip? Not sure I've hot your point, but if so why should a Media Type that has been marked as official change over the time? There is no expiration date. Maybe the file can become obsolete.Spitball
You're right, they don't expire unless they are explicitly made obsolete by something new. But IANA doesn't even mention those other zip mime types. Where do they come from? Why do they exist? How do they relate to the official "application/zip"? Perhaps IANA just neglected to update their info? How can we be sure?Cockney
Your 5 year later answer is virtually the same as my answer; same link to Iana, and same conclusion about the mime-types.Listing
S
0

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
    }
}
Satterlee answered 1/11, 2018 at 8:6 Comment(0)
G
-3

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 '.'

Gracchus answered 20/2, 2015 at 9:10 Comment(1)
It is very unfortunate but there is no guarantee that the mime type conventions illustrated by that other answers is observed by specific OS / browser combos. Really the only thing you can be sure of are file extension, unfortunately.Gracchus

© 2022 - 2024 — McMap. All rights reserved.