< 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: 124
Uncovered lines: 3
Coverable lines: 127
Total lines: 199
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%7.33666.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 Jellyfin.Extensions;
 10
 11namespace MediaBrowser.Model.Net
 12{
 13    /// <summary>
 14    /// Class MimeTypes.
 15    /// </summary>
 16    ///
 17    /// <remarks>
 18    /// For more information on MIME types:
 19    /// <list type="bullet">
 20    ///     <item>http://en.wikipedia.org/wiki/Internet_media_type</item>
 21    ///     <item>https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types</item>
 22    ///     <item>http://www.iana.org/assignments/media-types/media-types.xhtml</item>
 23    /// </list>
 24    /// </remarks>
 25    public static class MimeTypes
 26    {
 27        /// <summary>
 28        /// Any extension in this list is considered a video file.
 29        /// </summary>
 430        private static readonly FrozenSet<string> _videoFileExtensions = new[]
 431        {
 432            ".3gp",
 433            ".asf",
 434            ".avi",
 435            ".divx",
 436            ".dvr-ms",
 437            ".f4v",
 438            ".flv",
 439            ".img",
 440            ".iso",
 441            ".m2t",
 442            ".m2ts",
 443            ".m2v",
 444            ".m4v",
 445            ".mk3d",
 446            ".mkv",
 447            ".mov",
 448            ".mp4",
 449            ".mpg",
 450            ".mpeg",
 451            ".mts",
 452            ".ogg",
 453            ".ogm",
 454            ".ogv",
 455            ".rec",
 456            ".ts",
 457            ".rmvb",
 458            ".webm",
 459            ".wmv",
 460            ".wtv",
 461        }.ToFrozenSet(StringComparer.OrdinalIgnoreCase);
 62
 63        /// <summary>
 64        /// Used for extensions not in <see cref="Model.MimeTypes"/> or to override them.
 65        /// </summary>
 466        private static readonly FrozenDictionary<string, string> _mimeTypeLookup = new KeyValuePair<string, string>[]
 467        {
 468            // Type application
 469            new(".azw3", "application/vnd.amazon.ebook"),
 470            new(".cb7", "application/x-cb7"),
 471            new(".cba", "application/x-cba"),
 472            new(".cbr", "application/vnd.comicbook-rar"),
 473            new(".cbt", "application/x-cbt"),
 474            new(".cbz", "application/vnd.comicbook+zip"),
 475
 476            // Type image
 477            new(".tbn", "image/jpeg"),
 478
 479            // Type text
 480            new(".ass", "text/x-ssa"),
 481            new(".ssa", "text/x-ssa"),
 482            new(".edl", "text/plain"),
 483            new(".html", "text/html; charset=UTF-8"),
 484            new(".htm", "text/html; charset=UTF-8"),
 485
 486            // Type video
 487            new(".mpegts", "video/mp2t"),
 488
 489            // Type audio
 490            new(".aac", "audio/aac"),
 491            new(".ac3", "audio/ac3"),
 492            new(".ape", "audio/x-ape"),
 493            new(".dsf", "audio/dsf"),
 494            new(".dsp", "audio/dsp"),
 495            new(".flac", "audio/flac"),
 496            new(".m4b", "audio/mp4"),
 497            new(".mp3", "audio/mpeg"),
 498            new(".vorbis", "audio/vorbis"),
 499            new(".webma", "audio/webm"),
 4100            new(".wv", "audio/x-wavpack"),
 4101            new(".xsp", "audio/xsp"),
 4102        }.ToFrozenDictionary(pair => pair.Key, pair => pair.Value, StringComparer.OrdinalIgnoreCase);
 103
 4104        private static readonly FrozenDictionary<string, string> _extensionLookup = new KeyValuePair<string, string>[]
 4105        {
 4106            // Type application
 4107            new("application/vnd.comicbook-rar", ".cbr"),
 4108            new("application/vnd.comicbook+zip", ".cbz"),
 4109            new("application/x-cb7", ".cb7"),
 4110            new("application/x-cba", ".cba"),
 4111            new("application/x-cbr", ".cbr"),
 4112            new("application/x-cbt", ".cbt"),
 4113            new("application/x-cbz", ".cbz"),
 4114            new("application/x-javascript", ".js"),
 4115            new("application/xml", ".xml"),
 4116            new("application/x-mpegURL", ".m3u8"),
 4117
 4118            // Type audio
 4119            new("audio/aac", ".aac"),
 4120            new("audio/ac3", ".ac3"),
 4121            new("audio/dsf", ".dsf"),
 4122            new("audio/dsp", ".dsp"),
 4123            new("audio/flac", ".flac"),
 4124            new("audio/m4b", ".m4b"),
 4125            new("audio/vorbis", ".vorbis"),
 4126            new("audio/x-ape", ".ape"),
 4127            new("audio/xsp", ".xsp"),
 4128            new("audio/x-wavpack", ".wv"),
 4129
 4130            // Type image
 4131            new("image/jpeg", ".jpg"),
 4132            new("image/tiff", ".tiff"),
 4133            new("image/x-png", ".png"),
 4134            new("image/x-icon", ".ico"),
 4135
 4136            // Type text
 4137            new("text/plain", ".txt"),
 4138            new("text/rtf", ".rtf"),
 4139            new("text/x-ssa", ".ssa"),
 4140
 4141            // Type video
 4142            new("video/vnd.mpeg.dash.mpd", ".mpd"),
 4143            new("video/x-matroska", ".mkv"),
 4144        }.ToFrozenDictionary(pair => pair.Key, pair => pair.Value, StringComparer.OrdinalIgnoreCase);
 145
 3146        public static string GetMimeType(string path) => GetMimeType(path, "application/octet-stream");
 147
 148        /// <summary>
 149        /// Gets the type of the MIME.
 150        /// </summary>
 151        /// <param name="filename">The filename to find the MIME type of.</param>
 152        /// <param name="defaultValue">The default value to return if no fitting MIME type is found.</param>
 153        /// <returns>The correct MIME type for the given filename, or <paramref name="defaultValue"/> if it wasn't found
 154        [return: NotNullIfNotNull("defaultValue")]
 155        public static string? GetMimeType(string filename, string? defaultValue = null)
 156        {
 84157            ArgumentException.ThrowIfNullOrEmpty(filename);
 158
 84159            var ext = Path.GetExtension(filename);
 160
 84161            if (_mimeTypeLookup.TryGetValue(ext, out string? result))
 162            {
 26163                return result;
 164            }
 165
 58166            if (Model.MimeTypes.TryGetMimeType(filename, out var mimeType))
 167            {
 58168                return mimeType;
 169            }
 170
 171            // Catch-all for all video types that don't require specific mime types
 0172            if (_videoFileExtensions.Contains(ext))
 173            {
 0174                return string.Concat("video/", ext.AsSpan(1));
 175            }
 176
 0177            return defaultValue;
 178        }
 179
 180        public static string? ToExtension(string mimeType)
 181        {
 82182            ArgumentException.ThrowIfNullOrEmpty(mimeType);
 183
 184            // handle text/html; charset=UTF-8
 82185            mimeType = mimeType.AsSpan().LeftPart(';').ToString();
 186
 82187            if (_extensionLookup.TryGetValue(mimeType, out string? result))
 188            {
 32189                return result;
 190            }
 191
 50192            var extension = Model.MimeTypes.GetMimeTypeExtensions(mimeType).FirstOrDefault();
 50193            return string.IsNullOrEmpty(extension) ? null : "." + extension;
 194        }
 195
 196        public static bool IsImage(ReadOnlySpan<char> mimeType)
 12197            => mimeType.StartsWith("image/", StringComparison.OrdinalIgnoreCase);
 198    }
 199}