mirror of
https://github.com/jellyfin/TMDbLib.git
synced 2024-11-23 05:40:12 +00:00
Fixup disposable usage internally, to ensure HttpResponseMessage is disposed
This commit is contained in:
parent
2118725348
commit
5edc95e0f6
@ -185,6 +185,7 @@ namespace TMDbLib.Client
|
||||
return await response.Content.ReadAsByteArrayAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("IDisposableAnalyzers.Correctness", "IDISP003:Dispose previous before re-assigning.", Justification = "Only called from ctor")]
|
||||
private void Initialize(string baseUrl, bool useSsl, string apiKey)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(baseUrl))
|
||||
@ -202,6 +203,7 @@ namespace TMDbLib.Client
|
||||
baseUrl = baseUrl.Substring("https://".Length);
|
||||
|
||||
string httpScheme = useSsl ? "https" : "http";
|
||||
|
||||
_client = new RestClient(new Uri(string.Format("{0}://{1}/{2}/", httpScheme, baseUrl, ApiVersion)), _serializer, WebProxy);
|
||||
_client.AddDefaultQueryString("api_key", apiKey);
|
||||
}
|
||||
@ -272,7 +274,7 @@ namespace TMDbLib.Client
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
public virtual void Dispose()
|
||||
{
|
||||
_client?.Dispose();
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ namespace TMDbLib.Client
|
||||
RestRequest request = _client.Create("authentication/session/new");
|
||||
request.AddParameter("request_token", initialRequestToken);
|
||||
|
||||
RestResponse<UserSession> response = await request.Get<UserSession>(cancellationToken).ConfigureAwait(false);
|
||||
using RestResponse<UserSession> response = await request.Get<UserSession>(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (response.StatusCode == HttpStatusCode.Unauthorized)
|
||||
throw new UnauthorizedAccessException();
|
||||
@ -51,7 +51,7 @@ namespace TMDbLib.Client
|
||||
{
|
||||
RestRequest request = _client.Create("authentication/token/new");
|
||||
|
||||
RestResponse<Token> response = await request.Get<Token>(cancellationToken).ConfigureAwait(false);
|
||||
using RestResponse<Token> response = await request.Get<Token>(cancellationToken).ConfigureAwait(false);
|
||||
Token token = await response.GetDataObject().ConfigureAwait(false);
|
||||
|
||||
token.AuthenticationCallback = response.GetHeader("Authentication-Callback");
|
||||
@ -76,6 +76,8 @@ namespace TMDbLib.Client
|
||||
throw ex.InnerException;
|
||||
}
|
||||
|
||||
using RestResponse _ = response;
|
||||
|
||||
if (response.StatusCode == HttpStatusCode.Unauthorized)
|
||||
{
|
||||
throw new UnauthorizedAccessException("Call to TMDb returned unauthorized. Most likely the provided user credentials are invalid.");
|
||||
|
@ -31,7 +31,7 @@ namespace TMDbLib.Client
|
||||
if (endDate != null)
|
||||
req.AddParameter("end_date", endDate.Value.ToString("yyyy-MM-dd"));
|
||||
|
||||
RestResponse<T> resp = await req.Get<T>(cancellationToken).ConfigureAwait(false);
|
||||
using RestResponse<T> resp = await req.Get<T>(cancellationToken).ConfigureAwait(false);
|
||||
T res = await resp.GetDataObject().ConfigureAwait(false);
|
||||
|
||||
if (res is SearchContainer<ChangesListItem> asSearch)
|
||||
|
@ -56,7 +56,7 @@ namespace TMDbLib.Client
|
||||
|
||||
//req.DateFormat = "yyyy-MM-dd";
|
||||
|
||||
RestResponse<Collection> response = await req.Get<Collection>(cancellationToken).ConfigureAwait(false);
|
||||
using RestResponse<Collection> response = await req.Get<Collection>(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (!response.IsValid)
|
||||
return null;
|
||||
|
@ -17,7 +17,7 @@ namespace TMDbLib.Client
|
||||
{
|
||||
RestRequest req = _client.Create("configuration");
|
||||
|
||||
RestResponse<APIConfiguration> response = await req.Get<APIConfiguration>(cancellationToken).ConfigureAwait(false);
|
||||
using RestResponse<APIConfiguration> response = await req.Get<APIConfiguration>(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
return (await response.GetDataObject().ConfigureAwait(false));
|
||||
}
|
||||
@ -26,16 +26,16 @@ namespace TMDbLib.Client
|
||||
{
|
||||
RestRequest req = _client.Create("configuration/countries");
|
||||
|
||||
RestResponse<List<Country>> response = await req.Get<List<Country>>(cancellationToken).ConfigureAwait(false);
|
||||
using RestResponse<List<Country>> response = await req.Get<List<Country>>(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
return (await response.GetDataObject().ConfigureAwait(false));
|
||||
return await response.GetDataObject().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task<List<Language>> GetLanguagesAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
RestRequest req = _client.Create("configuration/languages");
|
||||
|
||||
RestResponse<List<Language>> response = await req.Get<List<Language>>(cancellationToken).ConfigureAwait(false);
|
||||
using RestResponse<List<Language>> response = await req.Get<List<Language>>(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
return (await response.GetDataObject().ConfigureAwait(false));
|
||||
}
|
||||
@ -44,7 +44,7 @@ namespace TMDbLib.Client
|
||||
{
|
||||
RestRequest req = _client.Create("configuration/primary_translations");
|
||||
|
||||
RestResponse<List<string>> response = await req.Get<List<string>>(cancellationToken).ConfigureAwait(false);
|
||||
using RestResponse<List<string>> response = await req.Get<List<string>>(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
return (await response.GetDataObject().ConfigureAwait(false));
|
||||
}
|
||||
@ -53,7 +53,7 @@ namespace TMDbLib.Client
|
||||
{
|
||||
RestRequest req = _client.Create("timezones/list");
|
||||
|
||||
RestResponse<List<Dictionary<string, List<string>>>> resp = await req.Get<List<Dictionary<string, List<string>>>>(cancellationToken).ConfigureAwait(false);
|
||||
using RestResponse<List<Dictionary<string, List<string>>>> resp = await req.Get<List<Dictionary<string, List<string>>>>(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
List<Dictionary<string, List<string>>> item = await resp.GetDataObject().ConfigureAwait(false);
|
||||
|
||||
@ -81,7 +81,7 @@ namespace TMDbLib.Client
|
||||
{
|
||||
RestRequest req = _client.Create("configuration/jobs");
|
||||
|
||||
RestResponse<List<Job>> response = await req.Get<List<Job>>(cancellationToken).ConfigureAwait(false);
|
||||
using RestResponse<List<Job>> response = await req.Get<List<Job>>(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
return (await response.GetDataObject().ConfigureAwait(false));
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ namespace TMDbLib.Client
|
||||
if (!string.IsNullOrWhiteSpace(language))
|
||||
req.AddParameter("language", language);
|
||||
|
||||
RestResponse<GenreContainer> resp = await req.Get<GenreContainer>(cancellationToken).ConfigureAwait(false);
|
||||
using RestResponse<GenreContainer> resp = await req.Get<GenreContainer>(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
return (await resp.GetDataObject().ConfigureAwait(false)).Genres;
|
||||
}
|
||||
@ -68,7 +68,7 @@ namespace TMDbLib.Client
|
||||
if (!string.IsNullOrWhiteSpace(language))
|
||||
req.AddParameter("language", language);
|
||||
|
||||
RestResponse<GenreContainer> resp = await req.Get<GenreContainer>(cancellationToken).ConfigureAwait(false);
|
||||
using RestResponse<GenreContainer> resp = await req.Get<GenreContainer>(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
return (await resp.GetDataObject().ConfigureAwait(false)).Genres;
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ namespace TMDbLib.Client
|
||||
|
||||
req.SetBody(new { media_id = movieId });
|
||||
|
||||
RestResponse<PostReply> response = await req.Post<PostReply>(cancellationToken).ConfigureAwait(false);
|
||||
using RestResponse<PostReply> response = await req.Post<PostReply>(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
// Status code 12 = "The item/record was updated successfully"
|
||||
// Status code 13 = "The item/record was deleted successfully"
|
||||
@ -79,7 +79,7 @@ namespace TMDbLib.Client
|
||||
req.AddUrlSegment("listId", listId);
|
||||
req.AddParameter("movie_id", movieId.ToString());
|
||||
|
||||
RestResponse<ListStatus> response = await req.Get<ListStatus>(cancellationToken).ConfigureAwait(false);
|
||||
using RestResponse<ListStatus> response = await req.Get<ListStatus>(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
return (await response.GetDataObject().ConfigureAwait(false)).ItemPresent;
|
||||
}
|
||||
@ -118,7 +118,7 @@ namespace TMDbLib.Client
|
||||
request.AddParameter("confirm", "true");
|
||||
AddSessionId(request, SessionType.UserSession);
|
||||
|
||||
RestResponse<PostReply> response = await request.Post<PostReply>(cancellationToken).ConfigureAwait(false);
|
||||
using RestResponse<PostReply> response = await request.Post<PostReply>(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
// Status code 12 = "The item/record was updated successfully"
|
||||
PostReply item = await response.GetDataObject().ConfigureAwait(false);
|
||||
@ -161,7 +161,7 @@ namespace TMDbLib.Client
|
||||
req.SetBody(new { name = name, description = description });
|
||||
}
|
||||
|
||||
RestResponse<ListCreateReply> response = await req.Post<ListCreateReply>(cancellationToken).ConfigureAwait(false);
|
||||
using RestResponse<ListCreateReply> response = await req.Post<ListCreateReply>(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
return (await response.GetDataObject().ConfigureAwait(false)).ListId;
|
||||
}
|
||||
@ -184,7 +184,7 @@ namespace TMDbLib.Client
|
||||
req.AddUrlSegment("listId", listId);
|
||||
AddSessionId(req, SessionType.UserSession);
|
||||
|
||||
RestResponse<PostReply> response = await req.Delete<PostReply>(cancellationToken).ConfigureAwait(false);
|
||||
using RestResponse<PostReply> response = await req.Delete<PostReply>(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
// Status code 13 = success
|
||||
PostReply item = await response.GetDataObject().ConfigureAwait(false);
|
||||
|
@ -64,7 +64,7 @@ namespace TMDbLib.Client
|
||||
req.AddUrlSegment("method", MovieMethods.AccountStates.GetDescription());
|
||||
AddSessionId(req, SessionType.UserSession);
|
||||
|
||||
RestResponse<AccountState> response = await req.Get<AccountState>(cancellationToken).ConfigureAwait(false);
|
||||
using RestResponse<AccountState> response = await req.Get<AccountState>(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
return await response.GetDataObject().ConfigureAwait(false);
|
||||
}
|
||||
@ -132,7 +132,7 @@ namespace TMDbLib.Client
|
||||
if (appends != string.Empty)
|
||||
req.AddParameter("append_to_response", appends);
|
||||
|
||||
RestResponse<Movie> response = await req.Get<Movie>(cancellationToken).ConfigureAwait(false);
|
||||
using RestResponse<Movie> response = await req.Get<Movie>(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (!response.IsValid)
|
||||
return null;
|
||||
@ -203,7 +203,7 @@ namespace TMDbLib.Client
|
||||
public async Task<Movie> GetMovieLatestAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
RestRequest req = _client.Create("movie/latest");
|
||||
RestResponse<Movie> resp = await req.Get<Movie>(cancellationToken).ConfigureAwait(false);
|
||||
using RestResponse<Movie> resp = await req.Get<Movie>(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
Movie item = await resp.GetDataObject().ConfigureAwait(false);
|
||||
|
||||
@ -351,7 +351,7 @@ namespace TMDbLib.Client
|
||||
req.AddUrlSegment("movieId", movieId.ToString(CultureInfo.InvariantCulture));
|
||||
AddSessionId(req);
|
||||
|
||||
RestResponse<PostReply> response = await req.Delete<PostReply>(cancellationToken).ConfigureAwait(false);
|
||||
using RestResponse<PostReply> response = await req.Delete<PostReply>(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
// status code 13 = "The item/record was deleted successfully."
|
||||
PostReply item = await response.GetDataObject().ConfigureAwait(false);
|
||||
@ -379,7 +379,7 @@ namespace TMDbLib.Client
|
||||
|
||||
req.SetBody(new { value = rating });
|
||||
|
||||
RestResponse<PostReply> response = await req.Post<PostReply>(cancellationToken).ConfigureAwait(false);
|
||||
using RestResponse<PostReply> response = await req.Post<PostReply>(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
// status code 1 = "Success"
|
||||
// status code 12 = "The item/record was updated successfully" - Used when an item was previously rated by the user
|
||||
|
@ -80,7 +80,7 @@ namespace TMDbLib.Client
|
||||
// TODO: Dateformat?
|
||||
//req.DateFormat = "yyyy-MM-dd";
|
||||
|
||||
RestResponse<Person> response = await req.Get<Person>(cancellationToken).ConfigureAwait(false);
|
||||
using RestResponse<Person> response = await req.Get<Person>(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (!response.IsValid)
|
||||
return null;
|
||||
|
@ -23,7 +23,7 @@ namespace TMDbLib.Client
|
||||
if (!string.IsNullOrWhiteSpace(language))
|
||||
req.AddParameter("language", language);
|
||||
|
||||
RestResponse<TvGroupCollection> response = await req.Get<TvGroupCollection>(cancellationToken).ConfigureAwait(false);
|
||||
using RestResponse<TvGroupCollection> response = await req.Get<TvGroupCollection>(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (!response.IsValid)
|
||||
return null;
|
||||
|
@ -46,7 +46,7 @@ namespace TMDbLib.Client
|
||||
req.AddUrlSegment("method", TvEpisodeMethods.AccountStates.GetDescription());
|
||||
AddSessionId(req, SessionType.UserSession);
|
||||
|
||||
RestResponse<TvEpisodeAccountState> response = await req.Get<TvEpisodeAccountState>(cancellationToken).ConfigureAwait(false);
|
||||
using RestResponse<TvEpisodeAccountState> response = await req.Get<TvEpisodeAccountState>(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
return await response.GetDataObject().ConfigureAwait(false);
|
||||
}
|
||||
@ -92,7 +92,7 @@ namespace TMDbLib.Client
|
||||
if (appends != string.Empty)
|
||||
req.AddParameter("append_to_response", appends);
|
||||
|
||||
RestResponse<TvEpisode> response = await req.Get<TvEpisode>(cancellationToken).ConfigureAwait(false);
|
||||
using RestResponse<TvEpisode> response = await req.Get<TvEpisode>(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (!response.IsValid)
|
||||
return null;
|
||||
@ -184,7 +184,7 @@ namespace TMDbLib.Client
|
||||
|
||||
AddSessionId(req);
|
||||
|
||||
RestResponse<PostReply> response = await req.Delete<PostReply>(cancellationToken).ConfigureAwait(false);
|
||||
using RestResponse<PostReply> response = await req.Delete<PostReply>(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
// status code 13 = "The item/record was deleted successfully."
|
||||
PostReply item = await response.GetDataObject().ConfigureAwait(false);
|
||||
@ -206,7 +206,7 @@ namespace TMDbLib.Client
|
||||
|
||||
req.SetBody(new { value = rating });
|
||||
|
||||
RestResponse<PostReply> response = await req.Post<PostReply>(cancellationToken).ConfigureAwait(false);
|
||||
using RestResponse<PostReply> response = await req.Post<PostReply>(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
// status code 1 = "Success"
|
||||
// status code 12 = "The item/record was updated successfully" - Used when an item was previously rated by the user
|
||||
|
@ -44,7 +44,7 @@ namespace TMDbLib.Client
|
||||
req.AddUrlSegment("method", TvEpisodeMethods.AccountStates.GetDescription());
|
||||
AddSessionId(req, SessionType.UserSession);
|
||||
|
||||
RestResponse<ResultContainer<TvEpisodeAccountStateWithNumber>> response = await req.Get<ResultContainer<TvEpisodeAccountStateWithNumber>>(cancellationToken).ConfigureAwait(false);
|
||||
using RestResponse<ResultContainer<TvEpisodeAccountStateWithNumber>> response = await req.Get<ResultContainer<TvEpisodeAccountStateWithNumber>>(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
return await response.GetDataObject().ConfigureAwait(false);
|
||||
}
|
||||
@ -89,7 +89,7 @@ namespace TMDbLib.Client
|
||||
if (appends != string.Empty)
|
||||
req.AddParameter("append_to_response", appends);
|
||||
|
||||
RestResponse<TvSeason> response = await req.Get<TvSeason>(cancellationToken).ConfigureAwait(false);
|
||||
using RestResponse<TvSeason> response = await req.Get<TvSeason>(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (!response.IsValid)
|
||||
return null;
|
||||
|
@ -85,7 +85,7 @@ namespace TMDbLib.Client
|
||||
req.AddUrlSegment("method", TvShowMethods.AccountStates.GetDescription());
|
||||
AddSessionId(req, SessionType.UserSession);
|
||||
|
||||
RestResponse<AccountState> response = await req.Get<AccountState>(cancellationToken).ConfigureAwait(false);
|
||||
using RestResponse<AccountState> response = await req.Get<AccountState>(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
return await response.GetDataObject().ConfigureAwait(false);
|
||||
}
|
||||
@ -132,7 +132,7 @@ namespace TMDbLib.Client
|
||||
if (appends != string.Empty)
|
||||
req.AddParameter("append_to_response", appends);
|
||||
|
||||
RestResponse<TvShow> response = await req.Get<TvShow>(cancellationToken).ConfigureAwait(false);
|
||||
using RestResponse<TvShow> response = await req.Get<TvShow>(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (!response.IsValid)
|
||||
return null;
|
||||
@ -210,6 +210,7 @@ namespace TMDbLib.Client
|
||||
/// If specified the api will attempt to return a localized result. ex: en,it,es.
|
||||
/// For images this means that the image might contain language specifc text
|
||||
/// </param>
|
||||
/// <param name="includeImageLanguage">If you want to include a fallback language (especially useful for backdrops) you can use the include_image_language parameter. This should be a comma separated value like so: include_image_language=en,null.</param>
|
||||
/// <param name="cancellationToken">A cancellation token</param>
|
||||
public async Task<ImagesWithId> GetTvShowImagesAsync(int id, string language = null, string includeImageLanguage = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
@ -335,7 +336,7 @@ namespace TMDbLib.Client
|
||||
req.AddUrlSegment("tvShowId", tvShowId.ToString(CultureInfo.InvariantCulture));
|
||||
AddSessionId(req);
|
||||
|
||||
RestResponse<PostReply> response = await req.Delete<PostReply>(cancellationToken).ConfigureAwait(false);
|
||||
using RestResponse<PostReply> response = await req.Delete<PostReply>(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
// status code 13 = "The item/record was deleted successfully."
|
||||
PostReply item = await response.GetDataObject().ConfigureAwait(false);
|
||||
@ -363,7 +364,7 @@ namespace TMDbLib.Client
|
||||
|
||||
req.SetBody(new { value = rating });
|
||||
|
||||
RestResponse<PostReply> response = await req.Post<PostReply>(cancellationToken).ConfigureAwait(false);
|
||||
using RestResponse<PostReply> response = await req.Post<PostReply>(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
// status code 1 = "Success"
|
||||
// status code 12 = "The item/record was updated successfully" - Used when an item was previously rated by the user
|
||||
|
@ -7,7 +7,7 @@ using TMDbLib.Utilities.Serializer;
|
||||
|
||||
namespace TMDbLib.Rest
|
||||
{
|
||||
internal class RestClient : IDisposable
|
||||
internal sealed class RestClient : IDisposable
|
||||
{
|
||||
private int _maxRetryCount;
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
@ -93,6 +94,7 @@ namespace TMDbLib.Rest
|
||||
return new RestResponse(resp);
|
||||
}
|
||||
|
||||
[SuppressMessage("IDisposableAnalyzers.Correctness", "IDISP001:Dispose created", Justification = "resp is disposed by RestResponse<>()")]
|
||||
public async Task<RestResponse<T>> Delete<T>(CancellationToken cancellationToken)
|
||||
{
|
||||
HttpResponseMessage resp = await SendInternal(HttpMethod.Delete, cancellationToken).ConfigureAwait(false);
|
||||
@ -107,6 +109,7 @@ namespace TMDbLib.Rest
|
||||
return new RestResponse(resp);
|
||||
}
|
||||
|
||||
[SuppressMessage("IDisposableAnalyzers.Correctness", "IDISP001:Dispose created", Justification = "resp is disposed by RestResponse<>()")]
|
||||
public async Task<RestResponse<T>> Get<T>(CancellationToken cancellationToken)
|
||||
{
|
||||
HttpResponseMessage resp = await SendInternal(HttpMethod.Get, cancellationToken).ConfigureAwait(false);
|
||||
@ -121,6 +124,7 @@ namespace TMDbLib.Rest
|
||||
return new RestResponse(resp);
|
||||
}
|
||||
|
||||
[SuppressMessage("IDisposableAnalyzers.Correctness", "IDISP001:Dispose created", Justification = "resp is disposed by RestResponse<>()")]
|
||||
public async Task<RestResponse<T>> Post<T>(CancellationToken cancellationToken)
|
||||
{
|
||||
HttpResponseMessage resp = await SendInternal(HttpMethod.Post, cancellationToken).ConfigureAwait(false);
|
||||
@ -182,51 +186,49 @@ namespace TMDbLib.Rest
|
||||
|
||||
do
|
||||
{
|
||||
using (HttpRequestMessage req = PrepRequest(method))
|
||||
using HttpRequestMessage req = PrepRequest(method);
|
||||
using HttpResponseMessage resp = await _client.HttpClient.SendAsync(req, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
bool isJson = resp.Content.Headers.ContentType.MediaType.Equals("application/json");
|
||||
|
||||
if (resp.IsSuccessStatusCode && isJson)
|
||||
return resp;
|
||||
|
||||
if (isJson)
|
||||
statusMessage = JsonConvert.DeserializeObject<TMDbStatusMessage>(await resp.Content.ReadAsStringAsync().ConfigureAwait(false));
|
||||
else
|
||||
statusMessage = null;
|
||||
|
||||
switch (resp.StatusCode)
|
||||
{
|
||||
HttpResponseMessage resp = await _client.HttpClient.SendAsync(req, cancellationToken).ConfigureAwait(false);
|
||||
case (HttpStatusCode)429:
|
||||
// The previous result was a ratelimit, read the Retry-After header and wait the allotted time
|
||||
retryHeader = resp.Headers.RetryAfter;
|
||||
TimeSpan? retryAfter = retryHeader?.Delta.Value;
|
||||
|
||||
bool isJson = resp.Content.Headers.ContentType.MediaType.Equals("application/json");
|
||||
if (retryAfter.HasValue && retryAfter.Value.TotalSeconds > 0)
|
||||
await Task.Delay(retryAfter.Value, cancellationToken).ConfigureAwait(false);
|
||||
else
|
||||
// TMDb sometimes gives us 0-second waits, which can lead to rapid succession of requests
|
||||
await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (resp.IsSuccessStatusCode && isJson)
|
||||
return resp;
|
||||
continue;
|
||||
case HttpStatusCode.Unauthorized:
|
||||
throw new UnauthorizedAccessException(
|
||||
"Call to TMDb returned unauthorized. Most likely the provided API key is invalid.");
|
||||
|
||||
if (isJson)
|
||||
statusMessage = JsonConvert.DeserializeObject<TMDbStatusMessage>(await resp.Content.ReadAsStringAsync().ConfigureAwait(false));
|
||||
else
|
||||
statusMessage = null;
|
||||
|
||||
switch (resp.StatusCode)
|
||||
{
|
||||
case (HttpStatusCode)429:
|
||||
// The previous result was a ratelimit, read the Retry-After header and wait the allotted time
|
||||
retryHeader = resp.Headers.RetryAfter;
|
||||
TimeSpan? retryAfter = retryHeader?.Delta.Value;
|
||||
|
||||
if (retryAfter.HasValue && retryAfter.Value.TotalSeconds > 0)
|
||||
await Task.Delay(retryAfter.Value, cancellationToken).ConfigureAwait(false);
|
||||
else
|
||||
// TMDb sometimes gives us 0-second waits, which can lead to rapid succession of requests
|
||||
await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken).ConfigureAwait(false);
|
||||
|
||||
continue;
|
||||
case HttpStatusCode.Unauthorized:
|
||||
throw new UnauthorizedAccessException(
|
||||
"Call to TMDb returned unauthorized. Most likely the provided API key is invalid.");
|
||||
|
||||
case HttpStatusCode.NotFound:
|
||||
if (_client.ThrowApiExceptions)
|
||||
{
|
||||
throw new NotFoundException(statusMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
throw new GeneralHttpException(resp.StatusCode);
|
||||
case HttpStatusCode.NotFound:
|
||||
if (_client.ThrowApiExceptions)
|
||||
{
|
||||
throw new NotFoundException(statusMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
throw new GeneralHttpException(resp.StatusCode);
|
||||
} while (timesToTry-- > 0);
|
||||
|
||||
// We never reached a success
|
||||
|
@ -7,7 +7,7 @@ namespace TMDbLib.Rest
|
||||
{
|
||||
public static async Task<T> DeleteOfT<T>(this RestRequest request, CancellationToken cancellationToken)
|
||||
{
|
||||
RestResponse<T> resp = await request.Delete<T>(cancellationToken).ConfigureAwait(false);
|
||||
using RestResponse<T> resp = await request.Delete<T>(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (!resp.IsValid)
|
||||
return default;
|
||||
@ -17,7 +17,7 @@ namespace TMDbLib.Rest
|
||||
|
||||
public static async Task<T> GetOfT<T>(this RestRequest request, CancellationToken cancellationToken)
|
||||
{
|
||||
RestResponse<T> resp = await request.Get<T>(cancellationToken).ConfigureAwait(false);
|
||||
using RestResponse<T> resp = await request.Get<T>(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (!resp.IsValid)
|
||||
return default;
|
||||
@ -27,7 +27,7 @@ namespace TMDbLib.Rest
|
||||
|
||||
public static async Task<T> PostOfT<T>(this RestRequest request, CancellationToken cancellationToken)
|
||||
{
|
||||
RestResponse<T> resp = await request.Post<T>(cancellationToken).ConfigureAwait(false);
|
||||
using RestResponse<T> resp = await request.Post<T>(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (!resp.IsValid)
|
||||
return default;
|
||||
|
@ -1,3 +1,5 @@
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
@ -7,9 +9,9 @@ using TMDbLib.Utilities.Serializer;
|
||||
|
||||
namespace TMDbLib.Rest
|
||||
{
|
||||
internal class RestResponse
|
||||
internal class RestResponse :IDisposable
|
||||
{
|
||||
protected readonly HttpResponseMessage Response;
|
||||
private readonly HttpResponseMessage Response;
|
||||
|
||||
public RestResponse(HttpResponseMessage response)
|
||||
{
|
||||
@ -29,6 +31,12 @@ namespace TMDbLib.Rest
|
||||
{
|
||||
return Response.Headers.GetValues(name).FirstOrDefault() ?? @default;
|
||||
}
|
||||
|
||||
[SuppressMessage("IDisposableAnalyzers.Correctness", "IDISP007:Don't dispose injected.", Justification = "RestResponse owns the response")]
|
||||
public virtual void Dispose()
|
||||
{
|
||||
Response.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
internal class RestResponse<T> : RestResponse
|
||||
|
@ -46,7 +46,8 @@ namespace TMDbLib.Utilities.Converters
|
||||
object result = Activator.CreateInstance(objectType);
|
||||
|
||||
// Populate the result
|
||||
serializer.Populate(jObject.CreateReader(), result);
|
||||
using JsonReader jsonReader = jObject.CreateReader();
|
||||
serializer.Populate(jsonReader, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -50,7 +50,8 @@ namespace TMDbLib.Utilities.Converters
|
||||
}
|
||||
|
||||
// Populate the result
|
||||
serializer.Populate(jObject.CreateReader(), result);
|
||||
using JsonReader jsonReader = jObject.CreateReader();
|
||||
serializer.Populate(jsonReader, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -13,7 +13,9 @@ namespace TMDbLib.Utilities.Converters
|
||||
JObject jObject = JObject.Load(reader);
|
||||
|
||||
T target = GetInstance(jObject);
|
||||
serializer.Populate(jObject.CreateReader(), target);
|
||||
|
||||
using JsonReader jsonReader = jObject.CreateReader();
|
||||
serializer.Populate(jsonReader, target);
|
||||
|
||||
return target;
|
||||
}
|
||||
|
@ -48,7 +48,8 @@ namespace TMDbLib.Utilities.Converters
|
||||
}
|
||||
|
||||
// Populate the result
|
||||
serializer.Populate(jObject.CreateReader(), result);
|
||||
using JsonReader jsonReader = jObject.CreateReader();
|
||||
serializer.Populate(jsonReader, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -19,7 +19,9 @@ namespace TMDbLib.Utilities.Converters
|
||||
JObject jObject = JObject.Load(reader);
|
||||
|
||||
TaggedImage result = new TaggedImage();
|
||||
serializer.Populate(jObject.CreateReader(), result);
|
||||
|
||||
using (JsonReader jsonReader = jObject.CreateReader())
|
||||
serializer.Populate(jsonReader, result);
|
||||
|
||||
JToken mediaJson = jObject["media"];
|
||||
switch (result.MediaType)
|
||||
|
@ -58,11 +58,13 @@ namespace TMDbLibTests
|
||||
[Fact]
|
||||
public async Task TestGenreMoviesAsync()
|
||||
{
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
SearchContainerWithId<SearchMovie> movies = await TMDbClient.GetGenreMoviesAsync(IdHelper.AdventureMovieGenre);
|
||||
|
||||
Assert.NotEmpty(movies.Results);
|
||||
Assert.Equal(IdHelper.AdventureMovieGenre, movies.Id);
|
||||
Assert.All(movies.Results, x => Assert.Contains(IdHelper.AdventureMovieGenre, x.GenreIds));
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -163,8 +163,8 @@ namespace TMDbLibTests.JsonHelpers
|
||||
|
||||
public int Compare(object x, object y)
|
||||
{
|
||||
object? valX = _property.GetValue(x);
|
||||
object? valY = _property.GetValue(y);
|
||||
object valX = _property.GetValue(x);
|
||||
object valY = _property.GetValue(y);
|
||||
|
||||
return Comparer.Default.Compare(valX, valY);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user