mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-04-20 09:04:42 +01:00
improve httpclient resource disposal
This commit is contained in:
@@ -279,39 +279,9 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||
public async Task<Stream> Get(HttpRequestOptions options)
|
||||
{
|
||||
var response = await GetResponse(options).ConfigureAwait(false);
|
||||
|
||||
return response.Content;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs a GET request and returns the resulting stream
|
||||
/// </summary>
|
||||
/// <param name="url">The URL.</param>
|
||||
/// <param name="resourcePool">The resource pool.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task{Stream}.</returns>
|
||||
public Task<Stream> Get(string url, SemaphoreSlim resourcePool, CancellationToken cancellationToken)
|
||||
{
|
||||
return Get(new HttpRequestOptions
|
||||
{
|
||||
Url = url,
|
||||
ResourcePool = resourcePool,
|
||||
CancellationToken = cancellationToken,
|
||||
BufferContent = resourcePool != null
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the specified URL.
|
||||
/// </summary>
|
||||
/// <param name="url">The URL.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task{Stream}.</returns>
|
||||
public Task<Stream> Get(string url, CancellationToken cancellationToken)
|
||||
{
|
||||
return Get(url, null, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// send as an asynchronous operation.
|
||||
/// </summary>
|
||||
@@ -589,26 +559,6 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||
return response.Content;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs a POST request
|
||||
/// </summary>
|
||||
/// <param name="url">The URL.</param>
|
||||
/// <param name="postData">Params to add to the POST data.</param>
|
||||
/// <param name="resourcePool">The resource pool.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>stream on success, null on failure</returns>
|
||||
public Task<Stream> Post(string url, Dictionary<string, string> postData, SemaphoreSlim resourcePool, CancellationToken cancellationToken)
|
||||
{
|
||||
return Post(new HttpRequestOptions
|
||||
{
|
||||
Url = url,
|
||||
ResourcePool = resourcePool,
|
||||
CancellationToken = cancellationToken,
|
||||
BufferContent = resourcePool != null
|
||||
|
||||
}, postData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Downloads the contents of a given url into a temporary location
|
||||
/// </summary>
|
||||
@@ -891,18 +841,6 @@ namespace Emby.Server.Implementations.HttpClientManager
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Posts the specified URL.
|
||||
/// </summary>
|
||||
/// <param name="url">The URL.</param>
|
||||
/// <param name="postData">The post data.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task{Stream}.</returns>
|
||||
public Task<Stream> Post(string url, Dictionary<string, string> postData, CancellationToken cancellationToken)
|
||||
{
|
||||
return Post(url, postData, null, cancellationToken);
|
||||
}
|
||||
|
||||
private Task<WebResponse> GetResponseAsync(WebRequest request, TimeSpan timeout)
|
||||
{
|
||||
var taskCompletion = new TaskCompletionSource<WebResponse>();
|
||||
|
||||
@@ -55,10 +55,10 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV
|
||||
if (season.IndexNumber.HasValue)
|
||||
{
|
||||
var seasonNumber = season.IndexNumber.Value;
|
||||
|
||||
|
||||
season.Name = seasonNumber == 0 ?
|
||||
args.LibraryOptions.SeasonZeroDisplayName :
|
||||
string.Format(_localization.GetLocalizedString("NameSeasonNumber"), seasonNumber.ToString(UsCulture));
|
||||
string.Format(_localization.GetLocalizedString("NameSeasonNumber"), seasonNumber.ToString(UsCulture), args.GetLibraryOptions().PreferredMetadataLanguage);
|
||||
}
|
||||
|
||||
return season;
|
||||
|
||||
@@ -1463,6 +1463,9 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
||||
_timerProvider.AddOrUpdate(timer, false);
|
||||
|
||||
await SaveRecordingMetadata(timer, recordPath, seriesPath).ConfigureAwait(false);
|
||||
|
||||
CreateRecordingFolders();
|
||||
|
||||
TriggerRefresh(recordPath);
|
||||
EnforceKeepUpTo(timer, seriesPath);
|
||||
};
|
||||
|
||||
@@ -541,27 +541,30 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
||||
|
||||
try
|
||||
{
|
||||
using (Stream responce = await Get(options, false, info).ConfigureAwait(false))
|
||||
using (var httpResponse = await Get(options, false, info).ConfigureAwait(false))
|
||||
{
|
||||
var root = _jsonSerializer.DeserializeFromStream<List<ScheduleDirect.Headends>>(responce);
|
||||
|
||||
if (root != null)
|
||||
using (Stream responce = httpResponse.Content)
|
||||
{
|
||||
foreach (ScheduleDirect.Headends headend in root)
|
||||
var root = _jsonSerializer.DeserializeFromStream<List<ScheduleDirect.Headends>>(responce);
|
||||
|
||||
if (root != null)
|
||||
{
|
||||
foreach (ScheduleDirect.Lineup lineup in headend.lineups)
|
||||
foreach (ScheduleDirect.Headends headend in root)
|
||||
{
|
||||
lineups.Add(new NameIdPair
|
||||
foreach (ScheduleDirect.Lineup lineup in headend.lineups)
|
||||
{
|
||||
Name = string.IsNullOrWhiteSpace(lineup.name) ? lineup.lineup : lineup.name,
|
||||
Id = lineup.uri.Substring(18)
|
||||
});
|
||||
lineups.Add(new NameIdPair
|
||||
{
|
||||
Name = string.IsNullOrWhiteSpace(lineup.name) ? lineup.lineup : lineup.name,
|
||||
Id = lineup.uri.Substring(18)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Info("No lineups available");
|
||||
else
|
||||
{
|
||||
_logger.Info("No lineups available");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -671,13 +674,13 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
||||
return await Post(options, false, providerInfo).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private async Task<Stream> Get(HttpRequestOptions options,
|
||||
private async Task<HttpResponseInfo> Get(HttpRequestOptions options,
|
||||
bool enableRetry,
|
||||
ListingsProviderInfo providerInfo)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _httpClient.Get(options).ConfigureAwait(false);
|
||||
return await _httpClient.SendAsync(options, "GET").ConfigureAwait(false);
|
||||
}
|
||||
catch (HttpException ex)
|
||||
{
|
||||
@@ -797,11 +800,14 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
||||
|
||||
try
|
||||
{
|
||||
using (var response = await Get(options, false, null).ConfigureAwait(false))
|
||||
using (var httpResponse = await Get(options, false, null).ConfigureAwait(false))
|
||||
{
|
||||
var root = _jsonSerializer.DeserializeFromStream<ScheduleDirect.Lineups>(response);
|
||||
using (var response = httpResponse.Content)
|
||||
{
|
||||
var root = _jsonSerializer.DeserializeFromStream<ScheduleDirect.Lineups>(response);
|
||||
|
||||
return root.lineups.Any(i => string.Equals(info.ListingsId, i.lineup, StringComparison.OrdinalIgnoreCase));
|
||||
return root.lineups.Any(i => string.Equals(info.ListingsId, i.lineup, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (HttpException ex)
|
||||
@@ -879,53 +885,56 @@ namespace Emby.Server.Implementations.LiveTv.Listings
|
||||
|
||||
var list = new List<ChannelInfo>();
|
||||
|
||||
using (var response = await Get(httpOptions, true, info).ConfigureAwait(false))
|
||||
using (var httpResponse = await Get(httpOptions, true, info).ConfigureAwait(false))
|
||||
{
|
||||
var root = _jsonSerializer.DeserializeFromStream<ScheduleDirect.Channel>(response);
|
||||
_logger.Info("Found " + root.map.Count + " channels on the lineup on ScheduleDirect");
|
||||
_logger.Info("Mapping Stations to Channel");
|
||||
|
||||
var allStations = root.stations ?? new List<ScheduleDirect.Station>();
|
||||
|
||||
foreach (ScheduleDirect.Map map in root.map)
|
||||
using (var response = httpResponse.Content)
|
||||
{
|
||||
var channelNumber = GetChannelNumber(map);
|
||||
var root = _jsonSerializer.DeserializeFromStream<ScheduleDirect.Channel>(response);
|
||||
_logger.Info("Found " + root.map.Count + " channels on the lineup on ScheduleDirect");
|
||||
_logger.Info("Mapping Stations to Channel");
|
||||
|
||||
var station = allStations.FirstOrDefault(item => string.Equals(item.stationID, map.stationID, StringComparison.OrdinalIgnoreCase));
|
||||
if (station == null)
|
||||
var allStations = root.stations ?? new List<ScheduleDirect.Station>();
|
||||
|
||||
foreach (ScheduleDirect.Map map in root.map)
|
||||
{
|
||||
station = new ScheduleDirect.Station
|
||||
var channelNumber = GetChannelNumber(map);
|
||||
|
||||
var station = allStations.FirstOrDefault(item => string.Equals(item.stationID, map.stationID, StringComparison.OrdinalIgnoreCase));
|
||||
if (station == null)
|
||||
{
|
||||
stationID = map.stationID
|
||||
station = new ScheduleDirect.Station
|
||||
{
|
||||
stationID = map.stationID
|
||||
};
|
||||
}
|
||||
|
||||
var name = channelNumber;
|
||||
|
||||
var channelInfo = new ChannelInfo
|
||||
{
|
||||
Number = channelNumber,
|
||||
Name = name
|
||||
};
|
||||
}
|
||||
|
||||
var name = channelNumber;
|
||||
|
||||
var channelInfo = new ChannelInfo
|
||||
{
|
||||
Number = channelNumber,
|
||||
Name = name
|
||||
};
|
||||
|
||||
if (station != null)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(station.name))
|
||||
if (station != null)
|
||||
{
|
||||
channelInfo.Name = station.name;
|
||||
if (!string.IsNullOrWhiteSpace(station.name))
|
||||
{
|
||||
channelInfo.Name = station.name;
|
||||
}
|
||||
|
||||
channelInfo.Id = station.stationID;
|
||||
channelInfo.CallSign = station.callsign;
|
||||
|
||||
if (station.logo != null)
|
||||
{
|
||||
channelInfo.ImageUrl = station.logo.URL;
|
||||
channelInfo.HasImage = true;
|
||||
}
|
||||
}
|
||||
|
||||
channelInfo.Id = station.stationID;
|
||||
channelInfo.CallSign = station.callsign;
|
||||
|
||||
if (station.logo != null)
|
||||
{
|
||||
channelInfo.ImageUrl = station.logo.URL;
|
||||
channelInfo.HasImage = true;
|
||||
}
|
||||
list.Add(channelInfo);
|
||||
}
|
||||
|
||||
list.Add(channelInfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -86,16 +86,19 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
||||
CancellationToken = cancellationToken,
|
||||
BufferContent = false
|
||||
};
|
||||
using (var stream = await _httpClient.Get(options).ConfigureAwait(false))
|
||||
using (var response = await _httpClient.SendAsync(options, "GET").ConfigureAwait(false))
|
||||
{
|
||||
var lineup = JsonSerializer.DeserializeFromStream<List<Channels>>(stream) ?? new List<Channels>();
|
||||
|
||||
if (info.ImportFavoritesOnly)
|
||||
using (var stream = response.Content)
|
||||
{
|
||||
lineup = lineup.Where(i => i.Favorite).ToList();
|
||||
}
|
||||
var lineup = JsonSerializer.DeserializeFromStream<List<Channels>>(stream) ?? new List<Channels>();
|
||||
|
||||
return lineup.Where(i => !i.DRM).ToList();
|
||||
if (info.ImportFavoritesOnly)
|
||||
{
|
||||
lineup = lineup.Where(i => i.Favorite).ToList();
|
||||
}
|
||||
|
||||
return lineup.Where(i => !i.DRM).ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,26 +146,29 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
||||
|
||||
try
|
||||
{
|
||||
using (var stream = await _httpClient.Get(new HttpRequestOptions()
|
||||
using (var response = await _httpClient.SendAsync(new HttpRequestOptions()
|
||||
{
|
||||
Url = string.Format("{0}/discover.json", GetApiUrl(info, false)),
|
||||
CancellationToken = cancellationToken,
|
||||
TimeoutMs = Convert.ToInt32(TimeSpan.FromSeconds(5).TotalMilliseconds),
|
||||
BufferContent = false
|
||||
|
||||
}).ConfigureAwait(false))
|
||||
}, "GET").ConfigureAwait(false))
|
||||
{
|
||||
var response = JsonSerializer.DeserializeFromStream<DiscoverResponse>(stream);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(info.Id))
|
||||
using (var stream = response.Content)
|
||||
{
|
||||
lock (_modelCache)
|
||||
{
|
||||
_modelCache[info.Id] = response;
|
||||
}
|
||||
}
|
||||
var discoverResponse = JsonSerializer.DeserializeFromStream<DiscoverResponse>(stream);
|
||||
|
||||
return response;
|
||||
if (!string.IsNullOrWhiteSpace(info.Id))
|
||||
{
|
||||
lock (_modelCache)
|
||||
{
|
||||
_modelCache[info.Id] = discoverResponse;
|
||||
}
|
||||
}
|
||||
|
||||
return discoverResponse;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (HttpException ex)
|
||||
|
||||
@@ -92,14 +92,17 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
||||
|
||||
}, "GET").ConfigureAwait(false))
|
||||
{
|
||||
Logger.Info("Opened HDHR stream from {0}", url);
|
||||
|
||||
Logger.Info("Beginning multicastStream.CopyUntilCancelled");
|
||||
|
||||
FileSystem.CreateDirectory(FileSystem.GetDirectoryName(TempFilePath));
|
||||
using (var fileStream = FileSystem.GetFileStream(TempFilePath, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read, FileOpenOptions.None))
|
||||
using (var stream = response.Content)
|
||||
{
|
||||
StreamHelper.CopyTo(response.Content, fileStream, 81920, () => Resolve(openTaskCompletionSource), cancellationToken);
|
||||
Logger.Info("Opened HDHR stream from {0}", url);
|
||||
|
||||
Logger.Info("Beginning multicastStream.CopyUntilCancelled");
|
||||
|
||||
FileSystem.CreateDirectory(FileSystem.GetDirectoryName(TempFilePath));
|
||||
using (var fileStream = FileSystem.GetFileStream(TempFilePath, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read, FileOpenOptions.None))
|
||||
{
|
||||
StreamHelper.CopyTo(stream, fileStream, 81920, () => Resolve(openTaskCompletionSource), cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -315,6 +315,11 @@ namespace Emby.Server.Implementations.Localization
|
||||
|
||||
public string GetLocalizedString(string phrase, string culture)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(culture))
|
||||
{
|
||||
culture = _configurationManager.Configuration.UICulture;
|
||||
}
|
||||
|
||||
var dictionary = GetLocalizationDictionary(culture);
|
||||
|
||||
string value;
|
||||
|
||||
@@ -88,15 +88,18 @@ namespace Emby.Server.Implementations.News
|
||||
BufferContent = false
|
||||
};
|
||||
|
||||
using (var stream = await _httpClient.Get(requestOptions).ConfigureAwait(false))
|
||||
using (var response = await _httpClient.SendAsync(requestOptions, "GET").ConfigureAwait(false))
|
||||
{
|
||||
using (var reader = XmlReader.Create(stream))
|
||||
using (var stream = response.Content)
|
||||
{
|
||||
var news = ParseRssItems(reader).ToList();
|
||||
using (var reader = XmlReader.Create(stream))
|
||||
{
|
||||
var news = ParseRssItems(reader).ToList();
|
||||
|
||||
_json.SerializeToFile(news, path);
|
||||
_json.SerializeToFile(news, path);
|
||||
|
||||
await CreateNotifications(news, lastUpdate, CancellationToken.None).ConfigureAwait(false);
|
||||
await CreateNotifications(news, lastUpdate, CancellationToken.None).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -293,10 +293,13 @@ namespace Emby.Server.Implementations.Security
|
||||
|
||||
options.SetPostData(data);
|
||||
|
||||
using (var json = (await _httpClient.Post(options).ConfigureAwait(false)).Content)
|
||||
using (var response = (await _httpClient.Post(options).ConfigureAwait(false)))
|
||||
{
|
||||
reg = _jsonSerializer.DeserializeFromStream<RegRecord>(json);
|
||||
success = true;
|
||||
using (var json = response.Content)
|
||||
{
|
||||
reg = _jsonSerializer.DeserializeFromStream<RegRecord>(json);
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (reg.registered)
|
||||
|
||||
@@ -66,19 +66,22 @@ namespace Emby.Server.Implementations.Session
|
||||
return SendMessage(name, new Dictionary<string, string>(), cancellationToken);
|
||||
}
|
||||
|
||||
private Task SendMessage(string name,
|
||||
private async Task SendMessage(string name,
|
||||
Dictionary<string, string> args,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var url = PostUrl + "/" + name + ToQueryString(args);
|
||||
|
||||
return _httpClient.Post(new HttpRequestOptions
|
||||
using ((await _httpClient.Post(new HttpRequestOptions
|
||||
{
|
||||
Url = url,
|
||||
CancellationToken = cancellationToken,
|
||||
BufferContent = false
|
||||
|
||||
});
|
||||
}).ConfigureAwait(false)))
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public Task SendSessionEndedNotification(SessionInfoDto sessionInfo, CancellationToken cancellationToken)
|
||||
|
||||
@@ -175,13 +175,24 @@ namespace Emby.Server.Implementations.Updates
|
||||
{ "systemid", _applicationHost.SystemId }
|
||||
};
|
||||
|
||||
using (var json = await _httpClient.Post("https://www.mb3admin.com/admin/service/package/retrieveall?includeAllRuntimes=true", data, cancellationToken).ConfigureAwait(false))
|
||||
var options = new HttpRequestOptions
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
Url = "https://www.mb3admin.com/admin/service/package/retrieveall?includeAllRuntimes=true",
|
||||
CancellationToken = cancellationToken
|
||||
};
|
||||
|
||||
var packages = _jsonSerializer.DeserializeFromStream<PackageInfo[]>(json);
|
||||
options.SetPostData(data);
|
||||
|
||||
return FilterPackages(packages, packageType, applicationVersion);
|
||||
using (var response = await _httpClient.SendAsync(options, "POST").ConfigureAwait(false))
|
||||
{
|
||||
using (var json = response.Content)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var packages = _jsonSerializer.DeserializeFromStream<PackageInfo[]>(json);
|
||||
|
||||
return FilterPackages(packages, packageType, applicationVersion);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user