Rate limit on websocket connections #35
-
Hi, I am trying to get this to work with a react frontend and django backend. The django backend is configured ASGI and I want to apply this to requests to a websocket. I attached my configuration setup. A user called owlboots is attempting a DDoS attack. So, I put my application on maintenance mode and I banned his account but this hasn't stopped him. So I want to implement a rate limit on his ip address. The issue is once I deploy my code to production it isn't rate limiting, I also tried to limit myself by making many requests within a minute but it doesn't work. Any help is appreciated! All the best, |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 2 replies
-
https://github.com/abersheeran/asgi-ratelimit/blob/master/ratelimit/core.py#L50-L51 Currently, WebSocket rate limiting is not supported, because the ASGI protocol does not allow custom HTTP to be returned for WebSocket. |
Beta Was this translation helpful? Give feedback.
-
You can custom RateLimitMiddleware to deal websocket. class WSRateLimitMiddlware(RateLimitMiddleware):
async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
if scope["type"] == "lifespan":
return await self.app(scope, recevie, send)
url_path = scope["path"]
for pattern, rules in self.config.items():
if pattern.match(url_path):
# After finding the first rule that can match the path,
# calculate the user ID and group
try:
user, group = await self.authenticate(scope)
except Exception as exc:
if self.on_auth_error is not None:
reponse = await self.on_auth_error(exc)
return await reponse(scope, receive, send)
raise exc
# Select the first rule that can be matched
_rules = [rule for rule in rules if group == rule.group]
if _rules:
rule = _rules[0]
break
else: # If no rule can match, run `self.app` and return
return await self.app(scope, receive, send)
if not [name for name in RULENAMES if getattr(rule, name) is not None]:
return await self.app(scope, receive, send)
if rule.zone is None:
retry_after = await self.backend.retry_after(url_path, user, rule)
else:
retry_after = await self.backend.retry_after(rule.zone, user, rule)
if retry_after == 0:
return await self.app(scope, receive, send)
if scope["type"] == "websocket":
# Close this websocket
elif scope["type"] == "http":
# HTTP 429 |
Beta Was this translation helpful? Give feedback.
https://github.com/abersheeran/asgi-ratelimit/blob/master/ratelimit/core.py#L50-L51
Currently, WebSocket rate limiting is not supported, because the ASGI protocol does not allow custom HTTP to be returned for WebSocket.