All Projects → TerminalWitchcraft → Actix Ratelimit

TerminalWitchcraft / Actix Ratelimit

Licence: mit
Rate limiter framework for Actix web

Programming Languages

rust
11053 projects

Projects that are alternatives of or similar to Actix Ratelimit

robotframework-httprequestlibrary
Robot Framework's library to test REST interfaces utilizing Apache HttpClient
Stars: ✭ 20 (-77.78%)
Mutual labels:  http-requests
Requests
Convenient http client for java, inspired by python request module
Stars: ✭ 459 (+410%)
Mutual labels:  http-requests
Breaker
Circuit breaker for HTTP requests in Elixir
Stars: ✭ 30 (-66.67%)
Mutual labels:  http-requests
Netswift
A type-safe, high-level networking solution for Swift apps
Stars: ✭ 21 (-76.67%)
Mutual labels:  http-requests
Htrace.sh
My simple Swiss Army knife for http/https troubleshooting and profiling.
Stars: ✭ 3,465 (+3750%)
Mutual labels:  http-requests
Faster Than Requests
Faster requests on Python 3
Stars: ✭ 639 (+610%)
Mutual labels:  http-requests
EthernetWebServer
This is simple yet complete WebServer library for AVR, Portenta_H7, Teensy, SAM DUE, SAMD21/SAMD51, nRF52, STM32, RP2040-based, etc. boards running Ethernet shields. The functions are similar and compatible to ESP8266/ESP32 WebServer libraries to make life much easier to port sketches from ESP8266/ESP32. Coexisting now with `ESP32 WebServer` and…
Stars: ✭ 118 (+31.11%)
Mutual labels:  http-requests
Embedio
A tiny, cross-platform, module based web server for .NET
Stars: ✭ 1,007 (+1018.89%)
Mutual labels:  http-requests
Karin
An elegant promise based HTTP client for the browser and node.js [WIP]
Stars: ✭ 393 (+336.67%)
Mutual labels:  http-requests
Http Factory
Implementation of PSR-17 (HTTP Message Factories)
Stars: ✭ 859 (+854.44%)
Mutual labels:  http-requests
Statcode
Man pages for HTTP status codes
Stars: ✭ 307 (+241.11%)
Mutual labels:  http-requests
Http Shortcuts
Android app to create home screen shortcuts that trigger arbitrary HTTP requests
Stars: ✭ 329 (+265.56%)
Mutual labels:  http-requests
Restclient
🦄 Simple HTTP and REST client for Unity based on Promises, also supports Callbacks! 🎮
Stars: ✭ 675 (+650%)
Mutual labels:  http-requests
The-PHP-Workshop
A New, Interactive Approach to Learning PHP
Stars: ✭ 30 (-66.67%)
Mutual labels:  http-requests
Easygo
基于Kotlin、OkHttp的声明式网络框架,像写HTML界面一样写网络调用代码
Stars: ✭ 40 (-55.56%)
Mutual labels:  http-requests
firehopper
Rhino Grasshopper's RESTful interface for Google Firebase
Stars: ✭ 18 (-80%)
Mutual labels:  http-requests
Httpu
The terminal-first http client
Stars: ✭ 619 (+587.78%)
Mutual labels:  http-requests
Logstash Input Http
Stars: ✭ 46 (-48.89%)
Mutual labels:  http-requests
Stormer
Wrappers for making load test with locust more convienient.
Stars: ✭ 41 (-54.44%)
Mutual labels:  http-requests
Gout
gout to become the Swiss Army Knife of the http client @^^@---> gout 是http client领域的瑞士军刀,小巧,强大,犀利。具体用法可看文档,如使用迷惑或者API用得不爽都可提issues
Stars: ✭ 749 (+732.22%)
Mutual labels:  http-requests

Travis (.org) Crates.io Crates.io

actix-ratelimit

Rate limiting middleware framework for actix-web

This crate provides an asynchronous and concurrent rate limiting middleware based on actor model which can be wraped around an Actix application. Middleware contains a store which is used to identify client request.

Check out the documentation here.

Comments, suggesstions and critiques are welcome!

Usage

Add this to your Cargo.toml:

[dependencies]
actix-ratelimit = "0.3.1"

