Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ jobs:
steps:
- uses: actions/checkout@v4

- name: Setup .NET 8.0
- name: Setup .NET SDK
uses: actions/setup-dotnet@v3
with:
dotnet-version: '8.0.x'
dotnet-version: '10.0.x'

- name: Install Kampose
run: dotnet tool install --global kampose
Expand All @@ -43,3 +43,4 @@ jobs:
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./.site
keep_files: false
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2024 Kampute
// Copyright (C) 2025 Kampute
//
// This file is part of the Kampute.HttpClient.DataContract package and is released under the terms of the MIT license.
// See the LICENSE file in the project root for the full license text.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
<Title>Kampute.HttpClient.DataContract</Title>
<Description>This package is an extension package for Kampute.HttpClient, enhancing it to manage application/xml content types, using DataContractSerializer for serialization and deserialization of XML responses and payloads.</Description>
<Authors>Kambiz Khojasteh</Authors>
<Version>2.4.0</Version>
<Version>2.5.0</Version>
<Company>Kampute</Company>
<Copyright>Copyright (c) 2024 Kampute</Copyright>
<Copyright>Copyright (c) 2025 Kampute</Copyright>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<IncludeSymbols>true</IncludeSymbols>
Expand Down
2 changes: 1 addition & 1 deletion src/Kampute.HttpClient.DataContract/NamespaceDoc.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2024 Kampute
// Copyright (C) 2025 Kampute
//
// This file is part of the Kampute.HttpClient package and is released under the terms of the MIT license.
// See the LICENSE file in the project root for the full license text.
Expand Down
2 changes: 1 addition & 1 deletion src/Kampute.HttpClient.DataContract/XmlContent.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2024 Kampute
// Copyright (C) 2025 Kampute
//
// This file is part of the Kampute.HttpClient.DataContract package and is released under the terms of the MIT license.
// See the LICENSE file in the project root for the full license text.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2024 Kampute
// Copyright (C) 2025 Kampute
//
// This file is part of the Kampute.HttpClient.DataContract package and is released under the terms of the MIT license.
// See the LICENSE file in the project root for the full license text.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2024 Kampute
// Copyright (C) 2025 Kampute
//
// This file is part of the Kampute.HttpClient.Json package and is released under the terms of the MIT license.
// See the LICENSE file in the project root for the full license text.
Expand Down
2 changes: 1 addition & 1 deletion src/Kampute.HttpClient.Json/JsonContent.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2024 Kampute
// Copyright (C) 2025 Kampute
//
// This file is part of the Kampute.HttpClient.Json package and is released under the terms of the MIT license.
// See the LICENSE file in the project root for the full license text.
Expand Down
2 changes: 1 addition & 1 deletion src/Kampute.HttpClient.Json/JsonContentDeserializer.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2024 Kampute
// Copyright (C) 2025 Kampute
//
// This file is part of the Kampute.HttpClient.Json package and is released under the terms of the MIT license.
// See the LICENSE file in the project root for the full license text.
Expand Down
6 changes: 3 additions & 3 deletions src/Kampute.HttpClient.Json/Kampute.HttpClient.Json.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
<Title>Kampute.HttpClient.Json</Title>
<Description>This package is an extension package for Kampute.HttpClient, enhancing it to manage application/json content types, using System.Text.Json library for serialization and deserialization of JSON responses and payloads.</Description>
<Authors>Kambiz Khojasteh</Authors>
<Version>2.4.0</Version>
<Version>2.5.0</Version>
<Company>Kampute</Company>
<Copyright>Copyright (c) 2024 Kampute</Copyright>
<Copyright>Copyright (c) 2025 Kampute</Copyright>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<IncludeSymbols>true</IncludeSymbols>
Expand Down Expand Up @@ -36,7 +36,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="System.Text.Json" Version="10.0.0" />
<PackageReference Include="System.Text.Json" Version="10.*" />
</ItemGroup>

