Skip to content

Commit

Permalink
renamed property and added test
Browse files Browse the repository at this point in the history
  • Loading branch information
re-kfa committed Aug 18, 2021
1 parent c668c26 commit 23508f7
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 7 deletions.
4 changes: 2 additions & 2 deletions README.md
Expand Up @@ -102,7 +102,7 @@ app.post("/create-account", createAccountLimiter, function(req, res) {

A `req.rateLimit` property is added to all requests with the `limit`, `current`, and `remaining` number of requests and, if the store provides it, a `resetTime` Date object. These may be used in your application code to take additional actions or inform the user of their status.

The property name can be configured with the configuration option `reqRateLimitParam`
The property name can be configured with the configuration option `requestPropertyName`

## Configuration options

Expand Down Expand Up @@ -232,7 +232,7 @@ function (/*req, res*/) {
}
```

### reqRateLimitParam
### requestPropertyName
Parameter to add to `req`-Object.

Defaults to `rateLimit`.
Expand Down
16 changes: 11 additions & 5 deletions lib/express-rate-limit.js
Expand Up @@ -27,7 +27,7 @@ function RateLimit(options) {
res.status(options.statusCode).send(options.message);
},
onLimitReached: function (/*req, res, optionsUsed*/) {},
reqRateLimitParam: "rateLimit", // Parameter name appended to req object
requestPropertyName: "rateLimit", // Parameter name appended to req object
},
options
);
Expand Down Expand Up @@ -75,7 +75,7 @@ function RateLimit(options) {

Promise.resolve(maxResult)
.then((max) => {
req[options.reqRateLimitParam] = {
req[options.requestPropertyName] = {
limit: max,
current: current,
remaining: Math.max(max - current, 0),
Expand All @@ -84,7 +84,10 @@ function RateLimit(options) {

if (options.headers && !res.headersSent) {
res.setHeader("X-RateLimit-Limit", max);
res.setHeader("X-RateLimit-Remaining", req[options.reqRateLimitParam].remaining);
res.setHeader(
"X-RateLimit-Remaining",
req[options.requestPropertyName].remaining
);
if (resetTime instanceof Date) {
// if we have a resetTime, also provide the current date to help avoid issues with incorrect clocks
res.setHeader("Date", new Date().toUTCString());
Expand All @@ -96,7 +99,10 @@ function RateLimit(options) {
}
if (options.draft_polli_ratelimit_headers && !res.headersSent) {
res.setHeader("RateLimit-Limit", max);
res.setHeader("RateLimit-Remaining", req[options.reqRateLimitParam].remaining);
res.setHeader(
"RateLimit-Remaining",
req[options.requestPropertyName].remaining
);
if (resetTime) {
const deltaSeconds = Math.ceil(
(resetTime.getTime() - Date.now()) / 1000
Expand Down Expand Up @@ -176,4 +182,4 @@ function RateLimit(options) {
return rateLimit;
}

module.exports = RateLimit;
module.exports = RateLimit;
45 changes: 45 additions & 0 deletions test/express-rate-limit-test.js
Expand Up @@ -641,4 +641,49 @@ describe("express-rate-limit node module", () => {
await request(app).get("/").expect(429);
assert(errorCaught, "error should have been caught");
});

it("should handle two rate-limiters independtly", async () => {
const limiter = rateLimit({
max: 2,
keyGenerator: function (req, res) {
assert.ok(req);
assert.ok(res);

const key = req.query.key;
assert.ok(key);

return key;
},
requestPropertyName: "rateLimitIp",
handler: function (req, res) {
res.status(429).end("keyLimiter handler executed!");
},
});

const globalLimiter = rateLimit({
max: 5,
keyGenerator: () => {
"global";
},
requestPropertyName: "rateLimitGlobal",
handler: function (req, res) {
res.status(429).end("globalLimiter handler executed!");
},
});

createAppWith([limiter, globalLimiter]);
await request(app).get("/").query({ key: 1 }).expect(200); // keyLimiter[1]: 1, keyLimiter[2]: 0, keyLimiter[3]: 0, global: 1
await request(app).get("/").query({ key: 2 }).expect(200); // keyLimiter[1]: 1, keyLimiter[2]: 1, keyLimiter[3]: 0, global: 2
await request(app).get("/").query({ key: 1 }).expect(200); // keyLimiter[1]: 2, keyLimiter[2]: 1, keyLimiter[3]: 0, global: 3
await request(app).get("/").query({ key: 2 }).expect(200); // keyLimiter[1]: 2, keyLimiter[2]: 2, keyLimiter[3]: 0, global: 4
await request(app)
.get("/")
.query({ key: 1 })
.expect(429, "keyLimiter handler executed!"); // keyLimiter[1]: 3 > 2!
await request(app).get("/").query({ key: 3 }).expect(200); // keyLimiter[1]: 2, keyLimiter[2]: 2, keyLimiter[3]: 1, global: 5
await request(app)
.get("/")
.query({ key: 3 })
.expect(429, "globalLimiter handler executed!"); // keyLimiter[1]: 2, keyLimiter[2]: 2, keyLimiter[3]: 2, global: 6 > 5!
});
});

0 comments on commit 23508f7

Please sign in to comment.