File tree Expand file tree Collapse file tree 3 files changed +26
-0
lines changed Expand file tree Collapse file tree 3 files changed +26
-0
lines changed Original file line number Diff line number Diff line change @@ -15,6 +15,7 @@ import { withErrorHandler } from "./middleware/error";
15
15
import { withExpress } from "./middleware/express" ;
16
16
import { withRequestLogs } from "./middleware/logs" ;
17
17
import { withOpenApi } from "./middleware/open-api" ;
18
+ import { withRateLimit } from "./middleware/rateLimit" ;
18
19
import { withWebSocket } from "./middleware/websocket" ;
19
20
import { withRoutes } from "./routes" ;
20
21
import { writeOpenApiToFile } from "./utils/openapi" ;
@@ -62,6 +63,7 @@ export const initServer = async () => {
62
63
await withRequestLogs ( server ) ;
63
64
await withErrorHandler ( server ) ;
64
65
await withEnforceEngineMode ( server ) ;
66
+ await withRateLimit ( server ) ;
65
67
await withWebSocket ( server ) ;
66
68
await withAuth ( server ) ;
67
69
await withExpress ( server ) ;
Original file line number Diff line number Diff line change
1
+ import { FastifyInstance } from "fastify" ;
2
+ import { StatusCodes } from "http-status-codes" ;
3
+ import { env } from "../../utils/env" ;
4
+ import { redis } from "../../utils/redis/redis" ;
5
+ import { createCustomError } from "./error" ;
6
+
7
+ export const withRateLimit = async ( server : FastifyInstance ) => {
8
+ server . addHook ( "onRequest" , async ( request , reply ) => {
9
+ const epochTimeInMinutes = Math . floor ( new Date ( ) . getTime ( ) / ( 1000 * 60 ) ) ;
10
+ const key = `rate-limit:global:${ epochTimeInMinutes } ` ;
11
+ const count = await redis . incr ( key ) ;
12
+ redis . expire ( key , 2 * 60 ) ;
13
+
14
+ if ( count > env . GLOBAL_RATE_LIMIT_PER_MIN ) {
15
+ throw createCustomError (
16
+ `Too many requests. Please reduce your calls to ${ env . GLOBAL_RATE_LIMIT_PER_MIN } requests/minute or update the "GLOBAL_RATE_LIMIT_PER_MIN" env var.` ,
17
+ StatusCodes . TOO_MANY_REQUESTS ,
18
+ "TOO_MANY_REQUESTS" ,
19
+ ) ;
20
+ }
21
+ } ) ;
22
+ } ;
Original file line number Diff line number Diff line change @@ -82,6 +82,7 @@ export const env = createEnv({
82
82
ENGINE_MODE : z
83
83
. enum ( [ "default" , "sandbox" , "server_only" , "worker_only" ] )
84
84
. default ( "default" ) ,
85
+ GLOBAL_RATE_LIMIT_PER_MIN : z . coerce . number ( ) . default ( 400 * 60 ) ,
85
86
} ,
86
87
clientPrefix : "NEVER_USED" ,
87
88
client : { } ,
@@ -108,6 +109,7 @@ export const env = createEnv({
108
109
process . env . CONTRACT_SUBSCRIPTIONS_DELAY_SECONDS ,
109
110
REDIS_URL : process . env . REDIS_URL ,
110
111
ENGINE_MODE : process . env . ENGINE_MODE ,
112
+ GLOBAL_RATE_LIMIT_PER_MIN : process . env . GLOBAL_RATE_LIMIT_PER_MIN ,
111
113
} ,
112
114
onValidationError : ( error : ZodError ) => {
113
115
console . error (
You can’t perform that action at this time.
0 commit comments