<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion src/Kampute.HttpClient.Json/NamespaceDoc.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2024 Kampute
// Copyright (C) 2025 Kampute
//
// This file is part of the Kampute.HttpClient package and is released under the terms of the MIT license.
// See the LICENSE file in the project root for the full license text.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2024 Kampute
// Copyright (C) 2025 Kampute
//
// This file is part of the Kampute.HttpClient.NewtonsoftJson package and is released under the terms of the MIT license.
// See the LICENSE file in the project root for the full license text.
Expand Down
2 changes: 1 addition & 1 deletion src/Kampute.HttpClient.NewtonsoftJson/JsonContent.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2024 Kampute
// Copyright (C) 2025 Kampute
//
// This file is part of the Kampute.HttpClient.NewtonsoftJson package and is released under the terms of the MIT license.
// See the LICENSE file in the project root for the full license text.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2024 Kampute
// Copyright (C) 2025 Kampute
//
// This file is part of the Kampute.HttpClient.NewtonsoftJson package and is released under the terms of the MIT license.
// See the LICENSE file in the project root for the full license text.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
<Title>Kampute.HttpClient.NewtonsoftJson</Title>
<Description>This package is an extension package for Kampute.HttpClient, enhancing it to manage application/json content types, using Newtonsoft.Json library for serialization and deserialization of JSON responses and payloads.</Description>
<Authors>Kambiz Khojasteh</Authors>
<Version>2.4.0</Version>
<Version>2.5.0</Version>
<Company>Kampute</Company>
<Copyright>Copyright (c) 2024 Kampute</Copyright>
<Copyright>Copyright (c) 2025 Kampute</Copyright>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<IncludeSymbols>true</IncludeSymbols>
Expand Down Expand Up @@ -36,7 +36,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
<PackageReference Include="Newtonsoft.Json" Version="13.*" />
</ItemGroup>

<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion src/Kampute.HttpClient.NewtonsoftJson/NamespaceDoc.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2024 Kampute
// Copyright (C) 2025 Kampute
//
// This file is part of the Kampute.HttpClient package and is released under the terms of the MIT license.
// See the LICENSE file in the project root for the full license text.
Expand Down
2 changes: 1 addition & 1 deletion src/Kampute.HttpClient.Xml/HttpRestClientXmlExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2024 Kampute
// Copyright (C) 2025 Kampute
//
// This file is part of the Kampute.HttpClient.Xml package and is released under the terms of the MIT license.
// See the LICENSE file in the project root for the full license text.
Expand Down
4 changes: 2 additions & 2 deletions src/Kampute.HttpClient.Xml/Kampute.HttpClient.Xml.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
<Title>Kampute.HttpClient.Xml</Title>
<Description>This package is an extension package for Kampute.HttpClient, enhancing it to manage application/xml content types, using XmlSerializer for serialization and deserialization of XML responses and payloads.</Description>
<Authors>Kambiz Khojasteh</Authors>
<Version>2.4.0</Version>
<Version>2.5.0</Version>
<Company>Kampute</Company>
<Copyright>Copyright (c) 2024 Kampute</Copyright>
<Copyright>Copyright (c) 2025 Kampute</Copyright>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<IncludeSymbols>true</IncludeSymbols>
Expand Down
2 changes: 1 addition & 1 deletion src/Kampute.HttpClient.Xml/NamespaceDoc.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2024 Kampute
// Copyright (C) 2025 Kampute
//
// This file is part of the Kampute.HttpClient package and is released under the terms of the MIT license.
// See the LICENSE file in the project root for the full license text.
Expand Down
2 changes: 1 addition & 1 deletion src/Kampute.HttpClient.Xml/XmlContent.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2024 Kampute
// Copyright (C) 2025 Kampute
//
// This file is part of the Kampute.HttpClient.Xml package and is released under the terms of the MIT license.
// See the LICENSE file in the project root for the full license text.
Expand Down
2 changes: 1 addition & 1 deletion src/Kampute.HttpClient.Xml/XmlContentDeserializer.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2024 Kampute
// Copyright (C) 2025 Kampute
//
// This file is part of the Kampute.HttpClient.Xml package and is released under the terms of the MIT license.
// See the LICENSE file in the project root for the full license text.
Expand Down
2 changes: 1 addition & 1 deletion src/Kampute.HttpClient/AuthSchemes.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2024 Kampute
// Copyright (C) 2025 Kampute
//
// This file is part of the Kampute.HttpClient package and is released under the terms of the MIT license.
// See the LICENSE file in the project root for the full license text.
Expand Down
2 changes: 1 addition & 1 deletion src/Kampute.HttpClient/BackoffStrategies.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2024 Kampute
// Copyright (C) 2025 Kampute
//
// This file is part of the Kampute.HttpClient package and is released under the terms of the MIT license.
// See the LICENSE file in the project root for the full license text.
Expand Down
2 changes: 1 addition & 1 deletion src/Kampute.HttpClient/Content/Abstracts/NamespaceDoc.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2024 Kampute
// Copyright (C) 2025 Kampute
//
// This file is part of the Kampute.HttpClient package and is released under the terms of the MIT license.
// See the LICENSE file in the project root for the full license text.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2024 Kampute
// Copyright (C) 2025 Kampute
//
// This file is part of the Kampute.HttpClient package and is released under the terms of the MIT license.
// See the LICENSE file in the project root for the full license text.
Expand Down
2 changes: 1 addition & 1 deletion src/Kampute.HttpClient/Content/Compression/NamespaceDoc.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2024 Kampute
// Copyright (C) 2025 Kampute
//
// This file is part of the Kampute.HttpClient package and is released under the terms of the MIT license.
// See the LICENSE file in the project root for the full license text.
Expand Down
2 changes: 1 addition & 1 deletion src/Kampute.HttpClient/Content/NamespaceDoc.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2024 Kampute
// Copyright (C) 2025 Kampute
//
// This file is part of the Kampute.HttpClient package and is released under the terms of the MIT license.
// See the LICENSE file in the project root for the full license text.
Expand Down
13 changes: 13 additions & 0 deletions src/Kampute.HttpClient/ErrorHandlers/Abstracts/NamespaceDoc.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright (C) 2025 Kampute
//
// This file is part of the Kampute.HttpClient package and is released under the terms of the MIT license.
// See the LICENSE file in the project root for the full license text.