Version 0.3.* supports actix-web v3. If you're using actix-web v2, consider using version 0.2.*.

Minimal example:

use actix_web::{web, App, HttpRequest, HttpServer, Responder};
use actix_ratelimit::{RateLimiter, MemoryStore, MemoryStoreActor};
use std::time::Duration;

async fn greet(req: HttpRequest) -> impl Responder{
    let name = req.match_info().get("name").unwrap_or("World!");
    format!("Hello {}!", &name)
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    // Initialize store
    let store = MemoryStore::new();
    HttpServer::new(move ||{
        App::new()
            // Register the middleware
            // which allows for a maximum of
            // 100 requests per minute per client
            // based on IP address
            .wrap(
                RateLimiter::new(
                MemoryStoreActor::from(store.clone()).start())
                    .with_interval(Duration::from_secs(60))
                    .with_max_requests(100)
            )
            .route("/", web::get().to(greet))
            .route("/{name}", web::get().to(greet))
    })
    .bind("127.0.0.1:8000")?
    .run()
    .await
}

Sending a request returns a response with the ratelimiting headers:

$ curl -i "http://localhost:8000/"

HTTP/1.1 200 OK
content-length: 13
content-type: text/plain; charset=utf-8
x-ratelimit-remaining: 99
x-ratelimit-reset: 52
x-ratelimit-limit: 100
date: Tue, 04 Feb 2020 21:53:27 GMT

Hello World!

Exceeding the limit returns HTTP 429 Error code.

Stores

A store is a data structure, database connection or anything which can be used to store ratelimit data associated with a client. A store actor which acts on this store is responsible for performiing all sorts of operations(SET, GET, DEL, etc). It is Important to note that there are multiple store actors acting on a single store.

List of features

  • memory (in-memory store based on concurrent hashmap)
  • redis-store (based on redis-rs)
  • memcached (based on r2d2-memcache, see note to developers below)

Implementing your own store

To implement your own store, you have to implement an Actor which can handle ActorMessage type and return ActorResponse type. Check the module level documentation for more details and a basic example.

Note to developers

  • By default, all features are enabled. To use a particular feature, for instance redis, put this in your Cargo.toml:
[dependencies]
actix-ratelimit = {version = "0.3.1", default-features = false, features = ["redis-store"]}
  • By default, the client's IP address is used as the identifier which can be customized using ServiceRequest instance. For example, using api key header to identify client:
#[actix_web::main]
async fn main() -> std::io::Result<()> {
    // Initialize store
    let store = MemoryStore::new();
    HttpServer::new(move ||{
        App::new()
            .wrap(
                RateLimiter::new(
                MemoryStoreActor::from(store.clone()).start())
                    .with_interval(Duration::from_secs(60))
                    .with_max_requests(100)
                    .with_identifier(|req| {
                        let key = req.headers().get("x-api-key").unwrap();
                        let key = key.to_str().unwrap();
                        Ok(key.to_string())
                    })
            )
            .route("/", web::get().to(greet))
            .route("/{name}", web::get().to(greet))
    })
    .bind("127.0.0.1:8000")?
    .run()
    .await
}
  • The memcache store uses a separate key to keep track of expiry since there's no way to get ttl of keys in memcache natively yet. This means memcache store will use double the number of keys as compared to redis store. If there's any better way to do this, please considering opening an issue!

  • It is important to initialize store before creating HttpServer instance, or else a store will be created for each web worker. This may lead to instability and inconsistency! For example, initializing your app in the following manner would create more than one stores:

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(move ||{
        App::new()
            .wrap(
                RateLimiter::new(
                MemoryStoreActor::from(MemoryStore::new()).start())
                    .with_interval(Duration::from_secs(60))
                    .with_max_requests(100)
            )
            .route("/", web::get().to(greet))
            .route("/{name}", web::get().to(greet))
    })
    .bind("127.0.0.1:8000")?
    .run()
    .await
}
  • To enable ratelimiting across multiple instances of your web application(multiple http servers behind load balancer), consider using a feature called session stickiness supported by popular cloud services such as AWS, Azure, etc.

Status

This project has not reached v1.0, so some instability and breaking changes are to be expected till then.

You can use the issue tracker in case you encounter any problems.

LICENSE

This project is licensed under MIT license.

License: MIT

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].