< Summary - Jellyfin

Information
Class: MediaBrowser.Model.Net.MimeTypes
Assembly: MediaBrowser.Model
File(s): /srv/git/jellyfin/MediaBrowser.Model/Net/MimeTypes.cs
Line coverage
97%
Covered lines: 126
Uncovered lines: 3
Coverable lines: 129
Total lines: 202
Line coverage: 97.6%
Branch coverage
60%
Covered branches: 6
Total branches: 10
Branch coverage: 60%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.cctor()100%11100%
GetMimeType(...)100%11100%
GetMimeType(...)50%7666.66%
ToExtension(...)75%44100%
IsImage(...)100%11100%

File(s)

/srv/git/jellyfin/MediaBrowser.Model/Net/MimeTypes.cs

#LineLine coverage
 1#pragma warning disable CS1591
 2
 3using System;
 4using System.Collections.Frozen;
 5using System.Collections.Generic;
 6using System.Diagnostics.CodeAnalysis;
 7using System.IO;
 8using System.Linq;
 9using System.Net.Mime;
 10using Jellyfin.Extensions;
 11
 12namespace MediaBrowser.Model.Net
 13{
 14    /// <summary>
 15    /// Class MimeTypes.
 16    /// </summary>
 17    ///
 18    /// <remarks>
 19    /// For more information on MIME types:
 20    /// <list type="bullet">
 21    ///     <item>http://en.wikipedia.org/wiki/Internet_media_type</item>
 22    ///     <item>https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types</item>
 23    ///     <item>http://www.iana.org/assignments/media-types/media-types.xhtml</item>
 24    /// </list>
 25    /// </remarks>
 26    public static class MimeTypes
 27    {
 28        /// <summary>
 29        /// Any extension in this list is considered a video file.
 30        /// </summary>
 431        private static readonly FrozenSet<string> _videoFileExtensions = new[]
 432        {
 433            ".3gp",
 434            ".asf",
 435            ".avi",
 436            ".divx",
 437            ".dvr-ms",
 438            ".f4v",
 439            ".flv",
 440            ".img",
 441            ".iso",
 442            ".m2t",
 443            ".m2ts",
 444            ".m2v",
 445            ".m4v",
 446            ".mk3d",
 447            ".mkv",
 448            ".mov",
 449            ".mp4",
 450            ".mpg",
 451            ".mpeg",
 452            ".mts",
 453            ".ogg",
 454            ".ogm",
 455            ".ogv",
 456            ".rec",
 457            ".ts",
 458            ".rmvb",
 459            ".vob",
 460            ".webm",
 461            ".wmv",
 462            ".wtv",
 463        }.ToFrozenSet(StringComparer.OrdinalIgnoreCase);
 64
 65        /// <summary>
 66        /// Used for extensions not in <see cref="Model.MimeTypes"/> or to override them.
 67        /// </summary>
 468        private static readonly FrozenDictionary<string, string> _mimeTypeLookup = new KeyValuePair<string, string>[]
 469        {
 470            // Type application
 471            new(".azw3", "application/vnd.amazon.ebook"),
 472            new(".cb7", "application/x-cb7"),
 473            new(".cba", "application/x-cba"),
 474            new(".cbr", "application/vnd.comicbook-rar"),
 475            new(".cbt", "application/x-cbt"),
 476            new(".cbz", "application/vnd.comicbook+zip"),
 477
 478            // Type image
 479            new(".tbn", "image/jpeg"),
 480
 481            // Type text
 482            new(".ass", "text/x-ssa"),
 483            new(".ssa", "text/x-ssa"),
 484            new(".edl", "text/plain"),
 485            new(".html", "text/html; charset=UTF-8"),
 486            new(".htm", "text/html; charset=UTF-8"),
 487
 488            // Type video
 489            new(".mpegts", "video/mp2t"),
 490
 491            // Type audio
 492            new(".aac", "audio/aac"),
 493            new(".ac3", "audio/ac3"),
 494            new(".ape", "audio/x-ape"),
 495            new(".dsf", "audio/dsf"),
 496            new(".dsp", "audio/dsp"),
 497            new(".flac", "audio/flac"),
 498            new(".m4b", "audio/mp4"),
 499            new(".mp3", "audio/mpeg"),
 4100            new(".vorbis", "audio/vorbis"),
 4101            new(".webma", "audio/webm"),
 4102            new(".wv", "audio/x-wavpack"),
 4103            new(".xsp", "audio/xsp"),
 4104        }.ToFrozenDictionary(pair => pair.Key, pair => pair.Value, StringComparer.OrdinalIgnoreCase);
 105
 4106        private static readonly FrozenDictionary<string, string> _extensionLookup = new KeyValuePair<string, string>[]
 4107        {
 4108            // Type application
 4109            new("application/vnd.comicbook-rar", ".cbr"),
 4110            new("application/vnd.comicbook+zip", ".cbz"),
 4111            new("application/x-cb7", ".cb7"),
 4112            new("application/x-cba", ".cba"),
 4113            new("application/x-cbr", ".cbr"),
 4114            new("application/x-cbt", ".cbt"),
 4115            new("application/x-cbz", ".cbz"),
 4116            new("application/x-javascript", ".js"),
 4117            new("application/xml", ".xml"),
 4118            new("application/x-mpegURL", ".m3u8"),
 4119
 4120            // Type audio
 4121            new("audio/aac", ".aac"),
 4122            new("audio/ac3", ".ac3"),
 4123            new("audio/dsf", ".dsf"),
 4124            new("audio/dsp", ".dsp"),
 4125            new("audio/flac", ".flac"),
 4126            new("audio/m4b", ".m4b"),
 4127            new("audio/vorbis", ".vorbis"),
 4128            new("audio/x-ape", ".ape"),
 4129            new("audio/xsp", ".xsp"),
 4130            new("audio/x-aac", ".aac"),
 4131            new("audio/x-wavpack", ".wv"),
 4132
 4133            // Type image
 4134            new("image/jpeg", ".jpg"),
 4135            new("image/tiff", ".tiff"),
 4136            new("image/x-png", ".png"),
 4137            new("image/x-icon", ".ico"),
 4138
 4139            // Type text
 4140            new("text/plain", ".txt"),
 4141            new("text/rtf", ".rtf"),
 4142            new("text/x-ssa", ".ssa"),
 4143
 4144            // Type video
 4145            new("video/vnd.mpeg.dash.mpd", ".mpd"),
 4146            new("video/x-matroska", ".mkv"),
 4147        }.ToFrozenDictionary(pair => pair.Key, pair => pair.Value, StringComparer.OrdinalIgnoreCase);
 148
 3149        public static string GetMimeType(string path) => GetMimeType(path, MediaTypeNames.Application.Octet);
 150
 151        /// <summary>
 152        /// Gets the type of the MIME.
 153        /// </summary>
 154        /// <param name="filename">The filename to find the MIME type of.</param>
 155        /// <param name="defaultValue">The default value to return if no fitting MIME type is found.</param>
 156        /// <returns>The correct MIME type for the given filename, or <paramref name="defaultValue"/> if it wasn't found
 157        [return: NotNullIfNotNull("defaultValue")]
 158        public static string? GetMimeType(string filename, string? defaultValue = null)
 159        {
 84160            ArgumentException.ThrowIfNullOrEmpty(filename);
 161
 84162            var ext = Path.GetExtension(filename);
 163
 84164            if (_mimeTypeLookup.TryGetValue(ext, out string? result))
 165            {
 26166                return result;
 167            }
 168
 58169            if (Model.MimeTypes.TryGetMimeType(filename, out var mimeType))
 170            {
 58171                return mimeType;
 172            }
 173
 174            // Catch-all for all video types that don't require specific mime types
 0175            if (_videoFileExtensions.Contains(ext))
 176            {
 0177                return string.Concat("video/", ext.AsSpan(1));
 178            }
 179
 0180            return defaultValue;
 181        }
 182
 183        public static string? ToExtension(string mimeType)
 184        {
 82185            ArgumentException.ThrowIfNullOrEmpty(mimeType);
 186
 187            // handle text/html; charset=UTF-8
 82188            mimeType = mimeType.AsSpan().LeftPart(';').ToString();
 189
 82190            if (_extensionLookup.TryGetValue(mimeType, out string? result))
 191            {
 33192                return result;
 193            }
 194
 49195            var extension = Model.MimeTypes.GetMimeTypeExtensions(mimeType).FirstOrDefault();
 49196            return string.IsNullOrEmpty(extension) ? null : "." + extension;
 197        }
 198
 199        public static bool IsImage(ReadOnlySpan<char> mimeType)
 12200            => mimeType.StartsWith("image/", StringComparison.OrdinalIgnoreCase);
 201    }
 202}