Multiple Stream changes

* Remove useless MemoryStream in DlnaHttpClient
* Use HttpContent.ReadFromJsonAsync extension
* Call ConfigureAwait for IAsyncDisposable
* Use HttpContent.CopyToAsync where possible
This commit is contained in:
Bond_009 2023-10-11 18:32:57 +02:00
parent 26571a8c51
commit d7748cfa04
25 changed files with 195 additions and 214 deletions

View File

@ -55,21 +55,21 @@ namespace Emby.Dlna.PlayTo
var client = _httpClientFactory.CreateClient(NamedClient.Dlna); var client = _httpClientFactory.CreateClient(NamedClient.Dlna);
using var response = await client.SendAsync(request, cancellationToken).ConfigureAwait(false); using var response = await client.SendAsync(request, cancellationToken).ConfigureAwait(false);
response.EnsureSuccessStatusCode(); response.EnsureSuccessStatusCode();
await using MemoryStream ms = new MemoryStream(); Stream stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
await response.Content.CopyToAsync(ms, cancellationToken).ConfigureAwait(false); await using (stream.ConfigureAwait(false))
ms.Position = 0; {
try try
{ {
return await XDocument.LoadAsync( return await XDocument.LoadAsync(
ms, stream,
LoadOptions.None, LoadOptions.None,
cancellationToken).ConfigureAwait(false); cancellationToken).ConfigureAwait(false);
} }
catch (XmlException) catch (XmlException)
{ {
// try correcting the Xml response with common errors // try correcting the Xml response with common errors
ms.Position = 0; stream.Position = 0;
using StreamReader sr = new StreamReader(ms); using StreamReader sr = new StreamReader(stream);
var xmlString = await sr.ReadToEndAsync(cancellationToken).ConfigureAwait(false); var xmlString = await sr.ReadToEndAsync(cancellationToken).ConfigureAwait(false);
// find and replace unescaped ampersands (&) // find and replace unescaped ampersands (&)
@ -93,6 +93,7 @@ namespace Emby.Dlna.PlayTo
} }
} }
} }
}
public async Task<XDocument?> GetDataAsync(string url, CancellationToken cancellationToken) public async Task<XDocument?> GetDataAsync(string url, CancellationToken cancellationToken)
{ {

View File

@ -371,9 +371,12 @@ namespace Emby.Server.Implementations.Channels
Directory.CreateDirectory(Path.GetDirectoryName(path)); Directory.CreateDirectory(Path.GetDirectoryName(path));
await using FileStream createStream = File.Create(path); FileStream createStream = File.Create(path);
await using (createStream.ConfigureAwait(false))
{
await JsonSerializer.SerializeAsync(createStream, mediaSources, _jsonOptions).ConfigureAwait(false); await JsonSerializer.SerializeAsync(createStream, mediaSources, _jsonOptions).ConfigureAwait(false);
} }
}
/// <inheritdoc /> /// <inheritdoc />
public IEnumerable<MediaSourceInfo> GetStaticMediaSources(BaseItem item, CancellationToken cancellationToken) public IEnumerable<MediaSourceInfo> GetStaticMediaSources(BaseItem item, CancellationToken cancellationToken)

View File

@ -43,8 +43,6 @@
<TargetFramework>net7.0</TargetFramework> <TargetFramework>net7.0</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo> <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<GenerateDocumentationFile>true</GenerateDocumentationFile> <GenerateDocumentationFile>true</GenerateDocumentationFile>
<!-- https://github.com/microsoft/ApplicationInsights-dotnet/issues/2047 -->
<NoWarn>AD0001</NoWarn>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' "> <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">

View File

@ -48,15 +48,20 @@ namespace Emby.Server.Implementations.Library
if (!string.IsNullOrEmpty(cacheKey)) if (!string.IsNullOrEmpty(cacheKey))
{ {
FileStream jsonStream = AsyncFile.OpenRead(cacheFilePath);
try try
{ {
await using FileStream jsonStream = AsyncFile.OpenRead(cacheFilePath);
mediaInfo = await JsonSerializer.DeserializeAsync<MediaInfo>(jsonStream, _jsonOptions, cancellationToken).ConfigureAwait(false); mediaInfo = await JsonSerializer.DeserializeAsync<MediaInfo>(jsonStream, _jsonOptions, cancellationToken).ConfigureAwait(false);
// _logger.LogDebug("Found cached media info"); // _logger.LogDebug("Found cached media info");
} }
catch catch (Exception ex)
{ {
_logger.LogError(ex, "Error deserializing mediainfo cache");
}
finally
{
await jsonStream.DisposeAsync().ConfigureAwait(false);
} }
} }
@ -84,10 +89,13 @@ namespace Emby.Server.Implementations.Library
if (cacheFilePath is not null) if (cacheFilePath is not null)
{ {
Directory.CreateDirectory(Path.GetDirectoryName(cacheFilePath)); Directory.CreateDirectory(Path.GetDirectoryName(cacheFilePath));
await using FileStream createStream = AsyncFile.OpenWrite(cacheFilePath); FileStream createStream = AsyncFile.OpenWrite(cacheFilePath);
await using (createStream.ConfigureAwait(false))
{
await JsonSerializer.SerializeAsync(createStream, mediaInfo, _jsonOptions, cancellationToken).ConfigureAwait(false); await JsonSerializer.SerializeAsync(createStream, mediaInfo, _jsonOptions, cancellationToken).ConfigureAwait(false);
}
// _logger.LogDebug("Saved media info to {0}", cacheFilePath); _logger.LogDebug("Saved media info to {0}", cacheFilePath);
} }
} }

View File

