Skip to content

HTTP reference ​

The HTTP components live in the NResilience namespace in the NResilience package.

HttpResilienceHandler ​

HttpResilienceHandler is a sealed class deriving from DelegatingHandler. It runs resilience policies around HTTP requests.

MemberDescription
HttpResilienceHandler(Resilience? policy = null, HttpResilienceOptions? options = null)Creates a handler where the inner handler is assigned later (e.g., by a client factory).
HttpResilienceHandler(HttpMessageHandler innerHandler, Resilience? policy = null, HttpResilienceOptions? options = null)Creates a handler that wraps a specific transport handler.
PolicyThe policy executed by the handler, before per-host scoping is applied. Defaults to Resilience.Http.
OptionsThe HttpResilienceOptions used to configure the handler.
BreakersByHost()Returns a snapshot of the circuit breakers currently managed by the handler, keyed by host.
BudgetsByHost()Returns a snapshot of the retry budgets currently managed by the handler, keyed by host.
WillRetry(HttpRequestMessage)Says whether a request would be retried, based on whether the policy allows multiple attempts and whether the request is repeatable.

Both constructors validate the provided policy. The synchronous Send method is not supported and throws a NotSupportedException.

HttpResilienceOptions ​

HttpResilienceOptions is a sealed class used to configure the HttpResilienceHandler. It is mutable to allow configuration via options callbacks.

PropertyDefaultDescription
RetryUnsafeMethodsfalseWhether POST and PATCH methods are retried.
OwnTransportTimeouttrueWhether the client's Timeout is set to Timeout.InfiniteTimeSpan. Honored by whoever builds the client.
BreakerPerHosttrueEnables per-host circuit breakers. If the policy already carries an explicit Breaker, that breaker is used instead.
BreakerSettingsnullThe settings used to create per-host breakers.
BudgetPerHosttrueEnables per-host retry budgets. An explicit Budget (including RetryBudget.None) takes precedence. RetryBudget.Automatic does not specify a scope, so per-host scoping applies.
MaximumHosts1024The number of hosts the per-host registry keeps. At least 1; the least-recently-seen hosts are dropped past the cap. There is no unbounded mode - int.MaxValue is as close as it gets.
DetectNestedRetriestrueWhether the nested-retry header is added to requests and whether nesting is reported.
BufferResponsesfalseWhether the response body is read inside the attempt, so a stalled or broken body is retried. Costs the body in memory.
ResumeDownloadsfalseWhether a body that stalls while the caller is reading it is resumed with a Range request instead of ending the read. See Resuming a stalled download.
PropagateDeadlinefalseWhether each attempt carries the time this side will wait for it: min(AttemptTimeout, time left on the deadline), in whole milliseconds, recomputed per attempt and per hedged leg. The gRPC switch of the same name defaults to true, because grpc-timeout is a protocol field rather than a convention.
DeadlineHeader"X-Deadline-Ms"The header PropagateDeadline writes. AmbientDeadline.Header is the same value, and is what the inbound middleware reads. Must not be empty.
PropagateCriticalityfalseWhether each request carries how much the work it is part of matters: AmbientCriticality.Current, as one of the four Criticality names. The same value on every attempt. See Criticality.
CriticalityHeader"X-Criticality"The header PropagateCriticality writes. AmbientCriticality.Header is the same value, and is what the inbound middleware reads. Must not be empty.
QuotaQuota.Reserving(0.1)The reserve to keep against the allowance the dependency publishes, or null to read no rate-limit headers. See Quota.
MethodDescription
Validate()Throws ResilienceConfigurationException listing every problem at once. HttpResilienceHandler's constructor calls it beside the policy's own Validate(), so a bad header name, bad BreakerSettings or bad Quota fails there rather than from the middle of a request. MaximumHosts below 1 is a problem it reports.
Validated()Runs Validate() and returns the options, so a bad configuration throws where it is written.

Quota ​

Quota is a sealed record holding the reserve to keep against the allowance the dependency publishes. It is HttpResilienceOptions.Quota, and it is on by default. See Honor the allowance the dependency publishes.

MemberDefaultDescription
Reserve0.1The fraction of the published allowance to leave unspent. At least 0 and less than 1. At 0, the handler refuses only once the dependency says nothing is left.
LegacyHeadersnullThe header triple to read when the standard fields are absent, in the order limit, remaining, reset. null means X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset. Exactly three names, or none.
Reserving(reserve = 0.1)-Static. The way to configure a reserve.
ToString()-The reserve, as text.

The handler reads two shapes off every response and keeps the numbers per host. The standard fields - RateLimit-Policy carrying the quota q and window w, and RateLimit carrying the remaining allowance r and the seconds until reset t - win where both shapes are present, and the most constraining member of RateLimit is the one that binds. The legacy triple's reset is whole seconds, read as a Unix timestamp when it is too large to be a count from now.

A refusal is Verdict.Refused, carrying the time until the window resets as the pushback: retried on the long backoff curve, never charged to the retry budget, never evidence against the host's breaker, and reported as the RejectedByQuota event and RateLimitedException. A host that publishes nothing, a remaining count with no quota to take a fraction of, a window that has already reset, and a malformed field all leave the guard with no opinion.

Resuming a stalled download ​

ResumeDownloads resumes a body that stalls while the caller is reading it, with an HTTP Range request, instead of ending the read with AttemptStalledException. It is the alternative BufferResponses offers for a caller who cannot hold a large body in memory: a download that stalls at 3.9 GB of 4 GB re-requests only what is left.

A resume is only ever attempted when it is safe. The first response has to carry a strong ETag and Accept-Ranges: bytes; the resumed request sends the ETag back as If-Range, so the server itself refuses to splice a representation that has since changed. A response missing either header, a resume request that fails outright, and a resume that comes back 200 where a 206 was expected all fall back to the ordinary stall - the worst case is identical to ResumeDownloads being off. A stream resumes at most five times before a further stall is reported rather than retried again.

Requires Resilience.BoundProgress, which is on by default, and applies only to GET. A successful resume raises StreamResumed, the same event a checkpointed stream's own resume raises - see Checkpointed resume.

HttpResilience ​

HttpResilience is a static class providing utility methods and constants for HTTP resilience. The two headers the integration reads and writes are AmbientDeadline.Header and NestedRetry.Header, each declared beside the ambient value it carries.

MemberDescription
CreateClient(policy = null, options = null, innerHandler = null)Creates an HttpClient with an HttpResilienceHandler in its pipeline. Disposing the client also disposes the handler chain.
RepeatableAn HttpRequestOptionsKey<bool> used to override the idempotency decision for a specific request.

HttpRequestExtensions ​

HttpRequestExtensions is a static class of per-request helpers over HttpResilience's option keys. Both return the same request, so they compose in an initializer. See Idempotency.

MemberDescription
MarkRepeatable(idempotencyKey = null, headerName = "Idempotency-Key")Sets HttpResilience.Repeatable to true and stamps the idempotency key header when a key is supplied. An existing header of that name is left alone.
MarkSingleShot()Sets HttpResilience.Repeatable to false, so the request is sent at most once whatever its method and whatever RetryUnsafeMethods says.

Default retryable methods ​

The handler retries the following methods by default: GET, HEAD, PUT, DELETE, OPTIONS, and TRACE.

The following are not retried unless configured otherwise: POST, PATCH, and any HTTP method not recognized by the library.

Released under the MIT License.