feat: rate limiting parity — sliding window, keys, THROTTLE (#10)#28
Merged
Conversation
Refactors rate limiting into a rule on the engine, closing the parity gap with @webdecoy/node's RateLimitRule. - WebDecoy_Rate_Limit_Rule implements the SDK RuleInterface, so it evaluates in order with tripwires/filters (added last, so a deterministic DENY wins over a THROTTLE). Over-limit now returns a proper 429 + Retry-After + X-RateLimit-Limit/Remaining/Reset headers — previously an exceeded limit only added +25 to the bot score. - Sliding window: the classic two-bucket weighted approximation in a persistent object cache (Redis/Memcached) when present, transparently falling back to the fixed-window DB counter otherwise. - keyBy: IP (default), IP+route, or logged-in user id (WP-specific; anon falls back to IP). Composite keys are hashed to fit the DB column. - Per-rule limit/window/algorithm/key/dry-run in Protection settings; the existing global limit becomes the default rule, so effective limits are unchanged for existing installs. Increment-then-check matches node. - Removed the standalone pre-engine rate-limit block and the now-dead handle_rate_limit_exceeded(). - Fixed a latent constructor bug (absent config key re-read the undefined key instead of the default). Verified fixed + sliding admit/deny, per-IP/per-user independence, dry-run, header metadata, and sliding->fixed fallback with a stubbed harness. Closes #10. Part of #16. Co-authored-by: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes the last rate-limiting parity gap with
@webdecoy/node: rate limiting is now a rule on the engine producing a proper THROTTLE, not a side-channel that merely nudged the bot score.What changed
WebDecoy_Rate_Limit_Ruleimplements the SDKRuleInterface, so it evaluates in order alongside tripwires and filters — added last, so a deterministic tripwire/filter DENY wins over a THROTTLE for the same request.429+Retry-After+X-RateLimit-Limit/Remaining/Reset. Previously an exceeded limit just added +25 to the score.prev·overlap + curr) in a persistent object cache (Redis/Memcached) when one is present, transparently falling back to the fixed-window DB counter otherwise. Most serious WP hosts run a persistent cache, giving shared cross-process state node's in-memory limiter can't keep across restarts.Cleanup
Removed the standalone pre-engine rate-limit block and the now-dead
handle_rate_limit_exceeded(). Also fixed a latent constructor bug where an absent config key re-read the undefined key instead of its default.Tests
Stubbed
$wpdb+ object-cache harness: fixed and sliding admit/deny at the boundary, per-IP and per-user independence, dry-run returns ALLOW while recording, header metadata on throttle, and the sliding→fixed fallback when no persistent cache is present (16 checks). SDK suite still green (41).Closes #10. Part of #16.