@ -625,17 +625,19 @@ namespace Emby.Server.Implementations.Library
if (!string.IsNullOrEmpty(cacheKey)) if (!string.IsNullOrEmpty(cacheKey))
{ {
FileStream jsonStream = AsyncFile.OpenRead(cacheFilePath);
try try
{ {
await using FileStream jsonStream = AsyncFile.OpenRead(cacheFilePath);
mediaInfo = await JsonSerializer.DeserializeAsync<MediaInfo>(jsonStream, _jsonOptions, cancellationToken).ConfigureAwait(false); mediaInfo = await JsonSerializer.DeserializeAsync<MediaInfo>(jsonStream, _jsonOptions, cancellationToken).ConfigureAwait(false);
// _logger.LogDebug("Found cached media info");
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogDebug(ex, "_jsonSerializer.DeserializeFromFile threw an exception."); _logger.LogDebug(ex, "_jsonSerializer.DeserializeFromFile threw an exception.");
} }
finally
{
await jsonStream.DisposeAsync().ConfigureAwait(false);
}
} }
if (mediaInfo is null) if (mediaInfo is null)
@ -664,8 +666,11 @@ namespace Emby.Server.Implementations.Library
if (cacheFilePath is not null) if (cacheFilePath is not null)
{ {
Directory.CreateDirectory(Path.GetDirectoryName(cacheFilePath)); Directory.CreateDirectory(Path.GetDirectoryName(cacheFilePath));
await using FileStream createStream = File.Create(cacheFilePath); FileStream createStream = File.Create(cacheFilePath);
await using (createStream.ConfigureAwait(false))
{
await JsonSerializer.SerializeAsync(createStream, mediaInfo, _jsonOptions, cancellationToken).ConfigureAwait(false); await JsonSerializer.SerializeAsync(createStream, mediaInfo, _jsonOptions, cancellationToken).ConfigureAwait(false);
}
// _logger.LogDebug("Saved media info to {0}", cacheFilePath); // _logger.LogDebug("Saved media info to {0}", cacheFilePath);
} }

View File