namespace Kampute.HttpClient.ErrorHandlers.Abstracts
{
/// <summary>
/// This namespace contains abstract classes for handling transient HTTP error responses by implementing
/// backoff and retry strategies.
/// </summary>
internal static class NamespaceDoc { }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
// Copyright (C) 2025 Kampute
//
// This file is part of the Kampute.HttpClient package and is released under the terms of the MIT license.
// See the LICENSE file in the project root for the full license text.

namespace Kampute.HttpClient.ErrorHandlers.Abstracts
{
using Kampute.HttpClient.Interfaces;
using System;
using System.Net;
using System.Threading;
using System.Threading.Tasks;

/// <summary>
/// Provides the base functionality for handling HTTP responses with transient error status codes by attempting to back off and
/// retry the request according to a specified or default backoff strategy.
/// </summary>
/// <remarks>
/// This handler class is designed to be extended for specific transient error status codes. It offers a mechanism to respond to
/// transient HTTP errors by retrying the request after a delay. The delay duration and retry logic can be customized through the
/// <see cref="OnBackoffStrategy"/> delegate.
/// </remarks>
/// <seealso cref="HttpRestClient.ErrorHandlers"/>
/// <seealso cref="HttpRestClient.BackoffStrategy"/>
public abstract class RetryableHttpErrorHandler : IHttpErrorHandler
{
/// <summary>
/// A delegate that allows customization of the backoff strategy when responses with transient error status codes are received.
/// </summary>
/// <value>
/// A function that takes an <see cref="HttpResponseErrorContext"/> and an optional <see cref="DateTimeOffset"/> representing
/// the suggested retry time, and returns an <see cref="IHttpBackoffProvider"/> to be used for the retry operation.
/// </value>
/// <remarks>
/// <para>
/// If this delegate is set and returns an <see cref="IHttpBackoffProvider"/>, the returned strategy is used for the retry operation.
/// If it is not set, or returns <see langword="null"/>, a default behavior is applied.
/// </para>
/// <para>
/// The delegate receives the following parameters:
/// <list type="bullet">
/// <item>
/// <term>context</term>
/// <description>
/// Provides context about the HTTP response that indicates a transient error. It is encapsulated within an <see cref="HttpResponseErrorContext"/>
/// instance, allowing for an informed decision on the retry strategy.
/// </description>
/// </item>
/// <item>
/// <term>retryTime</term>
/// <description>
/// Advises on the next retry attempt timing as a <see cref="DateTimeOffset"/> value if the response suggests one. If the response
/// does not include a suggested retry time, the value will be <see langword="null"/>.
/// </description>
/// </item>
/// </list>
/// </para>
/// </remarks>
public Func<HttpResponseErrorContext, DateTimeOffset?, IHttpBackoffProvider?>? OnBackoffStrategy { get; set; }

/// <summary>
/// Determines whether this handler can process the specified HTTP status code.
/// </summary>
/// <param name="statusCode">The HTTP status code to evaluate.</param>
/// <returns><see langword="true"/> if the handler can process the status code; otherwise, <see langword="false"/>.</returns>
public abstract bool CanHandle(HttpStatusCode statusCode);

/// <summary>
/// Extracts the suggested retry time from the HTTP response's header, if present.
/// </summary>
/// <param name="ctx">The context containing information about the HTTP response.</param>
/// <returns>The suggested <see cref="DateTimeOffset"/> to retry the request, or <see langword="null"/> if the header is not present.</returns>
/// <exception cref="ArgumentNullException">Thrown if <paramref name="ctx"/> is <see langword="null"/>.</exception>
protected virtual DateTimeOffset? GetSuggestedRetryTime(HttpResponseErrorContext ctx)
{
if (ctx is null)
throw new ArgumentNullException(nameof(ctx));

ctx.Response.Headers.TryExtractRetryAfterTime(out var retryTime);
return retryTime;
}

/// <summary>
/// Provides the default backoff strategy when no custom strategy is specified.
/// </summary>
/// <param name="ctx">The context containing information about the HTTP response.</param>
/// <param name="retryTime">The suggested retry time, if any.</param>
/// <returns>An <see cref="IHttpBackoffProvider"/> representing the default backoff strategy.</returns>
/// <exception cref="ArgumentNullException">Thrown if <paramref name="ctx"/> is <see langword="null"/>.</exception>
protected virtual IHttpBackoffProvider GetDefaultStrategy(HttpResponseErrorContext ctx, DateTimeOffset? retryTime)
{
if (ctx is null)
throw new ArgumentNullException(nameof(ctx));

return retryTime.HasValue ? BackoffStrategies.Once(retryTime.Value) : ctx.Client.BackoffStrategy;
}

/// <summary>
/// Creates a scheduler for retrying the failed request based on the error context.
/// </summary>
/// <param name="ctx">The context containing information about the HTTP response that indicates a failure.</param>
/// <returns>An <see cref="IRetryScheduler"/> that schedules the retry attempts.</returns>
/// <exception cref="ArgumentNullException">Thrown if <paramref name="ctx"/> is <see langword="null"/>.</exception>
/// <remarks>
/// The method uses <see cref="OnBackoffStrategy"/> when available. If the delegate is not provided or returns
/// <see langword="null"/>, and the response includes a suggested retry time, a single retry at that time is used.
/// Otherwise the client's default backoff strategy is used.
/// </remarks>
protected virtual IRetryScheduler? CreateScheduler(HttpResponseErrorContext ctx)
{
if (ctx is null)
throw new ArgumentNullException(nameof(ctx));

var retryTime = GetSuggestedRetryTime(ctx);
var strategy = OnBackoffStrategy?.Invoke(ctx, retryTime) ?? GetDefaultStrategy(ctx, retryTime);
return strategy.CreateScheduler(ctx);
}

/// <inheritdoc/>
Task<HttpErrorHandlerResult> IHttpErrorHandler.DecideOnRetryAsync(HttpResponseErrorContext ctx, CancellationToken cancellationToken)
{
return ctx.ScheduleRetryAsync(CreateScheduler, cancellationToken);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2024 Kampute
// Copyright (C) 2025 Kampute
//
// This file is part of the Kampute.HttpClient package and is released under the terms of the MIT license.
// See the LICENSE file in the project root for the full license text.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2024 Kampute
// Copyright (C) 2025 Kampute
//
// This file is part of the Kampute.HttpClient package and is released under the terms of the MIT license.
// See the LICENSE file in the project root for the full license text.
Expand Down
Loading