Codebelt

Cuemon.Extensions.Net

Uri-centric HTTP calls and tamper-resistant links for Cuemon-based applications.

.NET 10.0 / .NET 9.0 MIT v10.5.3 26,977 downloads

Overview

Cuemon.Extensions.Net adds Uri-centered HTTP workflows, query-string helpers, URL encoding helpers, and signed URI support on top of Cuemon.Net and System.Net. Its two distinctive areas are a lightweight IHttpClientFactory implementation for managed HttpClient reuse and a pair of signing APIs that turn ordinary links into time-bounded, tamper-resistant URIs.

It also fills smaller gaps around query-string generation, status-code classification, and URL encoding so callers can stay in Uri, NameValueCollection, IDictionary<string, string[]>, string, and byte[] workflows instead of hand-assembling transport details.

Key APIs

SlimHttpClientFactory creates HttpClient instances from a Func<HttpClientHandler> and, on supported target frameworks, also exposes CreateHandler through IHttpMessageHandlerFactory. Internally it tracks active handlers, moves expired handlers into a sweep queue, and disposes inner handlers only after the tracking wrapper is no longer alive.

SlimHttpClientFactoryOptions controls handler reuse through HandlerLifetime. The default lifetime is five minutes, and the setter clamps lower values to the factory's 15 second expiration timer threshold.

Cuemon.Extensions.Net.Http.UriExtensions adds HttpGetAsync, HttpDeleteAsync, HttpPostAsync, HttpPatchAsync, HttpPutAsync, HttpTraceAsync, and generic HttpAsync overloads directly on Uri. Those methods all route through HttpManagerFactory.CreateManager(DefaultHttpClientFactory, HandlerName), which lets consumers swap the default factory once and keep the call site at the Uri level.

StringExtensions.ToSignedUri signs a URI string by appending query-string fields for start time, expiry time, and signature. The implementation canonicalizes the URI, computes an HMAC through KeyedHashFactory.CreateHmacCrypto, and returns a new signed Uri.

Cuemon.Extensions.Net.Security.UriExtensions adds ToSignedUri and ValidateSignedUri to Uri. The validation path checks the optional start and expiry windows, recomputes the signature from the canonical representation, and throws SecurityException when the signed URI has been altered or is outside its validity window.

SignedUriOptions configures how signing works. It exposes the HMAC algorithm, field names, URL-encoding behavior, an optional Content-MD5 header contribution, and a canonical representation builder, with defaults of HmacSha256, sig, st, and se.

Basic usage

using System;
using System.Security;
using System.Text;
using Codebelt.Extensions.Xunit;
using Cuemon.Extensions.Net.Security;
using Xunit;

namespace Contoso.Downloads.Tests;

public class SignedDownloadLinkTest : Test
{
    public SignedDownloadLinkTest(ITestOutputHelper output) : base(output)
    {
    }

    [Fact]
    public void ShouldRejectTamperedDownloadLink()
    {
        var secret = Encoding.UTF8.GetBytes("cuemon");
        var now = DateTime.UtcNow;
        var download = new Uri("https://cdn.example.test/packages/report.csv?tenant=42");
        var signed = download.ToSignedUri(secret, signedStart: now.AddMinutes(-1), signedExpiry: now.AddMinutes(5));
        var tampered = new UriBuilder(signed) { Query = signed.Query.TrimStart('?') + "&format=json" }.Uri;

        TestOutput.WriteLine(signed.OriginalString);

        signed.ValidateSignedUri(secret);
        Assert.Throws<SecurityException>(() => tampered.ValidateSignedUri(secret));
    }
}

Use this pattern when you issue download or callback links and need the receiver to reject tampered query strings without keeping server-side signing state. It matters because the validity window and signature travel with the URI, so verification stays explicit at the boundary where the link is consumed.

Installation

dotnet add package Cuemon.Extensions.Net

Usage guidance

Adopt this package when you want Cuemon.Net HTTP abstractions exposed as Uri extension methods or when you need signed query parameters with configurable field names, canonicalization, and expiry checks. Prefer the built-in Microsoft.Extensions.Http registration model when typed or named clients are already enough, and prefer Cuemon.Net alone when you need the lower-level HTTP manager APIs without the System.Net extension layer.

Family packages