Ejemplo n.º 1
0
    def _check_within_range(
            self,
            key: str,
            count_func: Callable[[], int],
            trim_func: Optional[Callable[[str, int], None]] = None) -> None:
        user_id = int(key.split(':')[1])
        try:
            user = get_user_profile_by_id(user_id)
        except Exception:
            user = None
        entity = RateLimitedUser(user)
        max_calls = max_api_calls(entity)

        age = int(client.ttl(key))
        if age < 0:
            logging.error("Found key with age of %s, will never expire: %s" % (
                age,
                key,
            ))

        count = count_func()
        if count > max_calls:
            logging.error("Redis health check found key with more elements \
than max_api_calls! (trying to trim) %s %s" % (key, count))
            if trim_func is not None:
                client.expire(key, max_api_window(entity))
                trim_func(key, max_calls)
Ejemplo n.º 2
0
    def process_response(self, request, response):
        if not settings.RATE_LIMITING:
            return response

        from zerver.lib.rate_limiter import max_api_calls
        # Add X-RateLimit-*** headers
        if hasattr(request, '_ratelimit_applied_limits'):
            response['X-RateLimit-Limit'] = max_api_calls(request.user)
            if hasattr(request, '_ratelimit_secs_to_freedom'):
                response['X-RateLimit-Reset'] = int(time.time() + request._ratelimit_secs_to_freedom)
            if hasattr(request, '_ratelimit_remaining'):
                response['X-RateLimit-Remaining'] = request._ratelimit_remaining
        return response
Ejemplo n.º 3
0
    def process_response(self, request, response):
        if not settings.RATE_LIMITING:
            return response

        from zerver.lib.rate_limiter import max_api_calls
        # Add X-RateLimit-*** headers
        if hasattr(request, '_ratelimit_applied_limits'):
            response['X-RateLimit-Limit'] = max_api_calls(request.user)
            if hasattr(request, '_ratelimit_secs_to_freedom'):
                response['X-RateLimit-Reset'] = int(time.time() + request._ratelimit_secs_to_freedom)
            if hasattr(request, '_ratelimit_remaining'):
                response['X-RateLimit-Remaining'] = request._ratelimit_remaining
        return response
Ejemplo n.º 4
0
    def process_response(self, request: HttpRequest, response: HttpResponse) -> HttpResponse:
        if not settings.RATE_LIMITING:
            return response

        from zerver.lib.rate_limiter import max_api_calls, RateLimitedUser
        # Add X-RateLimit-*** headers
        if hasattr(request, '_ratelimit_applied_limits'):
            entity = RateLimitedUser(request.user)
            response['X-RateLimit-Limit'] = str(max_api_calls(entity))
            if hasattr(request, '_ratelimit_secs_to_freedom'):
                response['X-RateLimit-Reset'] = str(int(time.time() + request._ratelimit_secs_to_freedom))
            if hasattr(request, '_ratelimit_remaining'):
                response['X-RateLimit-Remaining'] = str(request._ratelimit_remaining)
        return response
Ejemplo n.º 5
0
    def process_response(self, request: HttpRequest, response: HttpResponse) -> HttpResponse:
        if not settings.RATE_LIMITING:
            return response

        from zerver.lib.rate_limiter import max_api_calls, RateLimitedUser
        # Add X-RateLimit-*** headers
        if hasattr(request, '_ratelimit_applied_limits'):
            entity = RateLimitedUser(request.user)
            response['X-RateLimit-Limit'] = str(max_api_calls(entity))
            if hasattr(request, '_ratelimit_secs_to_freedom'):
                response['X-RateLimit-Reset'] = str(int(time.time() + request._ratelimit_secs_to_freedom))
            if hasattr(request, '_ratelimit_remaining'):
                response['X-RateLimit-Remaining'] = str(request._ratelimit_remaining)
        return response
