Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rate Limit Layer not Respected #764

Closed
cloud303-cholden opened this issue Mar 6, 2024 · 1 comment
Closed

Rate Limit Layer not Respected #764

cloud303-cholden opened this issue Mar 6, 2024 · 1 comment

Comments

@cloud303-cholden
Copy link

cloud303-cholden commented Mar 6, 2024

Quick note: I created an issue in axum as well as this involves both tower and axum. I can close whichever of the two makes the most sense.

I am running into an issue with using the RateLimitLayer from tower with axum. I noticed that I can keep sending requests and the rate isn't actually limited. Below is a complete example.

[package]
name = "axum-rate-limit-test"
version = "0.1.0"
edition = "2021"

[dependencies]
axum = "0.7.4"
serde = { version = "1.0.193", features = ["derive"] }
serde_json = { version = "1.0.108", features = ["std"] }
tokio = { version = "1.35.0", features = ["full"] }
tower = { version = "0.4.13", features = ["limit", "buffer"] }
use axum::{
    error_handling::HandleErrorLayer,
    http::StatusCode,
    routing::get,
    BoxError,
    Router,
    Json,
};
use serde::Serialize;
use tokio::net::TcpListener;
use tower::ServiceBuilder;

#[derive(Debug, Serialize)]
pub struct Health {
    pub ok: bool,
}

pub async fn health() -> Result<Json<Health>, (StatusCode, String)> {
    Ok(Json(Health { ok: true }))
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let app = Router::new()
        .route("/health", get(health))
        .route_layer(
            ServiceBuilder::new()
                .layer(HandleErrorLayer::new(|err: BoxError| async move {
                    (
                        StatusCode::INTERNAL_SERVER_ERROR,
                        format!("Unhandled error: {}", err),
                    )
                }))
                .buffer(1024)
                .rate_limit(1, tokio::time::Duration::from_secs(5))
        );
    let listener = TcpListener::bind("127.0.0.1:3000")
        .await
        .expect("failed to bind TCP listener");
    axum::serve(listener, app)
        .await
        .expect("failed to serve service");

    Ok(())
}

I expected the request rate to be limited to 1 per 5 seconds. But the below script executes without any rate limiting.

for n in {1..10}; do curl localhost:3000/health; done
@jplatte
Copy link
Contributor

jplatte commented Mar 6, 2024

The problem comes from axum, you can close this one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants