feat: add rate limiting middleware to Rust backend - #303
Open
Rayyanah0 wants to merge 1 commit into
Open
Conversation
Implements per-IP sliding-window rate limiting as a tower::Layer,
mirroring the existing TS middleware/rateLimiter.ts behaviour.
Changes:
- backend/src/rate_limiter.rs: new RateLimiterLayer / RateLimiterMiddleware
using Arc<Mutex<HashMap>> for per-IP window tracking. Configurable via
RATE_LIMIT_POINTS / RATE_LIMIT_DURATION env vars (default: 60 req/60 s).
Returns 429 with Retry-After header and JSON body {error, retryAfter}.
- backend/src/main.rs: wire RateLimiterLayer onto all routes; fix missing
cancel_invoice import; fix cancel/refund route registrations.
- backend/src/routes/mod.rs: expose the cancel module (was missing).
- backend/Cargo.toml: add tower dependency.
Bug-fixes (pre-existing):
- backend/src/routes/cancel.rs, refund.rs: SorobanClient::new called with
2 args instead of 3 in tests; fix 415/422 assertion to accept either.
- backend/src/routes/pay.rs: same 415/422 assertion fix.
- backend/src/routes/health.rs: fix type mismatch in mock server handler
(Json<Value> vs StatusCode), use into_make_service() for axum::serve.
- backend/src/routes.rs renamed to handlers.rs to resolve module-name
conflict with src/routes/ directory.
Tests (all 14 pass):
- rate_limiter: requests within limit allowed; 3rd request returns 429;
Retry-After header present and > 0; body contains error + retryAfter;
limit resets after window expires; X-Forwarded-For used as IP key.
- routes/health: 200 healthy, 503 degraded.
- routes/pay, cancel, refund: missing body returns 4xx; unreachable RPC
returns 5xx/404/403.
Closes WHEELBACK#198
|
@Rayyanah0 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
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.
Summary
Closes #198
Adds per-IP sliding-window rate limiting to the Rust backend service, matching the shape of the existing TypeScript
middleware/rateLimiter.ts.What changed
New:
backend/src/rate_limiter.rsA hand-rolled
tower::Layer/tower::Serviceimplementation:Arc<Mutex<HashMap<String, Bucket>>>(no extra runtime deps)RATE_LIMIT_POINTS60RATE_LIMIT_DURATION60X-Forwarded-Forheader used as IP key when present (first entry), falls back to socket peer addressRetry-After: <seconds>header{ "error": "Too many requests…", "retryAfter": <seconds> }Modified:
backend/src/main.rsWires the
RateLimiterLayeronto all routes; fixes missingcancel_invoiceimport.Modified:
backend/Cargo.tomlAdds
tower = { version = "0.5", features = ["util"] }.Other fixes (pre-existing bugs unblocked by compilation)
routes/mod.rs:cancelmodule was not declared (compile error)routes/cancel.rs,refund.rs:SorobanClient::newcalled with 2 args instead of 3routes/health.rs: type mismatch in mock server handler;axum::serveusage fixedroutes/pay.rs,cancel.rs,refund.rs: 415 vs 422 assertion made accuratesrc/routes.rsrenamed tosrc/handlers.rsto resolve module-name conflict withsrc/routes/directoryTest output
Request / Response examples
Request within limit — passes through normally
Response:
200 OK(normal route handling)Request beyond limit — 429
Configuration