< Summary - Kestrun — Combined Coverage

Information
Class: Kestrun.Callback.HttpCallbackSender
Assembly: Kestrun
File(s): /home/runner/work/Kestrun/Kestrun/src/CSharp/Kestrun/Callback/HttpCallbackSender.cs
Tag: Kestrun/Kestrun@ca54e35c77799b76774b3805b6f075cdbc0c5fbe
Line coverage
100%
Covered lines: 25
Uncovered lines: 0
Coverable lines: 25
Total lines: 67
Line coverage: 100%
Branch coverage
100%
Covered branches: 10
Total branches: 10
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100 01/02/2026 - 00:16:25 Line coverage: 100% (25/25) Branch coverage: 100% (10/10) Total lines: 67 Tag: Kestrun/Kestrun@8405dc23b786b9d436fba0d65fb80baa4171e1d0 01/02/2026 - 00:16:25 Line coverage: 100% (25/25) Branch coverage: 100% (10/10) Total lines: 67 Tag: Kestrun/Kestrun@8405dc23b786b9d436fba0d65fb80baa4171e1d0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
SendAsync()100%1010100%

File(s)

/home/runner/work/Kestrun/Kestrun/src/CSharp/Kestrun/Callback/HttpCallbackSender.cs

#LineLine coverage
 1namespace Kestrun.Callback;
 2/// <summary>
 3/// Sender for performing callback requests.
 4/// </summary>
 5/// <remarks>
 6/// Initializes a new instance of the <see cref="HttpCallbackSender"/> class.
 7/// </remarks>
 8/// <param name="http"> The HTTP client to use for sending requests.</param>
 9/// <param name="signer"> The optional callback signer for signing requests.</param>
 510public sealed class HttpCallbackSender(HttpClient http, ICallbackSigner? signer = null) : ICallbackSender
 11{
 512    private readonly HttpClient _http = http;
 513    private readonly ICallbackSigner? _signer = signer; // optional
 14
 15    /// <summary>
 16    /// Sends a callback request via HTTP.
 17    /// </summary>
 18    /// <param name="r"> The callback request to send.</param>
 19    /// <param name="ct"> The cancellation token.</param>
 20    /// <returns> A task that represents the asynchronous operation, containing the callback result.</returns>
 21    public async Task<CallbackResult> SendAsync(CallbackRequest r, CancellationToken ct)
 22    {
 523        using var cts = CancellationTokenSource.CreateLinkedTokenSource(ct);
 524        cts.CancelAfter(r.Timeout);
 25
 526        using var msg = new HttpRequestMessage(new HttpMethod(r.HttpMethod), r.TargetUrl);
 27
 1228        foreach (var kv in r.Headers)
 29        {
 130            _ = msg.Headers.TryAddWithoutValidation(kv.Key, kv.Value);
 31        }
 32
 533        _ = msg.Headers.TryAddWithoutValidation("X-Correlation-Id", r.CorrelationId);
 534        _ = msg.Headers.TryAddWithoutValidation("Idempotency-Key", r.IdempotencyKey);
 35
 536        if (r.Body != null)
 37        {
 238            msg.Content = new ByteArrayContent(r.Body);
 239            msg.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(r.ContentType);
 40        }
 541        _signer?.Sign(msg, r); // HMAC signature etc.
 42
 43        try
 44        {
 545            using var resp = await _http.SendAsync(msg, HttpCompletionOption.ResponseHeadersRead, cts.Token);
 346            var code = (int)resp.StatusCode;
 47
 48            // treat 2xx as success
 349            if (code is >= 200 and <= 299)
 50            {
 251                return new CallbackResult(true, code, null, null, DateTimeOffset.UtcNow);
 52            }
 53
 54            // read a small snippet for diagnostics (cap size)
 155            var err = resp.ReasonPhrase;
 156            return new CallbackResult(false, code, "HttpError", err, DateTimeOffset.UtcNow);
 57        }
 158        catch (OperationCanceledException oce) when (!ct.IsCancellationRequested)
 59        {
 160            return new CallbackResult(false, null, "Timeout", oce.Message, DateTimeOffset.UtcNow);
 61        }
 162        catch (HttpRequestException hre)
 63        {
 164            return new CallbackResult(false, null, "HttpRequestException", hre.Message, DateTimeOffset.UtcNow);
 65        }
 566    }
 67}