From beafd6eaabf7baa7c478b4a0ef131ddc480b368a Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Wed, 1 Dec 2021 00:13:02 +0100 Subject: Use JsonContent where possible Should reduce the # of allocated bytes --- tests/Jellyfin.Server.Integration.Tests/AuthHelper.cs | 6 +++--- .../Controllers/DlnaControllerTests.cs | 10 ++++------ .../Controllers/MediaStructureControllerTests.cs | 7 +++---- .../Controllers/StartupControllerTests.cs | 7 +++---- .../Controllers/UserControllerTests.cs | 7 +++---- 5 files changed, 16 insertions(+), 21 deletions(-) (limited to 'tests') diff --git a/tests/Jellyfin.Server.Integration.Tests/AuthHelper.cs b/tests/Jellyfin.Server.Integration.Tests/AuthHelper.cs index 4ea05397d..4c8f64d1e 100644 --- a/tests/Jellyfin.Server.Integration.Tests/AuthHelper.cs +++ b/tests/Jellyfin.Server.Integration.Tests/AuthHelper.cs @@ -1,6 +1,7 @@ using System; using System.Net; using System.Net.Http; +using System.Net.Http.Json; using System.Net.Http.Headers; using System.Net.Mime; using System.Text.Json; @@ -26,14 +27,13 @@ namespace Jellyfin.Server.Integration.Tests using var completeResponse = await client.PostAsync("/Startup/Complete", new ByteArrayContent(Array.Empty())).ConfigureAwait(false); Assert.Equal(HttpStatusCode.NoContent, completeResponse.StatusCode); - using var content = new ByteArrayContent(JsonSerializer.SerializeToUtf8Bytes( + using var content = JsonContent.Create( new AuthenticateUserByName() { Username = user!.Name, Pw = user.Password, }, - jsonOptions)); - content.Headers.ContentType = MediaTypeHeaderValue.Parse(MediaTypeNames.Application.Json); + options: jsonOptions); content.Headers.Add("X-Emby-Authorization", DummyAuthHeader); using var authResponse = await client.PostAsync("/Users/AuthenticateByName", content).ConfigureAwait(false); diff --git a/tests/Jellyfin.Server.Integration.Tests/Controllers/DlnaControllerTests.cs b/tests/Jellyfin.Server.Integration.Tests/Controllers/DlnaControllerTests.cs index 4421ced72..8a03583bb 100644 --- a/tests/Jellyfin.Server.Integration.Tests/Controllers/DlnaControllerTests.cs +++ b/tests/Jellyfin.Server.Integration.Tests/Controllers/DlnaControllerTests.cs @@ -2,6 +2,7 @@ using System; using System.Linq; using System.Net; using System.Net.Http; +using System.Net.Http.Json; using System.Net.Http.Headers; using System.Net.Mime; using System.Text; @@ -62,8 +63,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers Name = "ThisProfileDoesNotExist" }; - using var content = new ByteArrayContent(JsonSerializer.SerializeToUtf8Bytes(deviceProfile, _jsonOptions)); - content.Headers.ContentType = MediaTypeHeaderValue.Parse(MediaTypeNames.Application.Json); + using var content = JsonContent.Create(deviceProfile, options: _jsonOptions); using var getResponse = await client.PostAsync("/Dlna/Profiles/" + NonExistentProfile, content).ConfigureAwait(false); Assert.Equal(HttpStatusCode.NotFound, getResponse.StatusCode); } @@ -80,8 +80,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers Name = "ThisProfileIsNew" }; - using var content = new ByteArrayContent(JsonSerializer.SerializeToUtf8Bytes(deviceProfile, _jsonOptions)); - content.Headers.ContentType = MediaTypeHeaderValue.Parse(MediaTypeNames.Application.Json); + using var content = JsonContent.Create(deviceProfile, options: _jsonOptions); using var getResponse = await client.PostAsync("/Dlna/Profiles", content).ConfigureAwait(false); Assert.Equal(HttpStatusCode.NoContent, getResponse.StatusCode); } @@ -120,8 +119,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers Id = _newDeviceProfileId }; - using var content = new ByteArrayContent(JsonSerializer.SerializeToUtf8Bytes(updatedProfile, _jsonOptions)); - content.Headers.ContentType = MediaTypeHeaderValue.Parse(MediaTypeNames.Application.Json); + using var content = JsonContent.Create(updatedProfile, options: _jsonOptions); using var getResponse = await client.PostAsync("/Dlna/Profiles", content).ConfigureAwait(false); Assert.Equal(HttpStatusCode.NoContent, getResponse.StatusCode); } diff --git a/tests/Jellyfin.Server.Integration.Tests/Controllers/MediaStructureControllerTests.cs b/tests/Jellyfin.Server.Integration.Tests/Controllers/MediaStructureControllerTests.cs index 19d8381ea..a9713b4cb 100644 --- a/tests/Jellyfin.Server.Integration.Tests/Controllers/MediaStructureControllerTests.cs +++ b/tests/Jellyfin.Server.Integration.Tests/Controllers/MediaStructureControllerTests.cs @@ -1,6 +1,7 @@ using System; using System.Net; using System.Net.Http; +using System.Net.Http.Json; using System.Net.Http.Headers; using System.Net.Mime; using System.Text.Json; @@ -71,8 +72,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers Path = "/this/path/doesnt/exist" }; - using var postContent = new ByteArrayContent(JsonSerializer.SerializeToUtf8Bytes(data, _jsonOptions)); - postContent.Headers.ContentType = MediaTypeHeaderValue.Parse(MediaTypeNames.Application.Json); + using var postContent = JsonContent.Create(data, options: _jsonOptions); var response = await client.PostAsync("Library/VirtualFolders/Paths", postContent).ConfigureAwait(false); Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); @@ -90,8 +90,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers PathInfo = new MediaPathInfo("test") }; - using var postContent = new ByteArrayContent(JsonSerializer.SerializeToUtf8Bytes(data, _jsonOptions)); - postContent.Headers.ContentType = MediaTypeHeaderValue.Parse(MediaTypeNames.Application.Json); + using var postContent = JsonContent.Create(data, options: _jsonOptions); var response = await client.PostAsync("Library/VirtualFolders/Paths/Update", postContent).ConfigureAwait(false); Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); diff --git a/tests/Jellyfin.Server.Integration.Tests/Controllers/StartupControllerTests.cs b/tests/Jellyfin.Server.Integration.Tests/Controllers/StartupControllerTests.cs index 9c0fc72f6..d9cde1dd9 100644 --- a/tests/Jellyfin.Server.Integration.Tests/Controllers/StartupControllerTests.cs +++ b/tests/Jellyfin.Server.Integration.Tests/Controllers/StartupControllerTests.cs @@ -1,6 +1,7 @@ using System; using System.Net; using System.Net.Http; +using System.Net.Http.Json; using System.Net.Http.Headers; using System.Net.Mime; using System.Text.Json; @@ -36,8 +37,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers PreferredMetadataLanguage = "nl" }; - using var postContent = new ByteArrayContent(JsonSerializer.SerializeToUtf8Bytes(config, _jsonOptions)); - postContent.Headers.ContentType = MediaTypeHeaderValue.Parse(MediaTypeNames.Application.Json); + using var postContent = JsonContent.Create(config, options: _jsonOptions); using var postResponse = await client.PostAsync("/Startup/Configuration", postContent).ConfigureAwait(false); Assert.Equal(HttpStatusCode.NoContent, postResponse.StatusCode); @@ -80,8 +80,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers Password = "NewPassword" }; - using var postContent = new ByteArrayContent(JsonSerializer.SerializeToUtf8Bytes(user, _jsonOptions)); - postContent.Headers.ContentType = MediaTypeHeaderValue.Parse(MediaTypeNames.Application.Json); + using var postContent = JsonContent.Create(user, options: _jsonOptions); var postResponse = await client.PostAsync("/Startup/User", postContent).ConfigureAwait(false); Assert.Equal(HttpStatusCode.NoContent, postResponse.StatusCode); diff --git a/tests/Jellyfin.Server.Integration.Tests/Controllers/UserControllerTests.cs b/tests/Jellyfin.Server.Integration.Tests/Controllers/UserControllerTests.cs index 8866ab53c..0f8b930f1 100644 --- a/tests/Jellyfin.Server.Integration.Tests/Controllers/UserControllerTests.cs +++ b/tests/Jellyfin.Server.Integration.Tests/Controllers/UserControllerTests.cs @@ -3,6 +3,7 @@ using System.Globalization; using System.Linq; using System.Net; using System.Net.Http; +using System.Net.Http.Json; using System.Net.Http.Headers; using System.Net.Mime; using System.Text.Json; @@ -32,15 +33,13 @@ namespace Jellyfin.Server.Integration.Tests.Controllers private Task CreateUserByName(HttpClient httpClient, CreateUserByName request) { - using var postContent = new ByteArrayContent(JsonSerializer.SerializeToUtf8Bytes(request, _jsonOpions)); - postContent.Headers.ContentType = MediaTypeHeaderValue.Parse(MediaTypeNames.Application.Json); + using var postContent = JsonContent.Create(request, options: _jsonOpions); return httpClient.PostAsync("Users/New", postContent); } private Task UpdateUserPassword(HttpClient httpClient, Guid userId, UpdateUserPassword request) { - using var postContent = new ByteArrayContent(JsonSerializer.SerializeToUtf8Bytes(request, _jsonOpions)); - postContent.Headers.ContentType = MediaTypeHeaderValue.Parse(MediaTypeNames.Application.Json); + using var postContent = JsonContent.Create(request, options: _jsonOpions); return httpClient.PostAsync("Users/" + userId.ToString("N", CultureInfo.InvariantCulture) + "/Password", postContent); } -- cgit v1.2.3 From 40be86eec0fa7f43b64d05f30adcfab88ad3c402 Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Wed, 1 Dec 2021 15:58:23 +0100 Subject: Use PostAsJsonAsync where possible --- .../Controllers/DlnaControllerTests.cs | 9 +++------ .../Controllers/MediaStructureControllerTests.cs | 6 ++---- .../Controllers/StartupControllerTests.cs | 6 ++---- .../Controllers/UserControllerTests.cs | 10 ++-------- 4 files changed, 9 insertions(+), 22 deletions(-) (limited to 'tests') diff --git a/tests/Jellyfin.Server.Integration.Tests/Controllers/DlnaControllerTests.cs b/tests/Jellyfin.Server.Integration.Tests/Controllers/DlnaControllerTests.cs index 8a03583bb..4c46933aa 100644 --- a/tests/Jellyfin.Server.Integration.Tests/Controllers/DlnaControllerTests.cs +++ b/tests/Jellyfin.Server.Integration.Tests/Controllers/DlnaControllerTests.cs @@ -63,8 +63,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers Name = "ThisProfileDoesNotExist" }; - using var content = JsonContent.Create(deviceProfile, options: _jsonOptions); - using var getResponse = await client.PostAsync("/Dlna/Profiles/" + NonExistentProfile, content).ConfigureAwait(false); + using var getResponse = await client.PostAsJsonAsync("/Dlna/Profiles/" + NonExistentProfile, deviceProfile, _jsonOptions).ConfigureAwait(false); Assert.Equal(HttpStatusCode.NotFound, getResponse.StatusCode); } @@ -80,8 +79,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers Name = "ThisProfileIsNew" }; - using var content = JsonContent.Create(deviceProfile, options: _jsonOptions); - using var getResponse = await client.PostAsync("/Dlna/Profiles", content).ConfigureAwait(false); + using var getResponse = await client.PostAsJsonAsync("/Dlna/Profiles", deviceProfile, _jsonOptions).ConfigureAwait(false); Assert.Equal(HttpStatusCode.NoContent, getResponse.StatusCode); } @@ -119,8 +117,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers Id = _newDeviceProfileId }; - using var content = JsonContent.Create(updatedProfile, options: _jsonOptions); - using var getResponse = await client.PostAsync("/Dlna/Profiles", content).ConfigureAwait(false); + using var getResponse = await client.PostAsJsonAsync("/Dlna/Profiles", updatedProfile, _jsonOptions).ConfigureAwait(false); Assert.Equal(HttpStatusCode.NoContent, getResponse.StatusCode); } diff --git a/tests/Jellyfin.Server.Integration.Tests/Controllers/MediaStructureControllerTests.cs b/tests/Jellyfin.Server.Integration.Tests/Controllers/MediaStructureControllerTests.cs index a9713b4cb..2da5237db 100644 --- a/tests/Jellyfin.Server.Integration.Tests/Controllers/MediaStructureControllerTests.cs +++ b/tests/Jellyfin.Server.Integration.Tests/Controllers/MediaStructureControllerTests.cs @@ -72,8 +72,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers Path = "/this/path/doesnt/exist" }; - using var postContent = JsonContent.Create(data, options: _jsonOptions); - var response = await client.PostAsync("Library/VirtualFolders/Paths", postContent).ConfigureAwait(false); + var response = await client.PostAsJsonAsync("Library/VirtualFolders/Paths", data, _jsonOptions).ConfigureAwait(false); Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); } @@ -90,8 +89,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers PathInfo = new MediaPathInfo("test") }; - using var postContent = JsonContent.Create(data, options: _jsonOptions); - var response = await client.PostAsync("Library/VirtualFolders/Paths/Update", postContent).ConfigureAwait(false); + var response = await client.PostAsJsonAsync("Library/VirtualFolders/Paths/Update", data, _jsonOptions).ConfigureAwait(false); Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); } diff --git a/tests/Jellyfin.Server.Integration.Tests/Controllers/StartupControllerTests.cs b/tests/Jellyfin.Server.Integration.Tests/Controllers/StartupControllerTests.cs index d9cde1dd9..ed92ce25a 100644 --- a/tests/Jellyfin.Server.Integration.Tests/Controllers/StartupControllerTests.cs +++ b/tests/Jellyfin.Server.Integration.Tests/Controllers/StartupControllerTests.cs @@ -37,8 +37,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers PreferredMetadataLanguage = "nl" }; - using var postContent = JsonContent.Create(config, options: _jsonOptions); - using var postResponse = await client.PostAsync("/Startup/Configuration", postContent).ConfigureAwait(false); + using var postResponse = await client.PostAsJsonAsync("/Startup/Configuration", config, _jsonOptions).ConfigureAwait(false); Assert.Equal(HttpStatusCode.NoContent, postResponse.StatusCode); using var getResponse = await client.GetAsync("/Startup/Configuration").ConfigureAwait(false); @@ -80,8 +79,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers Password = "NewPassword" }; - using var postContent = JsonContent.Create(user, options: _jsonOptions); - var postResponse = await client.PostAsync("/Startup/User", postContent).ConfigureAwait(false); + var postResponse = await client.PostAsJsonAsync("/Startup/User", user, _jsonOptions).ConfigureAwait(false); Assert.Equal(HttpStatusCode.NoContent, postResponse.StatusCode); var getResponse = await client.GetAsync("/Startup/User").ConfigureAwait(false); diff --git a/tests/Jellyfin.Server.Integration.Tests/Controllers/UserControllerTests.cs b/tests/Jellyfin.Server.Integration.Tests/Controllers/UserControllerTests.cs index 0f8b930f1..f11f276f8 100644 --- a/tests/Jellyfin.Server.Integration.Tests/Controllers/UserControllerTests.cs +++ b/tests/Jellyfin.Server.Integration.Tests/Controllers/UserControllerTests.cs @@ -32,16 +32,10 @@ namespace Jellyfin.Server.Integration.Tests.Controllers } private Task CreateUserByName(HttpClient httpClient, CreateUserByName request) - { - using var postContent = JsonContent.Create(request, options: _jsonOpions); - return httpClient.PostAsync("Users/New", postContent); - } + => httpClient.PostAsJsonAsync("Users/New", request, _jsonOpions); private Task UpdateUserPassword(HttpClient httpClient, Guid userId, UpdateUserPassword request) - { - using var postContent = JsonContent.Create(request, options: _jsonOpions); - return httpClient.PostAsync("Users/" + userId.ToString("N", CultureInfo.InvariantCulture) + "/Password", postContent); - } + => httpClient.PostAsJsonAsync("Users/" + userId.ToString("N", CultureInfo.InvariantCulture) + "/Password", request, _jsonOpions); [Fact] [Priority(-1)] -- cgit v1.2.3 From 6193fdea698ad4486140bc6a00a9547ab979c8f7 Mon Sep 17 00:00:00 2001 From: Ahmed Rafiq Date: Sat, 4 Dec 2021 19:50:48 +0600 Subject: Use MimeTypes package to determine MIME type This simplifies the code since we don't have to keep large mappings of extensions and MIME types. We still keep the ability to override the mappings for: - filling in entries not present in the package, for e.g. ".azw3" - picking preferred extensions, for e.g. MimeTypes provides ".conf" as a possible extionsion for "text/plain", and while that is correct, ".txt" would be preferrable - compatibility reasons --- MediaBrowser.Model/MediaBrowser.Model.csproj | 4 + MediaBrowser.Model/Net/MimeTypes.cs | 147 +++++++------------- tests/Jellyfin.Model.Tests/Net/MimeTypesTests.cs | 164 +++++++++++++++++++++++ 3 files changed, 217 insertions(+), 98 deletions(-) create mode 100644 tests/Jellyfin.Model.Tests/Net/MimeTypesTests.cs (limited to 'tests') diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index 70fef5d66..b1fbe864b 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -31,6 +31,10 @@ + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/MediaBrowser.Model/Net/MimeTypes.cs b/MediaBrowser.Model/Net/MimeTypes.cs index 043cee2a2..ff8d1fbae 100644 --- a/MediaBrowser.Model/Net/MimeTypes.cs +++ b/MediaBrowser.Model/Net/MimeTypes.cs @@ -12,6 +12,10 @@ namespace MediaBrowser.Model.Net /// /// Class MimeTypes. /// + /// + /// http://en.wikipedia.org/wiki/Internet_media_type + /// https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types + /// http://www.iana.org/assignments/media-types/media-types.xhtml public static class MimeTypes { /// @@ -50,81 +54,26 @@ namespace MediaBrowser.Model.Net ".wtv", }; - // http://en.wikipedia.org/wiki/Internet_media_type - // https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types - // http://www.iana.org/assignments/media-types/media-types.xhtml - // Add more as needed + /// + /// Used for extensions not in or to override them. + /// private static readonly Dictionary _mimeTypeLookup = new Dictionary(StringComparer.OrdinalIgnoreCase) { // Type application - { ".7z", "application/x-7z-compressed" }, - { ".azw", "application/vnd.amazon.ebook" }, { ".azw3", "application/vnd.amazon.ebook" }, - { ".cbz", "application/x-cbz" }, - { ".cbr", "application/epub+zip" }, - { ".eot", "application/vnd.ms-fontobject" }, - { ".epub", "application/epub+zip" }, - { ".js", "application/x-javascript" }, - { ".json", "application/json" }, - { ".m3u8", "application/x-mpegURL" }, - { ".map", "application/x-javascript" }, - { ".mobi", "application/x-mobipocket-ebook" }, - { ".opf", "application/oebps-package+xml" }, - { ".pdf", "application/pdf" }, - { ".rar", "application/vnd.rar" }, - { ".srt", "application/x-subrip" }, - { ".ttml", "application/ttml+xml" }, - { ".wasm", "application/wasm" }, - { ".xml", "application/xml" }, - { ".zip", "application/zip" }, // Type image - { ".bmp", "image/bmp" }, - { ".gif", "image/gif" }, - { ".ico", "image/vnd.microsoft.icon" }, - { ".jpg", "image/jpeg" }, - { ".jpeg", "image/jpeg" }, - { ".png", "image/png" }, - { ".svg", "image/svg+xml" }, - { ".svgz", "image/svg+xml" }, { ".tbn", "image/jpeg" }, - { ".tif", "image/tiff" }, - { ".tiff", "image/tiff" }, - { ".webp", "image/webp" }, - - // Type font - { ".ttf", "font/ttf" }, - { ".woff", "font/woff" }, - { ".woff2", "font/woff2" }, // Type text { ".ass", "text/x-ssa" }, { ".ssa", "text/x-ssa" }, - { ".css", "text/css" }, - { ".csv", "text/csv" }, { ".edl", "text/plain" }, - { ".rtf", "text/rtf" }, - { ".txt", "text/plain" }, - { ".vtt", "text/vtt" }, + { ".html", "text/html; charset=UTF-8" }, + { ".htm", "text/html; charset=UTF-8" }, // Type video - { ".3gp", "video/3gpp" }, - { ".3g2", "video/3gpp2" }, - { ".asf", "video/x-ms-asf" }, - { ".avi", "video/x-msvideo" }, - { ".flv", "video/x-flv" }, - { ".mp4", "video/mp4" }, - { ".m4s", "video/mp4" }, - { ".m4v", "video/x-m4v" }, { ".mpegts", "video/mp2t" }, - { ".mpg", "video/mpeg" }, - { ".mkv", "video/x-matroska" }, - { ".mov", "video/quicktime" }, - { ".mpd", "video/vnd.mpeg.dash.mpd" }, - { ".ogv", "video/ogg" }, - { ".ts", "video/mp2t" }, - { ".webm", "video/webm" }, - { ".wmv", "video/x-ms-wmv" }, // Type audio { ".aac", "audio/aac" }, @@ -133,37 +82,47 @@ namespace MediaBrowser.Model.Net { ".dsf", "audio/dsf" }, { ".dsp", "audio/dsp" }, { ".flac", "audio/flac" }, - { ".m4a", "audio/mp4" }, { ".m4b", "audio/m4b" }, - { ".mid", "audio/midi" }, - { ".midi", "audio/midi" }, { ".mp3", "audio/mpeg" }, - { ".oga", "audio/ogg" }, - { ".ogg", "audio/ogg" }, - { ".opus", "audio/ogg" }, { ".vorbis", "audio/vorbis" }, - { ".wav", "audio/wav" }, { ".webma", "audio/webm" }, - { ".wma", "audio/x-ms-wma" }, { ".wv", "audio/x-wavpack" }, { ".xsp", "audio/xsp" }, }; - private static readonly Dictionary _extensionLookup = CreateExtensionLookup(); - - private static Dictionary CreateExtensionLookup() + private static readonly Dictionary _extensionLookup = new Dictionary(StringComparer.OrdinalIgnoreCase) { - var dict = _mimeTypeLookup - .GroupBy(i => i.Value) - .ToDictionary(x => x.Key, x => x.First().Key, StringComparer.OrdinalIgnoreCase); + // Type application + { "application/x-cbz", ".cbz" }, + { "application/x-javascript", ".js" }, + { "application/xml", ".xml" }, + { "application/x-mpegURL", ".m3u8" }, + + // Type audio + { "audio/aac", ".aac" }, + { "audio/ac3", ".ac3" }, + { "audio/dsf", ".dsf" }, + { "audio/dsp", ".dsp" }, + { "audio/flac", ".flac" }, + { "audio/m4b", ".m4b" }, + { "audio/vorbis", ".vorbis" }, + { "audio/x-ape", ".ape" }, + { "audio/xsp", ".xsp" }, + { "audio/x-wavpack", ".wv" }, - dict["image/jpg"] = ".jpg"; - dict["image/x-png"] = ".png"; + // Type image + { "image/jpg", ".jpg" }, + { "image/x-png", ".png" }, - dict["audio/x-aac"] = ".aac"; + // Type text + { "text/plain", ".txt" }, + { "text/rtf", ".rtf" }, + { "text/x-ssa", ".ssa" }, - return dict; - } + // Type video + { "video/vnd.mpeg.dash.mpd", ".mpd" }, + { "video/x-matroska", ".mkv" }, + }; public static string GetMimeType(string path) => GetMimeType(path, "application/octet-stream"); @@ -188,29 +147,15 @@ namespace MediaBrowser.Model.Net return result; } - // Catch-all for all video types that don't require specific mime types - if (_videoFileExtensions.Contains(ext)) - { - return string.Concat("video/", ext.AsSpan(1)); - } - - // Type text - if (string.Equals(ext, ".html", StringComparison.OrdinalIgnoreCase) - || string.Equals(ext, ".htm", StringComparison.OrdinalIgnoreCase)) - { - return "text/html; charset=UTF-8"; - } - - if (string.Equals(ext, ".log", StringComparison.OrdinalIgnoreCase) - || string.Equals(ext, ".srt", StringComparison.OrdinalIgnoreCase)) + if (Model.MimeTypes.TryGetMimeType(filename, out var mimeType)) { - return "text/plain"; + return mimeType; } - // Misc - if (string.Equals(ext, ".dll", StringComparison.OrdinalIgnoreCase)) + // Catch-all for all video types that don't require specific mime types + if (_videoFileExtensions.Contains(ext)) { - return "application/octet-stream"; + return string.Concat("video/", ext.AsSpan(1)); } return defaultValue; @@ -231,6 +176,12 @@ namespace MediaBrowser.Model.Net return result; } + var extensions = Model.MimeTypes.GetMimeTypeExtensions(mimeType); + if (extensions.Any()) + { + return "." + extensions.First(); + } + return null; } } diff --git a/tests/Jellyfin.Model.Tests/Net/MimeTypesTests.cs b/tests/Jellyfin.Model.Tests/Net/MimeTypesTests.cs new file mode 100644 index 000000000..b82607bf0 --- /dev/null +++ b/tests/Jellyfin.Model.Tests/Net/MimeTypesTests.cs @@ -0,0 +1,164 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using MediaBrowser.Model.Net; +using Xunit; + +namespace Jellyfin.Model.Tests.Net +{ + public class MimeTypesTests + { + [Theory] + [InlineData(".dll", "application/octet-stream")] + [InlineData(".log", "text/plain")] + [InlineData(".srt", "application/x-subrip")] + [InlineData(".html", "text/html; charset=UTF-8")] + [InlineData(".htm", "text/html; charset=UTF-8")] + [InlineData(".7z", "application/x-7z-compressed")] + [InlineData(".azw", "application/vnd.amazon.ebook")] + [InlineData(".azw3", "application/vnd.amazon.ebook")] + [InlineData(".eot", "application/vnd.ms-fontobject")] + [InlineData(".epub", "application/epub+zip")] + [InlineData(".json", "application/json")] + [InlineData(".mobi", "application/x-mobipocket-ebook")] + [InlineData(".opf", "application/oebps-package+xml")] + [InlineData(".pdf", "application/pdf")] + [InlineData(".rar", "application/vnd.rar")] + [InlineData(".ttml", "application/ttml+xml")] + [InlineData(".wasm", "application/wasm")] + [InlineData(".xml", "application/xml")] + [InlineData(".zip", "application/zip")] + [InlineData(".bmp", "image/bmp")] + [InlineData(".gif", "image/gif")] + [InlineData(".ico", "image/vnd.microsoft.icon")] + [InlineData(".jpg", "image/jpeg")] + [InlineData(".jpeg", "image/jpeg")] + [InlineData(".png", "image/png")] + [InlineData(".svg", "image/svg+xml")] + [InlineData(".svgz", "image/svg+xml")] + [InlineData(".tbn", "image/jpeg")] + [InlineData(".tif", "image/tiff")] + [InlineData(".tiff", "image/tiff")] + [InlineData(".webp", "image/webp")] + [InlineData(".ttf", "font/ttf")] + [InlineData(".woff", "font/woff")] + [InlineData(".woff2", "font/woff2")] + [InlineData(".ass", "text/x-ssa")] + [InlineData(".ssa", "text/x-ssa")] + [InlineData(".css", "text/css")] + [InlineData(".csv", "text/csv")] + [InlineData(".edl", "text/plain")] + [InlineData(".txt", "text/plain")] + [InlineData(".vtt", "text/vtt")] + [InlineData(".3gp", "video/3gpp")] + [InlineData(".3g2", "video/3gpp2")] + [InlineData(".asf", "video/x-ms-asf")] + [InlineData(".avi", "video/x-msvideo")] + [InlineData(".flv", "video/x-flv")] + [InlineData(".mp4", "video/mp4")] + [InlineData(".m4v", "video/x-m4v")] + [InlineData(".mpegts", "video/mp2t")] + [InlineData(".mpg", "video/mpeg")] + [InlineData(".mkv", "video/x-matroska")] + [InlineData(".mov", "video/quicktime")] + [InlineData(".ogv", "video/ogg")] + [InlineData(".ts", "video/mp2t")] + [InlineData(".webm", "video/webm")] + [InlineData(".wmv", "video/x-ms-wmv")] + [InlineData(".aac", "audio/aac")] + [InlineData(".ac3", "audio/ac3")] + [InlineData(".ape", "audio/x-ape")] + [InlineData(".dsf", "audio/dsf")] + [InlineData(".dsp", "audio/dsp")] + [InlineData(".flac", "audio/flac")] + [InlineData(".m4a", "audio/mp4")] + [InlineData(".m4b", "audio/m4b")] + [InlineData(".mid", "audio/midi")] + [InlineData(".midi", "audio/midi")] + [InlineData(".mp3", "audio/mpeg")] + [InlineData(".oga", "audio/ogg")] + [InlineData(".ogg", "audio/ogg")] + [InlineData(".opus", "audio/ogg")] + [InlineData(".vorbis", "audio/vorbis")] + [InlineData(".wav", "audio/wav")] + [InlineData(".webma", "audio/webm")] + [InlineData(".wma", "audio/x-ms-wma")] + [InlineData(".wv", "audio/x-wavpack")] + [InlineData(".xsp", "audio/xsp")] + public void GetMimeType(string input, string expectedResult) + { + Assert.Equal(expectedResult, MimeTypes.GetMimeType(input, null)); + } + + [Theory] + [InlineData("application/epub+zip", ".epub")] + [InlineData("application/json", ".json")] + [InlineData("application/oebps-package+xml", ".opf")] + [InlineData("application/pdf", ".pdf")] + [InlineData("application/ttml+xml", ".ttml")] + [InlineData("application/vnd.amazon.ebook", ".azw")] + [InlineData("application/vnd.ms-fontobject", ".eot")] + [InlineData("application/vnd.rar", ".rar")] + [InlineData("application/wasm", ".wasm")] + [InlineData("application/x-7z-compressed", ".7z")] + [InlineData("application/x-cbz", ".cbz")] + [InlineData("application/x-javascript", ".js")] + [InlineData("application/x-mobipocket-ebook", ".mobi")] + [InlineData("application/x-mpegURL", ".m3u8")] + [InlineData("application/x-subrip", ".srt")] + [InlineData("application/xml", ".xml")] + [InlineData("application/zip", ".zip")] + [InlineData("audio/aac", ".aac")] + [InlineData("audio/ac3", ".ac3")] + [InlineData("audio/dsf", ".dsf")] + [InlineData("audio/dsp", ".dsp")] + [InlineData("audio/flac", ".flac")] + [InlineData("audio/m4b", ".m4b")] + [InlineData("audio/mp4", ".m4a")] + [InlineData("audio/vorbis", ".vorbis")] + [InlineData("audio/wav", ".wav")] + [InlineData("audio/x-aac", ".aac")] + [InlineData("audio/x-ape", ".ape")] + [InlineData("audio/x-ms-wma", ".wma")] + [InlineData("audio/x-wavpack", ".wv")] + [InlineData("audio/xsp", ".xsp")] + [InlineData("font/ttf", ".ttf")] + [InlineData("font/woff", ".woff")] + [InlineData("font/woff2", ".woff2")] + [InlineData("image/bmp", ".bmp")] + [InlineData("image/gif", ".gif")] + [InlineData("image/jpg", ".jpg")] + [InlineData("image/png", ".png")] + [InlineData("image/svg+xml", ".svg")] + [InlineData("image/tiff", ".tif")] + [InlineData("image/vnd.microsoft.icon", ".ico")] + [InlineData("image/webp", ".webp")] + [InlineData("image/x-png", ".png")] + [InlineData("text/css", ".css")] + [InlineData("text/csv", ".csv")] + [InlineData("text/plain", ".txt")] + [InlineData("text/rtf", ".rtf")] + [InlineData("text/vtt", ".vtt")] + [InlineData("text/x-ssa", ".ssa")] + [InlineData("video/3gpp", ".3gp")] + [InlineData("video/3gpp2", ".3g2")] + [InlineData("video/mp2t", ".ts")] + [InlineData("video/mp4", ".mp4")] + [InlineData("video/ogg", ".ogv")] + [InlineData("video/quicktime", ".mov")] + [InlineData("video/vnd.mpeg.dash.mpd", ".mpd")] + [InlineData("video/webm", ".webm")] + [InlineData("video/x-flv", ".flv")] + [InlineData("video/x-m4v", ".m4v")] + [InlineData("video/x-matroska", ".mkv")] + [InlineData("video/x-ms-asf", ".asf")] + [InlineData("video/x-ms-wmv", ".wmv")] + [InlineData("video/x-msvideo", ".avi")] + public void ToExtension(string input, string expectedResult) + { + Assert.Equal(expectedResult, MimeTypes.ToExtension(input)); + } + } +} -- cgit v1.2.3 From fa6f6515a6874a5fca4267c50e6c597a2042ad96 Mon Sep 17 00:00:00 2001 From: Ahmed Rafiq Date: Sat, 4 Dec 2021 21:14:16 +0600 Subject: Update unit test name Co-authored-by: Claus Vium --- tests/Jellyfin.Model.Tests/Net/MimeTypesTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/Jellyfin.Model.Tests/Net/MimeTypesTests.cs b/tests/Jellyfin.Model.Tests/Net/MimeTypesTests.cs index b82607bf0..637424e27 100644 --- a/tests/Jellyfin.Model.Tests/Net/MimeTypesTests.cs +++ b/tests/Jellyfin.Model.Tests/Net/MimeTypesTests.cs @@ -87,7 +87,7 @@ namespace Jellyfin.Model.Tests.Net [InlineData(".wma", "audio/x-ms-wma")] [InlineData(".wv", "audio/x-wavpack")] [InlineData(".xsp", "audio/xsp")] - public void GetMimeType(string input, string expectedResult) + public void GetMimeType_Valid_ReturnsCorrectResult(string input, string expectedResult) { Assert.Equal(expectedResult, MimeTypes.GetMimeType(input, null)); } -- cgit v1.2.3 From cf75f99f0e4d765cc7dfa928b3a508121f538db4 Mon Sep 17 00:00:00 2001 From: Ahmed Rafiq Date: Sat, 4 Dec 2021 21:14:52 +0600 Subject: Update unit test name Co-authored-by: Claus Vium --- tests/Jellyfin.Model.Tests/Net/MimeTypesTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/Jellyfin.Model.Tests/Net/MimeTypesTests.cs b/tests/Jellyfin.Model.Tests/Net/MimeTypesTests.cs index 637424e27..55050cc95 100644 --- a/tests/Jellyfin.Model.Tests/Net/MimeTypesTests.cs +++ b/tests/Jellyfin.Model.Tests/Net/MimeTypesTests.cs @@ -156,7 +156,7 @@ namespace Jellyfin.Model.Tests.Net [InlineData("video/x-ms-asf", ".asf")] [InlineData("video/x-ms-wmv", ".wmv")] [InlineData("video/x-msvideo", ".avi")] - public void ToExtension(string input, string expectedResult) + public void ToExtension_Valid_ReturnsCorrectResult(string input, string expectedResult) { Assert.Equal(expectedResult, MimeTypes.ToExtension(input)); } -- cgit v1.2.3