diff --git a/limitador-server/examples/envoy.yaml b/limitador-server/examples/envoy.yaml index 208d3c76..1a7d0eda 100644 --- a/limitador-server/examples/envoy.yaml +++ b/limitador-server/examples/envoy.yaml @@ -28,8 +28,8 @@ static_resources: rate_limits: - stage: 0 actions: - - {request_headers: {header_name: "userid", descriptor_key: "user_id"}} - - { request_headers: { header_name: ":method", descriptor_key: "req_method" } } + - { request_headers: { header_name: "userid", descriptor_key: "user_id" } } + - { request_headers: { header_name: ":method", descriptor_key: "descriptors[0]['method']" } } http_filters: - name: envoy.filters.http.ratelimit typed_config: diff --git a/limitador-server/examples/limits.yaml b/limitador-server/examples/limits.yaml index be60b900..c47aedf4 100644 --- a/limitador-server/examples/limits.yaml +++ b/limitador-server/examples/limits.yaml @@ -10,6 +10,6 @@ max_value: 5 seconds: 60 conditions: - - "req_method == 'POST'" + - "descriptors[0]['req.method'] == 'POST'" variables: - user_id diff --git a/limitador-server/sandbox/README.md b/limitador-server/sandbox/README.md index ca0cd9b9..76614284 100644 --- a/limitador-server/sandbox/README.md +++ b/limitador-server/sandbox/README.md @@ -99,11 +99,11 @@ bin/grpcurl -plaintext -d @ 127.0.0.1:18081 envoy.service.ratelimit.v3.RateLimit { "entries": [ { - "key": "req_method", + "key": "req.method", "value": "POST" }, { - "key": "req_path", + "key": "req.path", "value": "/" } ] @@ -125,11 +125,11 @@ while :; do bin/grpcurl -plaintext -d @ 127.0.0.1:18081 envoy.service.ratelimit. { "entries": [ { - "key": "req_method", + "key": "req.method", "value": "POST" }, { - "key": "req_path", + "key": "req.path", "value": "/" } ] diff --git a/limitador-server/sandbox/envoy.yaml b/limitador-server/sandbox/envoy.yaml index bf5ee863..7e678e10 100644 --- a/limitador-server/sandbox/envoy.yaml +++ b/limitador-server/sandbox/envoy.yaml @@ -27,10 +27,10 @@ static_resources: - actions: - request_headers: header_name: :method - descriptor_key: req_method + descriptor_key: req.method - request_headers: header_name: :path - descriptor_key: req_path + descriptor_key: req.path http_filters: - name: envoy.filters.http.ratelimit typed_config: diff --git a/limitador-server/sandbox/envoy2.yaml b/limitador-server/sandbox/envoy2.yaml index 351ba1d3..d1d15958 100644 --- a/limitador-server/sandbox/envoy2.yaml +++ b/limitador-server/sandbox/envoy2.yaml @@ -27,10 +27,10 @@ static_resources: - actions: - request_headers: header_name: :method - descriptor_key: req_method + descriptor_key: req.method - request_headers: header_name: :path - descriptor_key: req_path + descriptor_key: req.path http_filters: - name: envoy.filters.http.ratelimit typed_config: diff --git a/limitador-server/sandbox/envoy3.yaml b/limitador-server/sandbox/envoy3.yaml index ba557fb0..03180c47 100644 --- a/limitador-server/sandbox/envoy3.yaml +++ b/limitador-server/sandbox/envoy3.yaml @@ -27,10 +27,10 @@ static_resources: - actions: - request_headers: header_name: :method - descriptor_key: req_method + descriptor_key: req.method - request_headers: header_name: :path - descriptor_key: req_path + descriptor_key: req.path http_filters: - name: envoy.filters.http.ratelimit typed_config: diff --git a/limitador-server/sandbox/limits.yaml b/limitador-server/sandbox/limits.yaml index 853c0340..cb354bf2 100644 --- a/limitador-server/sandbox/limits.yaml +++ b/limitador-server/sandbox/limits.yaml @@ -3,20 +3,20 @@ max_value: 10 seconds: 60 conditions: - - "req_method == 'GET'" - - "req_path != '/json'" + - "descriptors[0]['req.method'] == 'GET'" + - "descriptors[0]['req.path'] != '/json'" variables: [] - namespace: test_namespace max_value: 5 seconds: 60 conditions: - - "req_method == 'POST'" - - "req_path != '/json'" + - "descriptors[0]['req.method'] == 'POST'" + - "descriptors[0]['req.path'] != '/json'" variables: [] - namespace: test_namespace max_value: 50000 seconds: 10 conditions: - - "req_method == 'GET'" - - "req_path == '/json'" + - "descriptors[0]['req.method'] == 'GET'" + - "descriptors[0]['req.path'] == '/json'" variables: [] diff --git a/limitador-server/sandbox/load-test.json b/limitador-server/sandbox/load-test.json index 0cd6c81b..b23422cc 100644 --- a/limitador-server/sandbox/load-test.json +++ b/limitador-server/sandbox/load-test.json @@ -5,11 +5,11 @@ { "entries": [ { - "key": "req_method", + "key": "req.method", "value": "GET" }, { - "key": "req_path", + "key": "req.path", "value": "/json" } ] diff --git a/limitador-server/sandbox/redis-otel/README.md b/limitador-server/sandbox/redis-otel/README.md index 1759437a..8b2f10ab 100644 --- a/limitador-server/sandbox/redis-otel/README.md +++ b/limitador-server/sandbox/redis-otel/README.md @@ -24,7 +24,7 @@ bin/grpcurl -plaintext -d @ 127.0.0.1:18081 envoy.service.ratelimit.v3.RateLimit { "entries": [ { - "key": "req_method", + "key": "req.method", "value": "POST" } ] diff --git a/limitador-server/src/envoy_rls/server.rs b/limitador-server/src/envoy_rls/server.rs index b6d24e1b..09923a7e 100644 --- a/limitador-server/src/envoy_rls/server.rs +++ b/limitador-server/src/envoy_rls/server.rs @@ -8,7 +8,7 @@ use tonic::codegen::http::HeaderMap; use tonic::{transport, transport::Server, Request, Response, Status}; use tracing::Span; use tracing_opentelemetry::OpenTelemetrySpanExt; - +use limitador::limit::Context; use crate::envoy_rls::server::envoy::config::core::v3::HeaderValue; use crate::envoy_rls::server::envoy::service::ratelimit::v3::rate_limit_response::Code; use crate::envoy_rls::server::envoy::service::ratelimit::v3::rate_limit_service_server::{ @@ -72,7 +72,7 @@ impl RateLimitService for MyRateLimiter { ) -> Result, Status> { debug!("Request received: {:?}", request); - let mut values: HashMap = HashMap::new(); + let mut values: Vec> = Vec::default(); let (metadata, _ext, req) = request.into_parts(); let namespace = req.domain; let rl_headers = RateLimitRequestHeaders::new(metadata.into_headers()); @@ -96,9 +96,11 @@ impl RateLimitService for MyRateLimiter { let namespace = namespace.into(); for descriptor in &req.descriptors { + let mut map = HashMap::default(); for entry in &descriptor.entries { - values.insert(entry.key.clone(), entry.value.clone()); + map.insert(entry.key.clone(), entry.value.clone()); } + values.push(map); } // "hits_addend" is optional according to the spec, and should default @@ -109,7 +111,8 @@ impl RateLimitService for MyRateLimiter { req.hits_addend }; - let ctx = values.into(); + let mut ctx = Context::default(); + ctx.list_binding("descriptors".to_string(), values); let rate_limited_resp = match &*self.limiter { Limiter::Blocking(limiter) => limiter.check_rate_limited_and_update( @@ -255,8 +258,8 @@ mod tests { namespace, 1, 60, - vec!["req_method == 'GET'".try_into().expect("failed parsing!")], - vec!["app_id".try_into().expect("failed parsing!")], + vec!["descriptors[0]['req.method'] == 'GET'".try_into().expect("failed parsing!")], + vec!["descriptors[0]['app.id']".try_into().expect("failed parsing!")], ); let limiter = RateLimiter::new(10_000); @@ -276,11 +279,11 @@ mod tests { descriptors: vec![RateLimitDescriptor { entries: vec![ Entry { - key: "req_method".to_string(), + key: "req.method".to_string(), value: "GET".to_string(), }, Entry { - key: "app_id".to_string(), + key: "app.id".to_string(), value: "1".to_string(), }, ], @@ -337,7 +340,7 @@ mod tests { domain: "test_namespace".to_string(), descriptors: vec![RateLimitDescriptor { entries: vec![Entry { - key: "req_method".to_string(), + key: "req.method".to_string(), value: "GET".to_string(), }], limit: None, @@ -371,7 +374,7 @@ mod tests { domain: "".to_string(), descriptors: vec![RateLimitDescriptor { entries: vec![Entry { - key: "req_method".to_string(), + key: "req.method".to_string(), value: "GET".to_string(), }], limit: None, diff --git a/limitador-server/src/http_api/server.rs b/limitador-server/src/http_api/server.rs index ed413e53..a72dd57a 100644 --- a/limitador-server/src/http_api/server.rs +++ b/limitador-server/src/http_api/server.rs @@ -382,8 +382,8 @@ mod tests { // Prepare values to check let mut values = HashMap::new(); - values.insert("req_method".into(), "GET".into()); - values.insert("app_id".into(), "1".into()); + values.insert("req.method".into(), "GET".into()); + values.insert("req.id".into(), "1".into()); let info = CheckAndReportInfo { namespace: namespace.into(), values, @@ -433,8 +433,8 @@ mod tests { // Prepare values to check let mut values = HashMap::new(); - values.insert("req_method".into(), "GET".into()); - values.insert("app_id".into(), "1".into()); + values.insert("req.method".into(), "GET".into()); + values.insert("app.id".into(), "1".into()); let info = CheckAndReportInfo { namespace: namespace.into(), values, @@ -508,8 +508,8 @@ mod tests { // Prepare values to check let mut values = HashMap::new(); - values.insert("req_method".into(), "GET".into()); - values.insert("app_id".into(), "1".into()); + values.insert("req.method".into(), "GET".into()); + values.insert("app.id".into(), "1".into()); let info = CheckAndReportInfo { namespace: namespace.into(), values, @@ -551,8 +551,8 @@ mod tests { namespace, max, 60, - vec!["req_method == 'GET'".try_into().expect("failed parsing!")], - vec!["app_id".try_into().expect("failed parsing!")], + vec!["descriptors[0]['req.method'] == 'GET'".try_into().expect("failed parsing!")], + vec!["descriptors[0]['app.id']".try_into().expect("failed parsing!")], ); match &limiter {