< 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: 127
Uncovered lines: 3
Coverable lines: 130
Total lines: 203
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 1/23/2026 - 12:11:06 AM Line coverage: 97.6% (126/129) Branch coverage: 60% (6/10) Total lines: 2024/24/2026 - 12:14:24 AM Line coverage: 97.6% (127/130) Branch coverage: 60% (6/10) Total lines: 203 1/23/2026 - 12:11:06 AM Line coverage: 97.6% (126/129) Branch coverage: 60% (6/10) Total lines: 2024/24/2026 - 12:14:24 AM Line coverage: 97.6% (127/130) Branch coverage: 60% (6/10) Total lines: 203

Coverage delta

Coverage delta 1 -1

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/jpg", ".jpg"),
 4136            new("image/tiff", ".tiff"),
 4137            new("image/x-png", ".png"),
 4138            new("image/x-icon", ".ico"),
 4139
 4140            // Type text
 4141            new("text/plain", ".txt"),
 4142            new("text/rtf", ".rtf"),
 4143            new("text/x-ssa", ".ssa"),
 4144
 4145            // Type video
 4146            new("video/vnd.mpeg.dash.mpd", ".mpd"),
 4147            new("video/x-matroska", ".mkv"),
 4148        }.ToFrozenDictionary(pair => pair.Key, pair => pair.Value, StringComparer.OrdinalIgnoreCase);
 149
 3150        public static string GetMimeType(string path) => GetMimeType(path, MediaTypeNames.Application.Octet);
 151
 152        /// <summary>
 153        /// Gets the type of the MIME.
 154        /// </summary>
 155        /// <param name="filename">The filename to find the MIME type of.</param>
 156        /// <param name="defaultValue">The default value to return if no fitting MIME type is found.</param>
 157        /// <returns>The correct MIME type for the given filename, or <paramref name="defaultValue"/> if it wasn't found
 158        [return: NotNullIfNotNull("defaultValue")]
 159        public static string? GetMimeType(string filename, string? defaultValue = null)
 160        {
 84161            ArgumentException.ThrowIfNullOrEmpty(filename);
 162
 84163            var ext = Path.GetExtension(filename);
 164
 84165            if (_mimeTypeLookup.TryGetValue(ext, out string? result))
 166            {
 26167                return result;
 168            }
 169
 58170            if (Model.MimeTypes.TryGetMimeType(filename, out var mimeType))
 171            {
 58172                return mimeType;
 173            }
 174
 175            // Catch-all for all video types that don't require specific mime types
 0176            if (_videoFileExtensions.Contains(ext))
 177            {
 0178                return string.Concat("video/", ext.AsSpan(1));
 179            }
 180
 0181            return defaultValue;
 182        }
 183
 184        public static string? ToExtension(string mimeType)
 185        {
 82186            ArgumentException.ThrowIfNullOrEmpty(mimeType);
 187
 188            // handle text/html; charset=UTF-8
 82189            mimeType = mimeType.AsSpan().LeftPart(';').ToString();
 190
 82191            if (_extensionLookup.TryGetValue(mimeType, out string? result))
 192            {
 33193                return result;
 194            }
 195
 49196            var extension = Model.MimeTypes.GetMimeTypeExtensions(mimeType).FirstOrDefault();
 49197            return string.IsNullOrEmpty(extension) ? null : "." + extension;
 198        }
 199
 200        public static bool IsImage(ReadOnlySpan<char> mimeType)
 12201            => mimeType.StartsWith("image/", StringComparison.OrdinalIgnoreCase);
 202    }
 203}