@ -1851,7 +1851,8 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
return; return;
} }
await using (var stream = new FileStream(nfoPath, FileMode.CreateNew, FileAccess.Write, FileShare.None)) var stream = new FileStream(nfoPath, FileMode.CreateNew, FileAccess.Write, FileShare.None);
await using (stream.ConfigureAwait(false))
{ {
var settings = new XmlWriterSettings var settings = new XmlWriterSettings
{ {
@ -1860,7 +1861,8 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
Async = true Async = true
}; };
await using (var writer = XmlWriter.Create(stream, settings)) var writer = XmlWriter.Create(stream, settings);
await using (writer.ConfigureAwait(false))
{ {
await writer.WriteStartDocumentAsync(true).ConfigureAwait(false); await writer.WriteStartDocumentAsync(true).ConfigureAwait(false);
await writer.WriteStartElementAsync(null, "tvshow", null).ConfigureAwait(false); await writer.WriteStartElementAsync(null, "tvshow", null).ConfigureAwait(false);
@ -1914,7 +1916,8 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
return; return;
} }
await using (var stream = new FileStream(nfoPath, FileMode.CreateNew, FileAccess.Write, FileShare.None)) var stream = new FileStream(nfoPath, FileMode.CreateNew, FileAccess.Write, FileShare.None);
await using (stream.ConfigureAwait(false))
{ {
var settings = new XmlWriterSettings var settings = new XmlWriterSettings
{ {
@ -1927,7 +1930,8 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
var isSeriesEpisode = timer.IsProgramSeries; var isSeriesEpisode = timer.IsProgramSeries;
await using (var writer = XmlWriter.Create(stream, settings)) var writer = XmlWriter.Create(stream, settings);
await using (writer.ConfigureAwait(false))
{ {
await writer.WriteStartDocumentAsync(true).ConfigureAwait(false); await writer.WriteStartDocumentAsync(true).ConfigureAwait(false);
@ -1965,7 +1969,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
} }
else else
{ {
await writer.WriteStartElementAsync(null, "movie", null); await writer.WriteStartElementAsync(null, "movie", null).ConfigureAwait(false);
if (!string.IsNullOrWhiteSpace(item.Name)) if (!string.IsNullOrWhiteSpace(item.Name))
{ {

View File

@ -106,8 +106,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
options.Content = JsonContent.Create(requestList, options: _jsonOptions); options.Content = JsonContent.Create(requestList, options: _jsonOptions);
options.Headers.TryAddWithoutValidation("token", token); options.Headers.TryAddWithoutValidation("token", token);
using var response = await Send(options, true, info, cancellationToken).ConfigureAwait(false); using var response = await Send(options, true, info, cancellationToken).ConfigureAwait(false);
await using var responseStream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false); var dailySchedules = await response.Content.ReadFromJsonAsync<IReadOnlyList<DayDto>>(_jsonOptions, cancellationToken).ConfigureAwait(false);
var dailySchedules = await JsonSerializer.DeserializeAsync<IReadOnlyList<DayDto>>(responseStream, _jsonOptions, cancellationToken).ConfigureAwait(false);
if (dailySchedules is null) if (dailySchedules is null)
{ {
return Array.Empty<ProgramInfo>(); return Array.Empty<ProgramInfo>();
@ -122,8 +121,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
programRequestOptions.Content = JsonContent.Create(programIds, options: _jsonOptions); programRequestOptions.Content = JsonContent.Create(programIds, options: _jsonOptions);
using var innerResponse = await Send(programRequestOptions, true, info, cancellationToken).ConfigureAwait(false); using var innerResponse = await Send(programRequestOptions, true, info, cancellationToken).ConfigureAwait(false);
await using var innerResponseStream = await innerResponse.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false); var programDetails = await innerResponse.Content.ReadFromJsonAsync<IReadOnlyList<ProgramDetailsDto>>(_jsonOptions, cancellationToken).ConfigureAwait(false);
var programDetails = await JsonSerializer.DeserializeAsync<IReadOnlyList<ProgramDetailsDto>>(innerResponseStream, _jsonOptions, cancellationToken).ConfigureAwait(false);
if (programDetails is null) if (programDetails is null)
{ {
return Array.Empty<ProgramInfo>(); return Array.Empty<ProgramInfo>();
@ -482,8 +480,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
try try
{ {
using var innerResponse2 = await Send(message, true, info, cancellationToken).ConfigureAwait(false); using var innerResponse2 = await Send(message, true, info, cancellationToken).ConfigureAwait(false);
await using var response = await innerResponse2.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false); return await innerResponse2.Content.ReadFromJsonAsync<IReadOnlyList<ShowImagesDto>>(_jsonOptions, cancellationToken).ConfigureAwait(false);
return await JsonSerializer.DeserializeAsync<IReadOnlyList<ShowImagesDto>>(response, _jsonOptions, cancellationToken).ConfigureAwait(false);
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -510,10 +507,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
try try
{ {
using var httpResponse = await Send(options, false, info, cancellationToken).ConfigureAwait(false); using var httpResponse = await Send(options, false, info, cancellationToken).ConfigureAwait(false);
await using var response = await httpResponse.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false); var root = await httpResponse.Content.ReadFromJsonAsync<IReadOnlyList<HeadendsDto>>(_jsonOptions, cancellationToken).ConfigureAwait(false);
var root = await JsonSerializer.DeserializeAsync<IReadOnlyList<HeadendsDto>>(response, _jsonOptions, cancellationToken).ConfigureAwait(false);
if (root is not null) if (root is not null)
{ {
foreach (HeadendsDto headend in root) foreach (HeadendsDto headend in root)
@ -649,8 +643,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
using var response = await Send(options, false, null, cancellationToken).ConfigureAwait(false); using var response = await Send(options, false, null, cancellationToken).ConfigureAwait(false);
response.EnsureSuccessStatusCode(); response.EnsureSuccessStatusCode();
await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false); var root = await response.Content.ReadFromJsonAsync<TokenDto>(_jsonOptions, cancellationToken).ConfigureAwait(false);
var root = await JsonSerializer.DeserializeAsync<TokenDto>(stream, _jsonOptions, cancellationToken).ConfigureAwait(false);
if (string.Equals(root?.Message, "OK", StringComparison.Ordinal)) if (string.Equals(root?.Message, "OK", StringComparison.Ordinal))
{ {
_logger.LogInformation("Authenticated with Schedules Direct token: {Token}", root.Token); _logger.LogInformation("Authenticated with Schedules Direct token: {Token}", root.Token);
@ -691,10 +684,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
{ {
using var httpResponse = await Send(options, false, null, cancellationToken).ConfigureAwait(false); using var httpResponse = await Send(options, false, null, cancellationToken).ConfigureAwait(false);
httpResponse.EnsureSuccessStatusCode(); httpResponse.EnsureSuccessStatusCode();
await using var stream = await httpResponse.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false); var root = await httpResponse.Content.ReadFromJsonAsync<LineupsDto>(_jsonOptions, cancellationToken).ConfigureAwait(false);
using var response = httpResponse.Content;
var root = await JsonSerializer.DeserializeAsync<LineupsDto>(stream, _jsonOptions, cancellationToken).ConfigureAwait(false);
return root?.Lineups.Any(i => string.Equals(info.ListingsId, i.Lineup, StringComparison.OrdinalIgnoreCase)) ?? false; return root?.Lineups.Any(i => string.Equals(info.ListingsId, i.Lineup, StringComparison.OrdinalIgnoreCase)) ?? false;
} }
catch (HttpRequestException ex) catch (HttpRequestException ex)
@ -748,8 +738,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
options.Headers.TryAddWithoutValidation("token", token); options.Headers.TryAddWithoutValidation("token", token);
using var httpResponse = await Send(options, true, info, cancellationToken).ConfigureAwait(false); using var httpResponse = await Send(options, true, info, cancellationToken).ConfigureAwait(false);
await using var stream = await httpResponse.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false); var root = await httpResponse.Content.ReadFromJsonAsync<ChannelDto>(_jsonOptions, cancellationToken).ConfigureAwait(false);
var root = await JsonSerializer.DeserializeAsync<ChannelDto>(stream, _jsonOptions, cancellationToken).ConfigureAwait(false);
if (root is null) if (root is null)
{ {
return new List<ChannelInfo>(); return new List<ChannelInfo>();

View File

@ -9,6 +9,7 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Net; using System.Net;
using System.Net.Http; using System.Net.Http;
using System.Net.Http.Json;
using System.Text.Json; using System.Text.Json;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -76,13 +77,10 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
var model = await GetModelInfo(info, false, cancellationToken).ConfigureAwait(false); var model = await GetModelInfo(info, false, cancellationToken).ConfigureAwait(false);
using var response = await _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(model.LineupURL ?? model.BaseURL + "/lineup.json", HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); using var response = await _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(model.LineupURL ?? model.BaseURL + "/lineup.json", HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false); var lineup = await response.Content.ReadFromJsonAsync<IEnumerable<Channels>>(_jsonOptions, cancellationToken).ConfigureAwait(false) ?? Enumerable.Empty<Channels>();
var lineup = await JsonSerializer.DeserializeAsync<List<Channels>>(stream, _jsonOptions, cancellationToken)
.ConfigureAwait(false) ?? new List<Channels>();
if (info.ImportFavoritesOnly) if (info.ImportFavoritesOnly)
{ {
lineup = lineup.Where(i => i.Favorite).ToList(); lineup = lineup.Where(i => i.Favorite);
} }
return lineup.Where(i => !i.DRM).ToList(); return lineup.Where(i => !i.DRM).ToList();
@ -129,9 +127,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
.GetAsync(GetApiUrl(info) + "/discover.json", HttpCompletionOption.ResponseHeadersRead, cancellationToken) .GetAsync(GetApiUrl(info) + "/discover.json", HttpCompletionOption.ResponseHeadersRead, cancellationToken)
.ConfigureAwait(false); .ConfigureAwait(false);
response.EnsureSuccessStatusCode(); response.EnsureSuccessStatusCode();
await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false); var discoverResponse = await response.Content.ReadFromJsonAsync<DiscoverResponse>(_jsonOptions, cancellationToken).ConfigureAwait(false);
var discoverResponse = await JsonSerializer.DeserializeAsync<DiscoverResponse>(stream, _jsonOptions, cancellationToken)
.ConfigureAwait(false);
if (!string.IsNullOrEmpty(cacheKey)) if (!string.IsNullOrEmpty(cacheKey))
{ {
@ -175,9 +171,11 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
using var response = await _httpClientFactory.CreateClient(NamedClient.Default) using var response = await _httpClientFactory.CreateClient(NamedClient.Default)
.GetAsync(string.Format(CultureInfo.InvariantCulture, "{0}/tuners.html", GetApiUrl(info)), HttpCompletionOption.ResponseHeadersRead, cancellationToken) .GetAsync(string.Format(CultureInfo.InvariantCulture, "{0}/tuners.html", GetApiUrl(info)), HttpCompletionOption.ResponseHeadersRead, cancellationToken)
.ConfigureAwait(false); .ConfigureAwait(false);
await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
using var sr = new StreamReader(stream, System.Text.Encoding.UTF8);
var tuners = new List<LiveTvTunerInfo>(); var tuners = new List<LiveTvTunerInfo>();
var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
await using (stream.ConfigureAwait(false))
{
using var sr = new StreamReader(stream, System.Text.Encoding.UTF8);
await foreach (var line in sr.ReadAllLinesAsync().ConfigureAwait(false)) await foreach (var line in sr.ReadAllLinesAsync().ConfigureAwait(false))
{ {
string stripedLine = StripXML(line); string stripedLine = StripXML(line);
@ -205,6 +203,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
}); });
} }
} }
}
return tuners; return tuners;
} }

View File

@ -71,8 +71,10 @@ namespace Emby.Server.Implementations.Localization
string countryCode = resource.Substring(RatingsPath.Length, 2); string countryCode = resource.Substring(RatingsPath.Length, 2);
var dict = new Dictionary<string, ParentalRating>(StringComparer.OrdinalIgnoreCase); var dict = new Dictionary<string, ParentalRating>(StringComparer.OrdinalIgnoreCase);
await using var stream = _assembly.GetManifestResourceStream(resource); var stream = _assembly.GetManifestResourceStream(resource);
using var reader = new StreamReader(stream!); // shouldn't be null here, we just got the resource path from Assembly.GetManifestResourceNames() await using (stream!.ConfigureAwait(false)) // shouldn't be null here, we just got the resource path from Assembly.GetManifestResourceNames()
{
using var reader = new StreamReader(stream!);
await foreach (var line in reader.ReadAllLinesAsync().ConfigureAwait(false)) await foreach (var line in reader.ReadAllLinesAsync().ConfigureAwait(false))
{ {
if (string.IsNullOrWhiteSpace(line)) if (string.IsNullOrWhiteSpace(line))
@ -92,6 +94,7 @@ namespace Emby.Server.Implementations.Localization
_logger.LogWarning("Malformed line in ratings file for country {CountryCode}", countryCode); _logger.LogWarning("Malformed line in ratings file for country {CountryCode}", countryCode);
} }
} }
}
_allParentalRatings[countryCode] = dict; _allParentalRatings[countryCode] = dict;
} }

View File

@ -386,11 +386,11 @@ namespace Emby.Server.Implementations.Plugins
var url = new Uri(packageInfo.ImageUrl); var url = new Uri(packageInfo.ImageUrl);
imagePath = Path.Join(path, url.Segments[^1]); imagePath = Path.Join(path, url.Segments[^1]);
await using var fileStream = AsyncFile.OpenWrite(imagePath); var fileStream = AsyncFile.OpenWrite(imagePath);
Stream? downloadStream = null;
try try
{ {
await using var downloadStream = await HttpClientFactory downloadStream = await HttpClientFactory
.CreateClient(NamedClient.Default) .CreateClient(NamedClient.Default)
.GetStreamAsync(url) .GetStreamAsync(url)
.ConfigureAwait(false); .ConfigureAwait(false);
@ -402,6 +402,14 @@ namespace Emby.Server.Implementations.Plugins
_logger.LogError(ex, "Failed to download image to path {Path} on disk.", imagePath); _logger.LogError(ex, "Failed to download image to path {Path} on disk.", imagePath);
imagePath = string.Empty; imagePath = string.Empty;
} }
finally
{
await fileStream.DisposeAsync().ConfigureAwait(false);
if (downloadStream is not null)
{
await downloadStream.DisposeAsync().ConfigureAwait(false);
}
}
} }
var manifest = new PluginManifest var manifest = new PluginManifest
@ -421,7 +429,7 @@ namespace Emby.Server.Implementations.Plugins
ImagePath = imagePath ImagePath = imagePath
}; };
if (!await ReconcileManifest(manifest, path)) if (!await ReconcileManifest(manifest, path).ConfigureAwait(false))
{ {
// An error occurred during reconciliation and saving could be undesirable. // An error occurred during reconciliation and saving could be undesirable.
return false; return false;
@ -458,7 +466,7 @@ namespace Emby.Server.Implementations.Plugins
} }
using var metaStream = File.OpenRead(metafile); using var metaStream = File.OpenRead(metafile);
var localManifest = await JsonSerializer.DeserializeAsync<PluginManifest>(metaStream, _jsonOptions); var localManifest = await JsonSerializer.DeserializeAsync<PluginManifest>(metaStream, _jsonOptions).ConfigureAwait(false);
localManifest ??= new PluginManifest(); localManifest ??= new PluginManifest();
if (!Equals(localManifest.Id, manifest.Id)) if (!Equals(localManifest.Id, manifest.Id))

View File

@ -520,10 +520,9 @@ namespace Emby.Server.Implementations.Updates
// CA5351: Do Not Use Broken Cryptographic Algorithms // CA5351: Do Not Use Broken Cryptographic Algorithms
#pragma warning disable CA5351 #pragma warning disable CA5351
using var md5 = MD5.Create();
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
var hash = Convert.ToHexString(md5.ComputeHash(stream)); var hash = Convert.ToHexString(await MD5.HashDataAsync(stream, cancellationToken).ConfigureAwait(false));
if (!string.Equals(package.Checksum, hash, StringComparison.OrdinalIgnoreCase)) if (!string.Equals(package.Checksum, hash, StringComparison.OrdinalIgnoreCase))
{ {
_logger.LogError( _logger.LogError(
@ -556,7 +555,7 @@ namespace Emby.Server.Implementations.Updates
reader.ExtractToDirectory(targetDir, true); reader.ExtractToDirectory(targetDir, true);
// Ensure we create one or populate existing ones with missing data. // Ensure we create one or populate existing ones with missing data.
await _pluginManager.PopulateManifest(package.PackageInfo, package.Version, targetDir, status); await _pluginManager.PopulateManifest(package.PackageInfo, package.Version, targetDir, status).ConfigureAwait(false);
_pluginManager.ImportPluginFrom(targetDir); _pluginManager.ImportPluginFrom(targetDir);
} }

View File

@ -8,8 +8,6 @@
<PropertyGroup> <PropertyGroup>
<TargetFramework>net7.0</TargetFramework> <TargetFramework>net7.0</TargetFramework>
<GenerateDocumentationFile>true</GenerateDocumentationFile> <GenerateDocumentationFile>true</GenerateDocumentationFile>
<!-- https://github.com/microsoft/ApplicationInsights-dotnet/issues/2047 -->
<NoWarn>AD0001</NoWarn>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -23,9 +23,12 @@ namespace MediaBrowser.Controller.ClientEvent
{ {
var fileName = $"upload_{clientName}_{clientVersion}_{DateTime.UtcNow:yyyyMMddHHmmss}_{Guid.NewGuid():N}.log"; var fileName = $"upload_{clientName}_{clientVersion}_{DateTime.UtcNow:yyyyMMddHHmmss}_{Guid.NewGuid():N}.log";
var logFilePath = Path.Combine(_applicationPaths.LogDirectoryPath, fileName); var logFilePath = Path.Combine(_applicationPaths.LogDirectoryPath, fileName);
await using var fileStream = new FileStream(logFilePath, FileMode.CreateNew, FileAccess.Write, FileShare.None); var fileStream = new FileStream(logFilePath, FileMode.CreateNew, FileAccess.Write, FileShare.None);
await using (fileStream.ConfigureAwait(false))
{
await fileContents.CopyToAsync(fileStream).ConfigureAwait(false); await fileContents.CopyToAsync(fileStream).ConfigureAwait(false);
return fileName; return fileName;
} }
} }
}
} }

