diff --git a/src/middleware/route-ratelimit.js b/src/middleware/route-ratelimit.js index a521e21..3bb7cc8 100644 --- a/src/middleware/route-ratelimit.js +++ b/src/middleware/route-ratelimit.js @@ -15,7 +15,7 @@ const RateLimit = require("express-rate-limit") // Set max requests per minute const maxRequests = process.env.RATE_LIMIT_MAX_REQUESTS ? parseInt(process.env.RATE_LIMIT_MAX_REQUESTS) - : 60 + : 6 // Pro-tier rate limits are 10x the freemium limits. const PRO_RPM = 10 * maxRequests @@ -33,6 +33,8 @@ const routeRateLimit = function(req, res, next) { // Current route const rateLimitTier = req.locals.proLimit ? "PRO" : "BASIC" const path = req.baseUrl + req.path + + // Create a unique string as a route identifier. const route = rateLimitTier + req.method + @@ -40,6 +42,7 @@ const routeRateLimit = function(req, res, next) { .split("/") .slice(0, 4) .join("/") + //console.log(`route identifier: ${JSON.stringify(route, null, 2)}`) // This boolean value is passed from the auth.js middleware. const proRateLimits = req.locals.proLimit @@ -89,6 +92,8 @@ const routeRateLimit = function(req, res, next) { } } + //console.log(`calling uniqueRateLimits() on this route: ${route}`) + // Call rate limit for this route uniqueRateLimits[route](req, res, next) } diff --git a/test/v3/integration/rate-limits.js b/test/v3/integration/rate-limits.js index b61c25e..8540797 100644 --- a/test/v3/integration/rate-limits.js +++ b/test/v3/integration/rate-limits.js @@ -11,7 +11,7 @@ const axios = require("axios") const util = require("util") util.inspect.defaultOptions = { depth: 1 } -const SERVER = `https://rest.btctest.net/v2/` +const SERVER = `http://192.168.0.36:12400/v3/` //const SERVER = `http://localhost:3000/v2/` describe("#rate limits", () => { diff --git a/test/v3/mocks/express-mocks.js b/test/v3/mocks/express-mocks.js index fcb545f..f9202e6 100644 --- a/test/v3/mocks/express-mocks.js +++ b/test/v3/mocks/express-mocks.js @@ -79,6 +79,8 @@ const mockRes = { format: sinon.stub().returns({}) } +// Dev-Note on Rate Limits: Since next() is mocked, I can call the Sinon untility +// functions on it, like called(), to see if this stub was called. const mockNext = sinon.stub().returns() module.exports = { diff --git a/test/v3/rate-limits.js b/test/v3/rate-limits.js index 56df9db..66fd57e 100644 --- a/test/v3/rate-limits.js +++ b/test/v3/rate-limits.js @@ -12,7 +12,7 @@ util.inspect.defaultOptions = { depth: 1 } const { mockReq, mockRes, mockNext } = require("./mocks/express-mocks") // Libraries under test -const rateLimitMiddleware = require("../../src/middleware/route-ratelimit") +let rateLimitMiddleware = require("../../src/middleware/route-ratelimit") const controlRoute = require("../../src/routes/v3/control") let req, res, next @@ -43,26 +43,28 @@ describe("#route-ratelimits", () => { }) describe("#routeRateLimit", () => { - const routeRateLimit = rateLimitMiddleware.routeRateLimit + let routeRateLimit = rateLimitMiddleware.routeRateLimit const getInfo = controlRoute.testableComponents.getInfo - /* + it("should pass through rate-limit middleware", async () => { - req.baseUrl = "/v2" - req.path = "/control/getInfo" + req.baseUrl = "/v3" + req.path = "/control/getNetworkInfo" req.method = "GET" + // Call the route twice to trigger the rate handling. + await routeRateLimit(req, res, next) await routeRateLimit(req, res, next) // next() will be called if rate-limit is not triggered assert.equal(next.called, true) }) - it("should trigger rate-limit handler if rate limits exceeds 60 request per minute", async () => { - req.baseUrl = "/v2" - req.path = "/control/getInfo" + it("should trigger rate-limit handler if rate limits exceeds 15 request per minute", async () => { + req.baseUrl = "/v3" + req.path = "/control/getNetworkInfo" req.method = "GET" - for (let i = 0; i < 65; i++) { + for (let i = 0; i < 15; i++) { next.reset() // reset the stubbed next() function. await routeRateLimit(req, res, next) @@ -76,18 +78,17 @@ describe("#route-ratelimits", () => { `next should not be called if rate limit was triggered.` ) }) - */ - /* - it("should NOT trigger rate-limit handler for pro-tier at 65 RPM", async () => { + + it("should NOT trigger rate-limit handler for pro-tier at 20 RPM", async () => { // Clear the require cache before running this test. delete require.cache[ - require.resolve("../../dist/middleware/route-ratelimit") + require.resolve("../../src/middleware/route-ratelimit") ] - rateLimitMiddleware = require("../../dist/middleware/route-ratelimit") + rateLimitMiddleware = require("../../src/middleware/route-ratelimit") routeRateLimit = rateLimitMiddleware.routeRateLimit - req.baseUrl = "/v2" - req.path = "/control/getInfo" + req.baseUrl = "/v3" + req.path = "/control/getNetworkInfo" req.method = "GET" req.locals.proLimit = true @@ -97,7 +98,7 @@ describe("#route-ratelimits", () => { // Prepare the authorization header //req.headers.authorization = generateAuthHeader("BITBOX") - for (let i = 0; i < 65; i++) { + for (let i = 0; i < 20; i++) { next.reset() // reset the stubbed next() function. await routeRateLimit(req, res, next) @@ -117,13 +118,13 @@ describe("#route-ratelimits", () => { it("rate-limiting should still kick in at a higher RPM for pro-tier", async () => { // Clear the require cache before running this test. delete require.cache[ - require.resolve("../../dist/middleware/route-ratelimit") + require.resolve("../../src/middleware/route-ratelimit") ] - rateLimitMiddleware = require("../../dist/middleware/route-ratelimit") + rateLimitMiddleware = require("../../src/middleware/route-ratelimit") routeRateLimit = rateLimitMiddleware.routeRateLimit - req.baseUrl = "/v2" - req.path = "/control/getInfo" + req.baseUrl = "/v3" + req.path = "/control/getNetworkInfo" req.method = "GET" req.locals.proLimit = true @@ -133,7 +134,7 @@ describe("#route-ratelimits", () => { // Prepare the authorization header //req.headers.authorization = generateAuthHeader("BITBOX") - for (let i = 0; i < 650; i++) { + for (let i = 0; i < 100; i++) { next.reset() // reset the stubbed next() function. await routeRateLimit(req, res, next) @@ -149,7 +150,6 @@ describe("#route-ratelimits", () => { `next should NOT be called if rate limit was triggered.` ) }) - */ }) })