Thomas Bruederli
2012-11-27 0a83971d3e6bc5dae958e304bea4bb1e7a33db59
Clarify mime_magic config option; add new function to map mimetypes and filename extensions
1 files deleted
3 files modified
10902 ■■■■■ changed files
config/main.inc.php.dist 10 ●●●● patch | view | raw | blame | history
config/mimetypes.php 7 ●●●●● patch | view | raw | blame | history
program/lib/Roundcube/rcube_mime.php 75 ●●●●● patch | view | raw | blame | history
program/lib/magic 10810 ●●●●● patch | view | raw | blame | history
config/main.inc.php.dist
@@ -363,8 +363,14 @@
// either a comma-separated list or an array: 'text/plain,text/html,text/xml,image/jpeg,image/gif,image/png,application/pdf'
$rcmail_config['client_mimetypes'] = null;  # null == default
// mime magic database
$rcmail_config['mime_magic'] = '/usr/share/misc/magic';
// Path to a local mime magic database file for PHPs finfo extension.
// Set to null if the default path should be used.
$rcmail_config['mime_magic'] = null;
// Path to local mime.types mapping table.
// This is used to derive mime-types from the filename extension or vice versa.
// Such a file is usually part of the apache webserver.
$rcmail_config['mime_types'] = null;
// path to imagemagick identify binary
$rcmail_config['im_identify_path'] = null;
config/mimetypes.php
@@ -1,5 +1,12 @@
<?php
/**
 * Local mapping file to specify mime-types based on common file-name extensions
 *
 * Please note that this mapping takes precedence over the content-based mime-type detection
 * and should only contain mappings which cannot be detected properly from the file contents.
 */
return array(
  'xls' => 'application/vnd.ms-excel',
  'xlm' => 'application/vnd.ms-excel',
program/lib/Roundcube/rcube_mime.php
@@ -641,21 +641,22 @@
    /**
     * A method to guess the mime_type of an attachment.
     *
     * @param string $path      Path to the file.
     * @param string $path      Path to the file or file contents
     * @param string $name      File name (with suffix)
     * @param string $failover  Mime type supplied for failover.
     * @param string $is_stream Set to True if $path contains file body
     * @param string $failover  Mime type supplied for failover
     * @param boolean $is_stream   Set to True if $path contains file contents
     * @param boolean $skip_suffix Set to True if the config/mimetypes.php mappig should be ignored
     *
     * @return string
     * @author Till Klampaeckel <till@php.net>
     * @see    http://de2.php.net/manual/en/ref.fileinfo.php
     * @see    http://de2.php.net/mime_content_type
     */
    public static function file_content_type($path, $name, $failover = 'application/octet-stream', $is_stream = false)
    public static function file_content_type($path, $name, $failover = 'application/octet-stream', $is_stream = false, $skip_suffix = false)
    {
        $mime_type = null;
        $mime_magic = rcube::get_instance()->config->get('mime_magic');
        $mime_ext = @include RCUBE_CONFIG_DIR . '/mimetypes.php';
        $mime_ext = $skip_suffix ? null : @include(RCUBE_CONFIG_DIR . '/mimetypes.php');
        // use file name suffix with hard-coded mime-type map
        if (is_array($mime_ext) && $name) {
@@ -695,6 +696,70 @@
    /**
     * Get mimetype => file extension mapping
     *
     * @param string  Mime-Type to get extensions for
     * @return array  List of extensions matching the given mimetype or a hash array with ext -> mimetype mappings if $mimetype is not given
     */
    public static function get_mime_extensions($mimetype = null)
    {
        static $mime_types, $mime_extensions;
        // return cached data
        if (is_array($mime_types)) {
            return $mimetype ? $mime_types[$mimetype] : $mime_extensions;
        }
        // load mapping file
        $file_paths = array();
        if ($mime_types = rcube::get_instance()->config->get('mime_types'))
            $file_paths[] = $mime_types;
        // try common locations
        $file_paths[] = '/etc/httpd/mime.types';
        $file_paths[] = '/etc/httpd2/mime.types';
        $file_paths[] = '/etc/apache/mime.types';
        $file_paths[] = '/etc/apache2/mime.types';
        $file_paths[] = '/usr/local/etc/httpd/conf/mime.types';
        $file_paths[] = '/usr/local/etc/apache/conf/mime.types';
        foreach ($file_paths as $fp) {
            if (is_readable($fp)) {
                $lines = file($fp, FILE_IGNORE_NEW_LINES);
                break;
            }
        }
        $mime_types = $mime_extensions = array();
        $regex = "/([\w\+\-\.\/]+)\t+([\w\s]+)/i";
        foreach((array)$lines as $line) {
             // skip comments or mime types w/o any extensions
            if ($line[0] == '#' || !preg_match($regex, $line, $matches))
                continue;
            $mime = $matches[1];
            foreach (explode(' ', $matches[2]) as $ext) {
                $ext = trim($ext);
                $mime_types[$mime][] = $ext;
                $mime_extensions[$ext] = $mime;
            }
        }
        // fallback to some well-known types most important for daily emails
        if (empty($mime_types)) {
            $mime_extensions = @include(RCUBE_CONFIG_DIR . '/mimetypes.php');
            $mime_extensions += array('gif' => 'image/gif', 'png' => 'image/png', 'jpg' => 'image/jpg', 'jpeg' => 'image/jpeg', 'tif' => 'image/tiff');
            foreach ($mime_extensions as $ext => $mime)
                $mime_types[$mime][] = $ext;
        }
        return $mimetype ? $mime_types[$mimetype] : $mime_extensions;
    }
    /**
     * Detect image type of the given binary data by checking magic numbers.
     *
     * @param string $data  Binary file content
program/lib/magic
File was deleted