View File

@ -176,17 +176,12 @@ namespace MediaBrowser.Providers.Plugins.AudioDb
Directory.CreateDirectory(Path.GetDirectoryName(path)); Directory.CreateDirectory(Path.GetDirectoryName(path));
using var response = await _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(url, cancellationToken).ConfigureAwait(false); using var response = await _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(url, cancellationToken).ConfigureAwait(false);
var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
await using (stream.ConfigureAwait(false))
{
var fileStreamOptions = AsyncFile.WriteOptions; var fileStreamOptions = AsyncFile.WriteOptions;
fileStreamOptions.Mode = FileMode.Create; fileStreamOptions.Mode = FileMode.Create;
fileStreamOptions.PreallocationSize = stream.Length; var fs = new FileStream(path, fileStreamOptions);
var xmlFileStream = new FileStream(path, fileStreamOptions); await using (fs.ConfigureAwait(false))
await using (xmlFileStream.ConfigureAwait(false))
{ {
await stream.CopyToAsync(xmlFileStream, cancellationToken).ConfigureAwait(false); await response.Content.CopyToAsync(fs, cancellationToken).ConfigureAwait(false);
}
} }
} }

View File

@ -154,20 +154,15 @@ namespace MediaBrowser.Providers.Plugins.AudioDb
using var response = await _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(url, cancellationToken).ConfigureAwait(false); using var response = await _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(url, cancellationToken).ConfigureAwait(false);
response.EnsureSuccessStatusCode(); response.EnsureSuccessStatusCode();
var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
await using (stream.ConfigureAwait(false))
{
var path = GetArtistInfoPath(_config.ApplicationPaths, musicBrainzId); var path = GetArtistInfoPath(_config.ApplicationPaths, musicBrainzId);
Directory.CreateDirectory(Path.GetDirectoryName(path)); Directory.CreateDirectory(Path.GetDirectoryName(path));
var fileStreamOptions = AsyncFile.WriteOptions; var fileStreamOptions = AsyncFile.WriteOptions;
fileStreamOptions.Mode = FileMode.Create; fileStreamOptions.Mode = FileMode.Create;
fileStreamOptions.PreallocationSize = stream.Length;
var xmlFileStream = new FileStream(path, fileStreamOptions); var xmlFileStream = new FileStream(path, fileStreamOptions);
await using (xmlFileStream.ConfigureAwait(false)) await using (xmlFileStream.ConfigureAwait(false))
{ {
await stream.CopyToAsync(xmlFileStream, cancellationToken).ConfigureAwait(false); await response.Content.CopyToAsync(xmlFileStream, cancellationToken).ConfigureAwait(false);
}
} }
} }

