question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Rate limiter context HttpContext feature API proposal

See original GitHub issue

Background and Motivation

In https://github.com/dotnet/aspnetcore/issues/44140 issue, one of The dream scenario for a better ASP.NET Core rate limiter middleware as @maartenba says, would be able Have a feature on the current HttpContext that gives access to the current rate limit context, so these details can also be returned on successful requests, or added to telemetry… This API proposal addresses this concern.

Proposed API

Below API supposes, that we have RateLimiterMiddleware in our app, which responsibility is to create IRateLimiterContextFeature for each request:

var app = builder.Build();

app.UseRateLimiter();

Now we can access to this interface in any custom middleware or controller:

namespace Microsoft.AspNetCore.RateLimiting.Features;

public interface IRateLimiterContextFeature
{
     HttpContext HttpContext { get; set; }

     RateLimitLease Lease { get; set; } 

     PartitionedRateLimiter<HttpContext>? GlobalLimiter { get; set; }

     PartitionedRateLimiter<HttpContext> EndpointLimiter { get; set; }
}

Usage Examples

Scenario 1: get statistics from limiters in custom telemetry middleware:

public Task Invoke(HttpContext context)
{
    var rlContext = context.Features.Get<IRateLimiterContextFeature>();

    var globalStatistics = rlContext.GlobalLimiter.GetStatistics(context);
    var endpointStatistics = rlContext.EndpointLimiter.GetStatistics(context);

    _someTelemetryService.PushStatisticsToPrometheus(globalStatistics);
    _someTelemetryService.PushStatisticsToPrometheus(endpointStatistics);
}

Scenario 2: Get metadata from successful RateLimiterLease for this request

public Task Invoke(HttpContext context)
{
    var rlContext = context.Features.Get<IRateLimiterContextFeature>();

    if (rlContext.Lease.TryGetMetadata("SOME_METADATA", out var metadata)
    {
        // Do some additional stuff, depends on metadata
    }
}

Alternative Design - 1

As @Tratcher said, there is a risk, that RateLimitLease would be disposed early. To prevent that, we can introduce facade-like class to wrap Lease with undisposable entity:


public interface IRateLimiterContextFeature
{
         HttpContext HttpContext { get; }

         RateLimitLeaseInfo LeaseInfo { get; } 

         PartitionedRateLimiter<HttpContext>? GlobalLimiter { get; }

         PartitionedRateLimiter<HttpContext> EndpointLimiter { get; }
}

public abstract class RateLimitLeaseInfo 
{
        // Same props as RateLimitLease, but without Dispose()
}

Alternative Design - 2

Also, Instead of using HttpContext Features, we can use HttpContext.Items and Extension methods, like its done in Microsoft.AspNetCore.Authentication extention methods (HttpContext.SingIn, HttpContext.ChallangeAsync, etc). So, we use the Alternative Design - 1 approach with Facade-like api, but implemented with extension methods

// very simple example of implementation (for only 1 method) just to show the API
public static class HttpContextRateLimiterExtentions
{
    public static RateLimiterStatistics GetRateLimiterStatistics(this HttpContext context)
    {
        // just for example - the code is not correct
        var limiter = (PartitionedRateLimiter<HttpContext>)context.Items["SomeGlobalLimiter"];
        var stats = limiter?.GetStatistics(context);
        return stats;
    }
}

// and then in some middleware:
var statistics = HttpContext.GetRateLimiterStatistics();

Risks

In Design 1:

  • would anyone use this to dispose of the lease early? Would that have any strange side-effects, especially if it got double-disposed by the middleware later?

Issue Analytics

  • State:open
  • Created 9 months ago
  • Comments:36 (35 by maintainers)

github_iconTop GitHub Comments

1reaction
mitchdennycommented, Jul 3, 2023

It looks like this hasn’t been implemented yet. I’d like to revisit the conversation in light of the following issue:

https://github.com/dotnet/aspnetcore/issues/47456

This issue illustrates a scenario where being able to access the global/endpoint limiters via a feature inside some middleware could be useful. For example you might use rate limiters to automatically consume a token for every request, but after a request has been processed you might decide that particular request was more expensive so you want to take more tokens.

If we exposed the rate limiters via a feature this could be easily implemented. Even though this API proposal was more about statistics, by exposing the rate limiters we would allow both scenarios.

/cc @halter73

Read more comments on GitHub >

github_iconTop Results From Across the Web

Rate limiter context HttpContext feature API proposal
NET framework for building modern cloud-based web applications on Windows, Mac, or Linux. - Rate limiter context HttpContext feature API proposal ...
Read more >
Announcing Rate Limiting for .NET - .NET Blog
Rate limiting is the concept of limiting how much a resource can be accessed. For example, you know that a database your application...
Read more >
Rate limiting middleware in ASP.NET Core
RateLimiting middleware provides rate limiting middleware. Apps configure rate limiting policies and then attach the policies to endpoints. Apps ...
Read more >
Microsoft Releases New .NET Rate Limiter in .NET 7
NET rate limiter has been designed to handle thousands of concurrent requests with minimal overhead — making it perfect for high traffic sites ......
Read more >
New in ASP.NET Core 7: Rate Limiting Middleware
A rate limiter improves the security of our applications. It acts as a flow controller that prevents malicious or fraudulent use of our...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found