@@ -51,6 +51,10 @@ def __init__(
5151 self .app : ASGIApp = app
5252
5353 self ._ignore_local : bool = ignore_localhost
54+
55+ for limit in global_limits :
56+ limit ["is_global" ] = True
57+
5458 self ._global_limits : list [RateLimitData ] = global_limits
5559
5660 self ._store : Store = Store (redis = redis )
@@ -82,28 +86,35 @@ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
8286 route = r
8387 break
8488
85- route_limits : list [RateLimitData ] = sorted (getattr (route , "limits" , []), key = lambda x : x ["priority" ])
89+ route_limits : list [RateLimitData ] = sorted (getattr (route , "limits" , []), key = lambda x : x .get ("priority" , 0 ))
90+ for data in route_limits :
91+ # Ensure routes are never treated as global limits...
92+ data ["is_global" ] = False
8693
8794 for limit in self ._global_limits + route_limits :
8895 is_exempt : bool = False
89- exempt : ExemptCallable | None = limit [ "exempt" ]
96+ exempt : ExemptCallable | None = limit . get ( "exempt" , None )
9097
9198 if exempt is not None :
9299 is_exempt : bool = await exempt (request )
93100
94101 if is_exempt :
95102 continue
96103
97- bucket : BucketType = limit [ "bucket" ]
104+ bucket : BucketType = limit . get ( "bucket" , "ip" )
98105 if bucket == "ip" :
99106 if not request .client and not forwarded :
100107 logger .warning ("Could not determine the IP address while ratelimiting! Ignoring..." )
101108 return await self .app (scope , receive , send )
102109
103110 # forwarded or client.host will exist at this point...
104- key : str = forwarded .split ("," )[0 ] if forwarded else request .client .host # type: ignore
111+ ip : str = forwarded .split ("," )[0 ] if forwarded else request .client .host # type: ignore
112+ if not limit .get ("is_global" , False ) and route :
113+ key = f"{ route .name } @{ route .path } ::{ limit ['rate' ]} .{ limit ['per' ]} .ip"
114+ else :
115+ key = ip
105116
106- if self ._ignore_local and key in ("127.0.0.1" , "::1" , "localhost" , "0.0.0.0" ):
117+ if self ._ignore_local and ip in ("127.0.0.1" , "::1" , "localhost" , "0.0.0.0" ):
107118 return await self .app (scope , receive , send )
108119 else :
109120 key : str | None = await bucket (request )
0 commit comments