AaronErhardt / actix-governor

A middleware for actix-web that provides rate-limiting backed by governor.
GNU General Public License v3.0
103 stars 21 forks source link

Add the possibility to whitelist some paths #40

Closed fistons closed 1 year ago

fistons commented 1 year ago

It may be useful to ignore a list of path in the rate limiter.

Associated PR: https://github.com/AaronErhardt/actix-governor/pull/39

fistons commented 1 year ago

A bit more context here.

I have my actix app configured like this:

    HttpServer::new(move || {
        App::new()
            .wrap(tracing_actix_web::TracingLogger::default())
            .wrap(sentry_actix::Sentry::default())
            .app_data(services.clone())
            .app_data(redis.clone())
            .configure(routes::configure)
            .service(actix_files::Files::new("/", "./static/").index_file("index.html"))
    })
    .listen(listener)?
    .run()
    .await

All my API routes are configured in routes::configure (which itself call other modules' ::configure )

The only paths that I don't want to see rate limited are:

Those are some static files and I don't see why I should rate limit them for the moment.

But it seems that I can apply the middleware only for certain paths, although I don't get how to do this

fistons commented 1 year ago

Ok, I found a solution using web::scope, allowing me to apply the rate limiting to a certain prefix, which match my use case

Pat-1337 commented 1 year ago

@fistons Could you please provide an example on how you did that?

fistons commented 1 year ago

Sure, here is how I did it:


pub async fn startup(
    database: DatabaseConnection,
    redis: Pool,
    listener: TcpListener,
) -> std::io::Result<()> {
    let application_service = build_services(&database);

    let governor_conf = build_rate_limiting_conf();
    let services = Data::new(application_service);
    let redis = Data::new(redis);

    HttpServer::new(move || {
        App::new()
            .wrap(tracing_actix_web::TracingLogger::default())
            .wrap(sentry_actix::Sentry::default())
            .app_data(services.clone())
            .app_data(redis.clone())
            .service(routes::ping)
            .service(
                web::scope("/api/v1")  // <-- Here I create a scope. The governor/rate limiting only applies to the routes prefixed by /api/v1
                    .wrap(Governor::new(&governor_conf))
                    .configure(routes::configure),
            )
            .service(actix_files::Files::new("/", "./static/").index_file("index.html"))
    })
    .listen(listener)?
    .run()
    .await