Ejemplo n.º 6
0
    def process_response(self, request: HttpRequest, response: HttpResponse) -> HttpResponse:
        if not settings.RATE_LIMITING:
            return response

        from zerver.lib.rate_limiter import max_api_calls, RateLimitedUser
        # Add X-RateLimit-*** headers
        if hasattr(request, '_ratelimit'):
            # Right now, the only kind of limiting requests is user-based.
            ratelimit_user_results = request._ratelimit['RateLimitedUser']
            entity = RateLimitedUser(request.user)
            response['X-RateLimit-Limit'] = str(max_api_calls(entity))
            response['X-RateLimit-Reset'] = str(int(time.time() + ratelimit_user_results['secs_to_freedom']))
            if 'remaining' in ratelimit_user_results:
                response['X-RateLimit-Remaining'] = str(ratelimit_user_results['remaining'])
        return response
Ejemplo n.º 7
0
    def set_response_headers(self, response: HttpResponse,
                             rate_limit_results: List[RateLimitResult]) -> None:
        # The limit on the action that was requested is the minimum of the limits that get applied:
        limit = min([max_api_calls(result.entity) for result in rate_limit_results])
        response['X-RateLimit-Limit'] = str(limit)
        # Same principle applies to remaining api calls:
        if all(result.remaining for result in rate_limit_results):
            remaining_api_calls = min([result.remaining for result in rate_limit_results])
            response['X-RateLimit-Remaining'] = str(remaining_api_calls)
        else:
            response['X-RateLimit-Remaining'] = str(0)

        # The full reset time is the maximum of the reset times for the limits that get applied:
        reset_time = time.time() + max([result.secs_to_freedom for result in rate_limit_results])
        response['X-RateLimit-Reset'] = str(int(reset_time))
Ejemplo n.º 8
0
    def _check_within_range(self, key: str, count_func: Callable[[], int],
                            trim_func: Optional[Callable[[str, int], None]]=None) -> None:
        user_id = int(key.split(':')[1])
        user = get_user_profile_by_id(user_id)
        entity = RateLimitedUser(user)
        max_calls = max_api_calls(entity)

        age = int(client.ttl(key))
        if age < 0:
            logging.error("Found key with age of %s, will never expire: %s" % (age, key,))

        count = count_func()
        if count > max_calls:
            logging.error("Redis health check found key with more elements \
than max_api_calls! (trying to trim) %s %s" % (key, count))
            if trim_func is not None:
                client.expire(key, max_api_window(entity))
                trim_func(key, max_calls)
Ejemplo n.º 9
0
    def _check_within_range(self, key, count_func, trim_func=None):
        user_id = int(key.split(':')[1])
        try:
            user = get_user_profile_by_id(user_id)
        except:
            user = None
        max_calls = max_api_calls(user=user)

        age = int(client.ttl(key))
        if age < 0:
            logging.error("Found key with age of %s, will never expire: %s" % (age, key,))

        count = count_func()
        if count > max_calls:
            logging.error("Redis health check found key with more elements \
than max_api_calls! (trying to trim) %s %s" % (key, count))
            if trim_func is not None:
                client.expire(key, max_api_window(user=user))
                trim_func(key, max_calls)
Ejemplo n.º 10
0
    def _check_within_range(self, key, count_func, trim_func):
        user_id = int(key.split(':')[1])
        try:
            user = get_user_profile_by_id(user_id)
        except:
            user = None
        max_calls = max_api_calls(user=user)

        age = int(client.ttl(key))
        if age < 0:
            logging.error("Found key with age of %s, will never expire: %s" % (age, key,))

        count = count_func()
        if count > max_calls:
            logging.error("Redis health check found key with more elements \
than max_api_calls! (trying to trim) %s %s" % (key, count))
            if self.trim:
                client.expire(key, max_api_window(user=user))
                trim_func(key, max_calls)
Ejemplo n.º 11
0
    def _check_within_range(self, key, count_func, trim_func=None):
        # type: ignore # mypy #1567 should be (str, Callable[[], int], Optional[Callable[[str, int], None]]) -> None
        user_id = int(key.split(':')[1])
        try:
            user = get_user_profile_by_id(user_id)
        except:
            user = None
        max_calls = max_api_calls(user=user)

        age = int(client.ttl(key))
        if age < 0:
            logging.error("Found key with age of %s, will never expire: %s" % (
                age,
                key,
            ))

        count = count_func()
        if count > max_calls:
            logging.error("Redis health check found key with more elements \
than max_api_calls! (trying to trim) %s %s" % (key, count))
            if trim_func is not None:
                client.expire(key, max_api_window(user=user))
                trim_func(key, max_calls)