Crate warp_rate_limit

Crate warp_rate_limit 

Source
Expand description

This crate provides RFC 6585 compliant in-memory rate limiting with configurable windows and limits as lightweight middleware for Warp web applications.

It provides a Filter you add to your routes that exposes rate-limiting information to your handlers, and a Rejection Type for error recovery.

It does not yet provide persistence, nor is the HashMap that stores IPs bounded. Both of these may be changed in a future version.

§Quickstart

  1. Include the crate:

cargo add warp-rate-limit

  1. Define one or more rate limit configurations. Following are some examples of available builder methods. The variable names are arbitrary:
// Limit: 60 requests per 60 Earth seconds
let public_routes_rate_limit = RateLimitConfig::default();
 
// Limit: 100 requests per 60 Earth seconds
let parter_routes_rate_limit = RateLimitConfig::max_per_minute(100);
 
// Limit: 10 requests per 20 Earth seconds
let static_route_limit = RateLimitConfig::max_per_window(10,20);
  1. Use rate limiting information in request handler. If you don’t want to use rate-limiting information related to the IP address associated with this request, you can skip this part.
// Example route handler
async fn hande_request(rate_limit_info: RateLimitInfo) -> Result<impl Reply, Rejection> {
    // Create a base response
    let mut response = warp::reply::with_status(
        "Hello world", 
        StatusCode::OK
    ).into_response();
 
    // Optionally add rate limit headers to your response.
    if let Err(e) = add_rate_limit_headers(response.headers_mut(), &rate_limit_info) {
        match e {
            RateLimitError::HeaderError(e) => {
                eprintln!("Failed to set rate limit headers due to invalid value: {}", e);
            }
            RateLimitError::Other(e) => {
                eprintln!("Unexpected error setting rate limit headers: {}", e);
            }
        }
    } 
 
    // You could also replace the above `if let Err(e)` block with:
    // let _ = add_rate_limit_headers(response.headers_mut(), &rate_limit_info);
 
    Ok(response)
}
  1. Handle rate limit errors in your rejection handler:
// Example rejection handler
async fn handle_rejection(rejection: Rejection) -> Result<impl Reply, Infallible> {
    // Somewhere in your rejection handling:
    if let Some(rate_limit_rejection) = rejection.find::<RateLimitRejection>() {
        // We have a rate limit rejection -- so let's get some info about it: 
        let info = get_rate_limit_info(rate_limit_rejection);
 
        // Let's use that info to create a response:
        let message = format!(
            "Rate limit exceeded. Try again after {}.", 
            info.retry_after
        );
 
        // Let's build that response:
        let mut response = warp::reply::with_status(
            message,
            StatusCode::TOO_MANY_REQUESTS
        ).into_response();
 
        // Then, let's add the rate-limiting headers to that response:
        if let Err(e) = add_rate_limit_headers(response.headers_mut(), &info) {
            // Whether or not you use the specific RateLimitError in 
            // your handler, consider handling errors explicitly here. 
            // Again, though, you're free to `if let _ = add_rate_limit_headers(...` 
            // if you don't care about these errors.
            match e {
                RateLimitError::HeaderError(e) => {
                    eprintln!("Failed to set rate limit headers due to invalid value: {}", e);
                }
                RateLimitError::Other(e) => {
                    eprintln!("Unexpected error setting rate limit headers: {}", e);
                }
            }
        }
 
        Ok(response)    
    } else {
        // Handle other types of rejections, e.g.
        Ok(warp::reply::with_status(
            "Internal Server Error",
            StatusCode::INTERNAL_SERVER_ERROR,
        ).into_response())
    }
} 

Re-exports§

pub use chrono;
pub use serde;

Structs§

RateLimitConfig
Configuration for the rate limiter
RateLimitInfo
Information about the current rate limit status
RateLimitRejection
Custom rejection type for rate limiting

Enums§

RateLimitError
Errors that can occur during rate limiting logic
RetryAfterFormat
Format options for the Retry-After header

Functions§

add_rate_limit_headers
Adds rate limit headers to a response
get_rate_limit_info
Gets rate limit information from a rejection
with_rate_limit
Creates a rate limiting filter with the given configuration