View File

@ -8,6 +8,7 @@ using System.Globalization;
using System.Linq; using System.Linq;
using System.Net; using System.Net;
using System.Net.Http; using System.Net.Http;
using System.Net.Http.Json;
using System.Text; using System.Text;
using System.Text.Json; using System.Text.Json;
using System.Threading; using System.Threading;
@ -137,12 +138,9 @@ namespace MediaBrowser.Providers.Plugins.Omdb
var url = OmdbProvider.GetOmdbUrl(urlQuery.ToString()); var url = OmdbProvider.GetOmdbUrl(urlQuery.ToString());
using var response = await _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(url, cancellationToken).ConfigureAwait(false); using var response = await _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(url, cancellationToken).ConfigureAwait(false);
var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
await using (stream.ConfigureAwait(false))
{
if (isSearch) if (isSearch)
{ {
var searchResultList = await JsonSerializer.DeserializeAsync<SearchResultList>(stream, _jsonOptions, cancellationToken).ConfigureAwait(false); var searchResultList = await response.Content.ReadFromJsonAsync<SearchResultList>(_jsonOptions, cancellationToken).ConfigureAwait(false);
if (searchResultList?.Search is not null) if (searchResultList?.Search is not null)
{ {
var resultCount = searchResultList.Search.Count; var resultCount = searchResultList.Search.Count;
@ -157,13 +155,12 @@ namespace MediaBrowser.Providers.Plugins.Omdb
} }
else else
{ {
var result = await JsonSerializer.DeserializeAsync<SearchResult>(stream, _jsonOptions, cancellationToken).ConfigureAwait(false); var result = await response.Content.ReadFromJsonAsync<SearchResult>(_jsonOptions, cancellationToken).ConfigureAwait(false);
if (string.Equals(result?.Response, "true", StringComparison.OrdinalIgnoreCase)) if (string.Equals(result?.Response, "true", StringComparison.OrdinalIgnoreCase))
{ {
return new[] { ResultToMetadataResult(result, searchInfo, indexNumberEnd) }; return new[] { ResultToMetadataResult(result, searchInfo, indexNumberEnd) };
} }
} }
}
return Enumerable.Empty<RemoteSearchResult>(); return Enumerable.Empty<RemoteSearchResult>();
} }

