Кратко

  • Код 429 сообщает, что поток, отнесённый сервером к выбранному субъекту, превысил локальный бюджет. Он не означает ошибку синтаксиса и сам по себе не доказывает злоупотребление конкретного человека.
  • Retry-After может подсказать время возвращения, но не резервирует будущую ёмкость. Новая попытка снова зависит от актуальной нагрузки, прав, политики и состояния ресурса.
  • RFC 6585 не определяет ни способ идентификации пользователя, ни алгоритм счёта. Общим стал внешний вердикт, а правильность и справедливость внутреннего учёта остались ответственностью оператора.

Запрос не испортился — изменился его номер в истории

Пусть API разрешает пятьдесят обращений в час для каждой учётной записи. Пятьдесят первое может иметь ту же правильную структуру, тот же адрес и те же действительные полномочия. Причина отказа находится не в его содержимом. Сервер связал его с предыдущими обращениями, и их сумма пересекла установленный предел.

До специального ответа сервис мог вернуть общий клиентский сбой, заставив программу исправлять безошибочный текст. Код 503 мог создать впечатление, что недоступна вся служба, хотя другие клиенты продолжали работать. В апреле 2012 года RFC 6585 зарегистрировал 429 Too Many Requests именно для более точного различия.

Спецификация рекомендует объяснять условие и разрешает поле Retry-After. Затем она прямо отказывается определять, как origin-сервер распознаёт пользователя и считает запросы. Протокол стандартизовал вывод, но не присвоил себе бухгалтерию.

Слово «пользователь» не устанавливает личность

Чтобы ограничить поток, системе нужен ключ группировки. Им может быть аутентифицированная запись, ключ API, cookie сеанса, арендатор, исходный адрес или их сочетание. Упомянутые в RFC полномочия и cookie — примеры, а не доказательство одного физического лица.

IP-адрес виден рано и дёшево, но за CGNAT, корпоративным выходом или приватным реле он объединяет множество независимых людей. Всплеск одного участника расходует запас всех. Ответ 429 может быть верен для адресного счётчика, но не доказывает, что каждый отклонённый человек исчерпал личную норму.

Аутентифицированная запись лучше совпадает с договором, однако может обслуживать несколько устройств, процессов или сотрудников. Ключи передают и похищают. Cookie доказывает продолжение сеанса, а не гражданскую идентичность. Каждая улика поддерживает лишь ограниченный вывод.

Сервер вправе сказать: «этот вычисленный субъект достиг лимита». Он не вправе превращать это в нравственное обвинение человеку, которого счётчик не установил.

За одним статусом скрываются разные области

RFC 6585 допускает подсчёт на один ресурс, на весь сервер или на группу серверов. Отдельный предел защищает дорогой поиск и оставляет настройки доступными. Общий предел бережёт совместную мощность, но может оценить лёгкую проверку так же, как тяжёлый отчёт.

Лимит арендатора способен отражать коммерческое распределение, если каждый запрос надёжно связан с договором. Межрегиональный счётчик хранит общий остаток, зато требует решения при задержке репликации, разделении сети и отказе хранилища состояния.

Даже момент расходования единицы выбирает оператор. Считать при поступлении, после аутентификации, при допуске или по окончании? Берёт ли перенаправление ещё одну единицу? Остаётся ли отменённый поток HTTP/2 в балансе? Кто платит за повтор посредника? HTTP не знает локального исполнения и потому не может дать один ответ.

Неточный счётчик способен выпускать идеально оформленные 429. Соответствие протоколу не является аудитом учёта.

Ожидание не покупает место

RFC 9110 разрешает записать Retry-After как HTTP-дату или неотрицательное число секунд после получения. RFC 6585 позволяет приложить поле к 429, но не требует его.

Обе формы сообщают, когда не следует возвращаться слишком рано. Они не дают брони. Абсолютная дата нуждается в пригодном общем времени; задержка отсчитывается локально. Ни одна не мешает тысячам клиентов проснуться на одной границе и создать следующую волну.

К моменту возвращения мощность могут занять другие, правила и права могут измениться, а целевой ресурс — устареть. Клиенту нужны собственные ограничения: конечное число попыток, распределение времени, срок полезности операции и проверка семантики метода.

Неидемпотентное действие не становится безопасным после окончания таймера. При транспортной неопределённости время не доказывает, произвела ли прежняя попытка эффект.

429 и 503 называют разные центры отказа

По RFC 9110 код 503 означает временную неспособность сервера обработать запрос из-за перегрузки или обслуживания. Код 429 означает избыток обращений для субъекта и окна, выбранных политикой частоты. Оба могут содержать Retry-After, но общее поле не делает причины одинаковыми.

Один арендатор может получать 429, пока остальные продолжают работу. Вся служба может отвечать 503, хотя ни одна запись не исчерпала личный бюджет. Если действуют оба механизма, статус должен описывать то условие, которое действительно остановило запрос.

Представлять общий недостаток мощности ошибкой клиента — переносить ответственность. Представлять локальный предел полным отказом — скрывать доступные пути. Точный код нужен, чтобы точно указать место решения.

Отказ тоже расходует защищаемый ресурс

В разделе безопасности RFC 6585 предупреждает: отвечать 429 на каждое сообщение во время атаки или огромного потока от одной стороны само по себе дорого. Сервер не обязан всегда использовать код; иногда разумнее сбросить соединение или принять иные меры.

До вежливого отказа система может расшифровать и разобрать сообщение, проверить полномочия, обратиться к распределённому счётчику, построить текст и зашифровать ответ. Если дешёвый вход заставляет пройти весь путь, объяснение становится поверхностью атаки.

Раннее отсечение на границе экономит вычисления, но располагает более слабой идентичностью и чаще задевает общие адреса. Чем меньше доказательств доступно раннему узлу, тем уже и обратимее должно быть его действие.

Кэш не должен продлевать приговор

RFC 6585 запрещает хранить ответы 429. Решение связано с субъектом, окном, областью и текущим счётчиком. Повтор из кэша может продолжить уже закончившийся отказ или перенести долг одного контекста на другой.

Посредник, владеющий собственной политикой мощности, может создать свежий 429 из собственного состояния. Он не может считать старый отказ повторно используемым содержимым. Вердикт остаётся рядом с системой, которая видит текущий остаток.

Узкая истина трёх цифр

429 не аутентифицирует, не доказывает умысел, не гарантирует равенство и не обещает будущий успех. Он также не заставляет атакуемый сервер тратить ресурсы на объяснение каждой потери.

Его польза скромнее: отделить частотную политику от неверного содержимого и общего простоя. Клиент понимает, что мгновенное повторение вряд ли поможет; сервер при наличии запаса может сообщить честный путь возврата.

HTTP не изобрёл квоту. Он дал локальному распределению общий голос и не позволил этому голосу стать доказательством того, чего внутренний счётчик не знает.

Источники