Skip to content

Add Retry-After header support for rate-limited responses#423

Open
PopoviciMarian wants to merge 2 commits into
mainfrom
feature/rate-limiting-retry-after-header
Open

Add Retry-After header support for rate-limited responses#423
PopoviciMarian wants to merge 2 commits into
mainfrom
feature/rate-limiting-retry-after-header

Conversation

@PopoviciMarian
Copy link
Copy Markdown
Contributor

@PopoviciMarian PopoviciMarian commented May 14, 2026

Add Retry-After header support for rate-limited responses

Expose retryAfterSeconds through the full stack (proto → agent → request processor → PHP extension) so rate-limited responses can include a Retry-After header that counts down toward window expiry.

  • Add retry_after_seconds field to RateLimitingStatus proto message
  • Compute remaining window time from SlidingWindow.CreatedAt in the agent
  • Pass retryAfterSeconds through the action JSON to the PHP extension
  • Expose retry_after_seconds on AikidoBlockRequestStatus PHP class
  • Add server test validating the header decreases over time
  • Update middleware docs (no-framework, Laravel, Symfony) with examples

Summary by Aikido

Security Issues: 0 🔍 Quality Issues: 1 Resolved Issues: 0

🚀 New Features

  • Implemented end-to-end Retry-After header support, updated docs and tests

⚡ Enhancements

  • Propagated retryAfterSeconds through agent, request processor, and PHP

🐛 Bugfixes

  • Fixed sliding window CreatedAt handling and adjusted window timing

More info

Comment thread lib/agent/grpc/request.go
1. Sets up rate limiting config to 3 requests / 5 minutes for route '/'.
2. Sends 3 requests to '/'. Checks that those requests are not blocked.
3. Sends a rate-limited request and captures the Retry-After value.
4. Sleeps 60 seconds, sends another rate-limited request, and asserts
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

time.sleep(5)? :D

if sw.Total >= dropped { // safety check to avoid negative total
sw.Total -= dropped
}
sw.CreatedAt = sw.CreatedAt.Add(time.Minute)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add comment why we do this?

Comment thread lib/agent/grpc/request.go
}
elapsed := int32(time.Since(sw.CreatedAt).Seconds())
retryAfter := windowSizeInSeconds - elapsed
if retryAfter < 1 {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add comment why?

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

Successfully merging this pull request may close these issues.

2 participants