View File

@ -40,9 +40,7 @@ namespace Jellyfin.Server.Integration.Tests
using var authResponse = await client.SendAsync(httpRequest); using var authResponse = await client.SendAsync(httpRequest);
authResponse.EnsureSuccessStatusCode(); authResponse.EnsureSuccessStatusCode();
var auth = await JsonSerializer.DeserializeAsync<AuthenticationResultDto>( var auth = await authResponse.Content.ReadFromJsonAsync<AuthenticationResultDto>(jsonOptions);
await authResponse.Content.ReadAsStreamAsync(),
jsonOptions);
return auth!.AccessToken; return auth!.AccessToken;
} }
@ -51,8 +49,7 @@ namespace Jellyfin.Server.Integration.Tests
{ {
using var response = await client.GetAsync("Users/Me"); using var response = await client.GetAsync("Users/Me");
Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var userDto = await JsonSerializer.DeserializeAsync<UserDto>( var userDto = await response.Content.ReadFromJsonAsync<UserDto>(JsonDefaults.Options);
await response.Content.ReadAsStreamAsync(), JsonDefaults.Options);
Assert.NotNull(userDto); Assert.NotNull(userDto);
return userDto; return userDto;
} }
@ -67,9 +64,7 @@ namespace Jellyfin.Server.Integration.Tests
var response = await client.GetAsync($"Users/{userId}/Items/Root"); var response = await client.GetAsync($"Users/{userId}/Items/Root");
Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var rootDto = await JsonSerializer.DeserializeAsync<BaseItemDto>( var rootDto = await response.Content.ReadFromJsonAsync<BaseItemDto>(JsonDefaults.Options);
await response.Content.ReadAsStreamAsync(),
JsonDefaults.Options);
Assert.NotNull(rootDto); Assert.NotNull(rootDto);
return rootDto; return rootDto;
} }

View File

@ -1,4 +1,5 @@
using System.Net; using System.Net;
using System.Net.Http.Json;
using System.Net.Mime; using System.Net.Mime;
using System.Text; using System.Text;
using System.Text.Json; using System.Text.Json;
@ -30,8 +31,7 @@ namespace Jellyfin.Server.Integration.Tests
Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.Equal(MediaTypeNames.Application.Json, response.Content.Headers.ContentType?.MediaType); Assert.Equal(MediaTypeNames.Application.Json, response.Content.Headers.ContentType?.MediaType);
Assert.Equal(Encoding.UTF8.BodyName, response.Content.Headers.ContentType?.CharSet); Assert.Equal(Encoding.UTF8.BodyName, response.Content.Headers.ContentType?.CharSet);
var responseBody = await response.Content.ReadAsStreamAsync(); await response.Content.ReadFromJsonAsync<BrandingOptions>();
_ = await JsonSerializer.DeserializeAsync<BrandingOptions>(responseBody);
} }
[Theory] [Theory]

View File

@ -1,5 +1,6 @@
using System.IO; using System.IO;
using System.Net; using System.Net;
using System.Net.Http.Json;
using System.Net.Mime; using System.Net.Mime;
using System.Text; using System.Text;
using System.Text.Json; using System.Text.Json;
@ -64,8 +65,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var res = await response.Content.ReadAsStreamAsync(); _ = await response.Content.ReadFromJsonAsync<ConfigurationPageInfo[]>(_jsonOpions);
_ = await JsonSerializer.DeserializeAsync<ConfigurationPageInfo[]>(res, _jsonOpions);
// TODO: check content // TODO: check content
} }
@ -81,8 +81,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
Assert.Equal(MediaTypeNames.Application.Json, response.Content.Headers.ContentType?.MediaType); Assert.Equal(MediaTypeNames.Application.Json, response.Content.Headers.ContentType?.MediaType);
Assert.Equal(Encoding.UTF8.BodyName, response.Content.Headers.ContentType?.CharSet); Assert.Equal(Encoding.UTF8.BodyName, response.Content.Headers.ContentType?.CharSet);
var res = await response.Content.ReadAsStreamAsync(); var data = await response.Content.ReadFromJsonAsync<ConfigurationPageInfo[]>(_jsonOpions);
var data = await JsonSerializer.DeserializeAsync<ConfigurationPageInfo[]>(res, _jsonOpions);
Assert.NotNull(data); Assert.NotNull(data);
Assert.Empty(data); Assert.Empty(data);
} }

View File

