Skip to content

A wrapper for HttpClient that caches to disk. Cached files, over the max specified, are deleted based on the last access times.

License

Notifications You must be signed in to change notification settings

SimonCropp/Replicant

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Replicant

Build status NuGet Status

A wrapper for HttpClient that caches to disk. Cached files, over the max specified, are deleted based on the last access times.

See Milestones for release notes.

Headers/Responses respected in caching decisions:

NuGet package

https://nuget.org/packages/Replicant/

Usage

Default instance

There is a default static instance:

var content = await HttpCache.Default.DownloadAsync("https://httpbin.org/status/200");

snippet source | anchor

This caches to {Temp}/Replicant.

Construction

An instance of HttpCache should be long running.

var httpCache = new HttpCache(
    cacheDirectory,
    // omit for default new HttpClient()
    new HttpClient
    {
        Timeout = TimeSpan.FromSeconds(30)
    },
    // omit for the default of 1000
    maxEntries: 10000);

// Dispose when finished
await httpCache.DisposeAsync();

snippet source | anchor

Dependency injection

Add HttpCache as a singleton when using dependency injection.

var services = new ServiceCollection();
services.AddSingleton(_ => new HttpCache(cachePath));

using var provider = services.BuildServiceProvider();
var httpCache = provider.GetRequiredService<HttpCache>();
ClassicAssert.NotNull(httpCache);

snippet source | anchor

Using HttpClient with HttpClientFactory.

ServiceCollection services = new();
services.AddHttpClient();
services.AddSingleton(
    _ =>
    {
        var clientFactory = _.GetRequiredService<IHttpClientFactory>();
        return new HttpCache(cachePath, () => clientFactory.CreateClient());
    });

using var provider = services.BuildServiceProvider();
var httpCache = provider.GetRequiredService<HttpCache>();
ClassicAssert.NotNull(httpCache);

snippet source | anchor

Get a string

var content = await httpCache.StringAsync("https://httpbin.org/json");

snippet source | anchor

var lines = new List<string>();
await foreach (var line in httpCache.LinesAsync("https://httpbin.org/json"))
{
    lines.Add(line);
}

snippet source | anchor

Get bytes

var bytes = await httpCache.BytesAsync("https://httpbin.org/json");

snippet source | anchor

Get a stream

using var stream = await httpCache.StreamAsync("https://httpbin.org/json");

snippet source | anchor

Download to a file

await httpCache.ToFileAsync("https://httpbin.org/json", targetFile);

snippet source | anchor

Download to a stream

await httpCache.ToStreamAsync("https://httpbin.org/json", targetStream);

snippet source | anchor

Manually add an item to the cache

using var response = new HttpResponseMessage(HttpStatusCode.OK)
{
    Content = new StringContent("the content")
};
await httpCache.AddItemAsync(uri, response);

snippet source | anchor

Use stale item on error

If an error occurs when re-validating a potentially stale item, then the cached item can be used as a fallback.

var content = httpCache.StringAsync(uri, staleIfError: true);

snippet source | anchor

Customizing HttpRequestMessage

The HttpRequestMessage used can be customized using a callback.

var content = await httpCache.StringAsync(
    uri,
    modifyRequest: message =>
    {
        message.Headers.Add("Key1", "Value1");
        message.Headers.Add("Key2", "Value2");
    });

snippet source | anchor

Full HttpResponseMessage

An instance of the HttpResponseMessage can be created from a cached item:

using var response = await httpCache.ResponseAsync("https://httpbin.org/status/200");

snippet source | anchor

Influences / Alternatives

Icon

Cyborg designed by Symbolon from The Noun Project.

About

A wrapper for HttpClient that caches to disk. Cached files, over the max specified, are deleted based on the last access times.

Topics

Resources

License

Code of conduct

Stars

Watchers

Forks

Sponsor this project

 

Languages