@ -93,9 +93,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
Assert.Equal(MediaTypeNames.Application.Json, response.Content.Headers.ContentType?.MediaType); Assert.Equal(MediaTypeNames.Application.Json, response.Content.Headers.ContentType?.MediaType);
Assert.Equal(Encoding.UTF8.BodyName, response.Content.Headers.ContentType?.CharSet); Assert.Equal(Encoding.UTF8.BodyName, response.Content.Headers.ContentType?.CharSet);
var profiles = await JsonSerializer.DeserializeAsync<DeviceProfileInfo[]>( var profiles = await response.Content.ReadFromJsonAsync<DeviceProfileInfo[]>(_jsonOptions);
await response.Content.ReadAsStreamAsync(),
_jsonOptions);
var newProfile = profiles?.FirstOrDefault(x => string.Equals(x.Name, "ThisProfileIsNew", StringComparison.Ordinal)); var newProfile = profiles?.FirstOrDefault(x => string.Equals(x.Name, "ThisProfileIsNew", StringComparison.Ordinal));
Assert.NotNull(newProfile); Assert.NotNull(newProfile);
@ -124,9 +122,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
Assert.Equal(MediaTypeNames.Application.Json, response.Content.Headers.ContentType?.MediaType); Assert.Equal(MediaTypeNames.Application.Json, response.Content.Headers.ContentType?.MediaType);
Assert.Equal(Encoding.UTF8.BodyName, response.Content.Headers.ContentType?.CharSet); Assert.Equal(Encoding.UTF8.BodyName, response.Content.Headers.ContentType?.CharSet);
var profiles = await JsonSerializer.DeserializeAsync<DeviceProfileInfo[]>( var profiles = await response.Content.ReadFromJsonAsync<DeviceProfileInfo[]>(_jsonOptions);
await response.Content.ReadAsStreamAsync(),
_jsonOptions);
Assert.Null(profiles?.FirstOrDefault(x => string.Equals(x.Name, "ThisProfileIsNew", StringComparison.Ordinal))); Assert.Null(profiles?.FirstOrDefault(x => string.Equals(x.Name, "ThisProfileIsNew", StringComparison.Ordinal)));
var newProfile = profiles?.FirstOrDefault(x => string.Equals(x.Name, "ThisProfileIsUpdated", StringComparison.Ordinal)); var newProfile = profiles?.FirstOrDefault(x => string.Equals(x.Name, "ThisProfileIsUpdated", StringComparison.Ordinal));
@ -150,9 +146,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
Assert.Equal(MediaTypeNames.Application.Json, response.Content.Headers.ContentType?.MediaType); Assert.Equal(MediaTypeNames.Application.Json, response.Content.Headers.ContentType?.MediaType);
Assert.Equal(Encoding.UTF8.BodyName, response.Content.Headers.ContentType?.CharSet); Assert.Equal(Encoding.UTF8.BodyName, response.Content.Headers.ContentType?.CharSet);
var profiles = await JsonSerializer.DeserializeAsync<DeviceProfileInfo[]>( var profiles = await response.Content.ReadFromJsonAsync<DeviceProfileInfo[]>(_jsonOptions);
await response.Content.ReadAsStreamAsync(),
_jsonOptions);
Assert.Null(profiles?.FirstOrDefault(x => string.Equals(x.Name, "ThisProfileIsUpdated", StringComparison.Ordinal))); Assert.Null(profiles?.FirstOrDefault(x => string.Equals(x.Name, "ThisProfileIsUpdated", StringComparison.Ordinal)));
} }

View File

@ -1,6 +1,7 @@
using System; using System;
using System.Globalization; using System.Globalization;
using System.Net; using System.Net;
using System.Net.Http.Json;
using System.Text.Json; using System.Text.Json;
using System.Threading.Tasks; using System.Threading.Tasks;
using Jellyfin.Extensions.Json; using Jellyfin.Extensions.Json;
@ -56,9 +57,7 @@ public sealed class ItemsControllerTests : IClassFixture<JellyfinApplicationFact
var response = await client.GetAsync(string.Format(CultureInfo.InvariantCulture, format, userDto.Id)); var response = await client.GetAsync(string.Format(CultureInfo.InvariantCulture, format, userDto.Id));
Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var items = await JsonSerializer.DeserializeAsync<QueryResult<BaseItemDto>>( var items = await response.Content.ReadFromJsonAsync<QueryResult<BaseItemDto>>(_jsonOptions);
await response.Content.ReadAsStreamAsync(),
_jsonOptions);
Assert.NotNull(items); Assert.NotNull(items);
} }
} }

View File

@ -43,8 +43,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
Assert.Equal(HttpStatusCode.OK, getResponse.StatusCode); Assert.Equal(HttpStatusCode.OK, getResponse.StatusCode);
Assert.Equal(MediaTypeNames.Application.Json, getResponse.Content.Headers.ContentType?.MediaType); Assert.Equal(MediaTypeNames.Application.Json, getResponse.Content.Headers.ContentType?.MediaType);
using var responseStream = await getResponse.Content.ReadAsStreamAsync(); var newConfig = await getResponse.Content.ReadFromJsonAsync<StartupConfigurationDto>(_jsonOptions);
var newConfig = await JsonSerializer.DeserializeAsync<StartupConfigurationDto>(responseStream, _jsonOptions);
Assert.Equal(config.UICulture, newConfig!.UICulture); Assert.Equal(config.UICulture, newConfig!.UICulture);
Assert.Equal(config.MetadataCountryCode, newConfig.MetadataCountryCode); Assert.Equal(config.MetadataCountryCode, newConfig.MetadataCountryCode);
Assert.Equal(config.PreferredMetadataLanguage, newConfig.PreferredMetadataLanguage); Assert.Equal(config.PreferredMetadataLanguage, newConfig.PreferredMetadataLanguage);
@ -60,8 +59,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.Equal(MediaTypeNames.Application.Json, response.Content.Headers.ContentType?.MediaType); Assert.Equal(MediaTypeNames.Application.Json, response.Content.Headers.ContentType?.MediaType);
using var contentStream = await response.Content.ReadAsStreamAsync(); var user = await response.Content.ReadFromJsonAsync<StartupUserDto>(_jsonOptions);
var user = await JsonSerializer.DeserializeAsync<StartupUserDto>(contentStream, _jsonOptions);
Assert.NotNull(user); Assert.NotNull(user);
Assert.NotNull(user.Name); Assert.NotNull(user.Name);
Assert.NotEmpty(user.Name); Assert.NotEmpty(user.Name);
@ -87,8 +85,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
Assert.Equal(HttpStatusCode.OK, getResponse.StatusCode); Assert.Equal(HttpStatusCode.OK, getResponse.StatusCode);
Assert.Equal(MediaTypeNames.Application.Json, getResponse.Content.Headers.ContentType?.MediaType); Assert.Equal(MediaTypeNames.Application.Json, getResponse.Content.Headers.ContentType?.MediaType);
var contentStream = await getResponse.Content.ReadAsStreamAsync(); var newUser = await getResponse.Content.ReadFromJsonAsync<StartupUserDto>(_jsonOptions);
var newUser = await JsonSerializer.DeserializeAsync<StartupUserDto>(contentStream, _jsonOptions);
Assert.NotNull(newUser); Assert.NotNull(newUser);
Assert.Equal(user.Name, newUser.Name); Assert.Equal(user.Name, newUser.Name);
Assert.NotNull(newUser.Password); Assert.NotNull(newUser.Password);

View File

@ -43,8 +43,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
using var response = await client.GetAsync("Users/Public"); using var response = await client.GetAsync("Users/Public");
Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var users = await JsonSerializer.DeserializeAsync<UserDto[]>( var users = await response.Content.ReadFromJsonAsync<UserDto[]>(_jsonOpions);
await response.Content.ReadAsStreamAsync(), _jsonOpions);
// User are hidden by default // User are hidden by default
Assert.NotNull(users); Assert.NotNull(users);
Assert.Empty(users); Assert.Empty(users);
@ -59,8 +58,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
using var response = await client.GetAsync("Users"); using var response = await client.GetAsync("Users");
Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var users = await JsonSerializer.DeserializeAsync<UserDto[]>( var users = await response.Content.ReadFromJsonAsync<UserDto[]>(_jsonOpions);
await response.Content.ReadAsStreamAsync(), _jsonOpions);
Assert.NotNull(users); Assert.NotNull(users);
Assert.Single(users); Assert.Single(users);
Assert.False(users![0].HasConfiguredPassword); Assert.False(users![0].HasConfiguredPassword);
@ -92,8 +90,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
using var response = await CreateUserByName(client, createRequest); using var response = await CreateUserByName(client, createRequest);
Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var user = await JsonSerializer.DeserializeAsync<UserDto>( var user = await response.Content.ReadFromJsonAsync<UserDto>(_jsonOpions);
await response.Content.ReadAsStreamAsync(), _jsonOpions);
Assert.Equal(TestUsername, user!.Name); Assert.Equal(TestUsername, user!.Name);
Assert.False(user.HasPassword); Assert.False(user.HasPassword);
Assert.False(user.HasConfiguredPassword); Assert.False(user.HasConfiguredPassword);

View File

@ -1,6 +1,7 @@
using System; using System;
using System.Globalization; using System.Globalization;
using System.Net; using System.Net;
using System.Net.Http.Json;
using System.Text.Json; using System.Text.Json;
using System.Threading.Tasks; using System.Threading.Tasks;
using Jellyfin.Extensions.Json; using Jellyfin.Extensions.Json;
@ -85,9 +86,7 @@ public sealed class UserLibraryControllerTests : IClassFixture<JellyfinApplicati
var response = await client.GetAsync($"Users/{userDto.Id}/Items/{rootFolderDto.Id}"); var response = await client.GetAsync($"Users/{userDto.Id}/Items/{rootFolderDto.Id}");
Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var rootDto = await JsonSerializer.DeserializeAsync<BaseItemDto>( var rootDto = await response.Content.ReadFromJsonAsync<BaseItemDto>(_jsonOptions);
await response.Content.ReadAsStreamAsync(),
_jsonOptions);
Assert.NotNull(rootDto); Assert.NotNull(rootDto);
} }
@ -102,9 +101,7 @@ public sealed class UserLibraryControllerTests : IClassFixture<JellyfinApplicati
var response = await client.GetAsync($"Users/{userDto.Id}/Items/{rootFolderDto.Id}/Intros"); var response = await client.GetAsync($"Users/{userDto.Id}/Items/{rootFolderDto.Id}/Intros");
Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var rootDto = await JsonSerializer.DeserializeAsync<QueryResult<BaseItemDto>>( var rootDto = await response.Content.ReadFromJsonAsync<QueryResult<BaseItemDto>>(_jsonOptions);
await response.Content.ReadAsStreamAsync(),
_jsonOptions);
Assert.NotNull(rootDto); Assert.NotNull(rootDto);
} }
@ -121,9 +118,7 @@ public sealed class UserLibraryControllerTests : IClassFixture<JellyfinApplicati
var response = await client.GetAsync(string.Format(CultureInfo.InvariantCulture, format, userDto.Id, rootFolderDto.Id)); var response = await client.GetAsync(string.Format(CultureInfo.InvariantCulture, format, userDto.Id, rootFolderDto.Id));
Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var rootDto = await JsonSerializer.DeserializeAsync<BaseItemDto[]>( var rootDto = await response.Content.ReadFromJsonAsync<BaseItemDto[]>(_jsonOptions);
await response.Content.ReadAsStreamAsync(),
_jsonOptions);
Assert.NotNull(rootDto); Assert.NotNull(rootDto);
} }
} }

View File

@ -31,10 +31,10 @@ namespace Jellyfin.Server.Integration.Tests
Assert.Equal("application/json; charset=utf-8", response.Content.Headers.ContentType?.ToString()); Assert.Equal("application/json; charset=utf-8", response.Content.Headers.ContentType?.ToString());
// Write out for publishing // Write out for publishing
var responseBody = await response.Content.ReadAsStringAsync();
string outputPath = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? ".", "openapi.json")); string outputPath = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? ".", "openapi.json"));
_outputHelper.WriteLine("Writing OpenAPI Spec JSON to '{0}'.", outputPath); _outputHelper.WriteLine("Writing OpenAPI Spec JSON to '{0}'.", outputPath);
File.WriteAllText(outputPath, responseBody); await using var fs = File.Create(outputPath);
await response.Content.CopyToAsync(fs);
} }
} }
} }