Код состояния HTTP 431, также известный как “Поля заголовка запроса слишком большие”, является ошибкой на стороне клиента, которая указывает на то, что сервер отказывается обрабатывать запрос, потому что его поля заголовка слишком велики. Эта ошибка может быть вызвана либо общим размером заголовков, либо превышением допустимого размера одного поля заголовка.
Код состояния HTTP 431 был впервые введен в RFC 6585, опубликованном в апреле 2012 года. Это было частью усилий по стандартизации дополнительных ответов для HTTP/1.1, решая проблемы, которые не были охвачены существующими кодами состояния на тот момент. Введение этого конкретного кода ошибки было crucial для повышения безопасности сервера и предотвращения вредоносных атак, таких как атаки переполнения буфера, которые могли бы использовать большие заголовки.
Понимание ошибки HTTP 431
Когда возникает ошибка 431, это означает, что сервер заблокировал запрос клиента из-за чрезмерно больших полей заголовка. Каждый сервер имеет свои собственные политики относительно максимального допустимого размера полей заголовка HTTP, что помогает защитить от атак типа отказа в обслуживании.
Общие симптомы ошибок HTTP 431
- Общий размер заголовков запроса слишком велик: Эта ошибка возникает, когда совокупный размер всех заголовков запроса превышает лимит.
- Размер отдельных полей заголовка слишком велик: В этом случае одно поле заголовка слишком велико для обработки, что приводит к ошибке 431.
Общие причины ошибок HTTP 431
- Слишком много cookies: Наличие чрезмерно больших или многочисленных cookies может вызвать ошибку 431. Это может произойти, если одни и те же cookies устанавливаются многократно или если несколько cookies объединяются в одном запросе или ответе. Один из распространенных сценариев — повторное использование одного и того же порта
localhost
в нескольких проектах и отправка всех cookies этих проектов вместе с запросом. - Неправильное кэширование полей заголовков: Неправильное кэширование больших заголовков может привести к ошибке 431. Неправильное кэширование может увеличить размер заголовка, вызывая переполнение буфера.
- Необязательные или неправильно отформатированные заголовки запроса: Чрезмерное использование HTTP-заголовков может привести к запросам, превышающим лимиты размера, установленные сервером, что вызывает ответ 431. Кроме того, убедитесь, что ваши заголовки правильно отформатированы. Слишком длинный URL
Referer
может вызвать ошибку 431.
Как избежать ошибки 431
Очистить Cookies
Регулярно очищайте cookies на стороне клиента (Инструменты разработчика Chrome > Приложение > Cookies) и ограничивайте количество используемых cookies на сервере.
Кэшировать Заголовки
Правильная реализация кэширования заголовков для обеспечения того, чтобы закэшированные заголовки отражали фактический запрос и сжатый ответ. Настройте ETags, если вы сильно полагаетесь на них для условных запросов, так как большие ETags могут способствовать возникновению ошибок.
Минимизация HTTP-заголовков
Упростите ваши HTTP-заголовки, включая только необходимую информацию. Избегайте включения избыточных метаданных, особенно в заголовках, таких как Authorization, Referer и User-Agent.
Сжатие размера заголовков
Иногда вы не отправляете достаточно заголовков, и ваши заголовки раздуты из-за ограничений, которые вне вашего контроля (например, ваш JWT-токен кодирует массу информации). Сжатие заголовков может значительно уменьшить размер ваших запросных заголовков. Используйте протоколы, такие как HTTP/2 и HTTP/3, которые поддерживают сжатие заголовков по умолчанию. Это может автоматически уменьшить размер ваших заголовков без необходимости дополнительной настройки.
Обработка ограничений максимального размера заголовков сервера
Спецификация HTTP не определяет ограничение на размер заголовка; однако многие серверы его имеют. Вот пределы для различных популярных веб-серверов/хостов:
- Apache: 8K
- nginx: 4K-8K
- IIS: 8K-16K
- Tomcat: 8K-48K
- Node: (<13) – 8K; (>13) – 16K
- Cloudflare: 16K на заголовок, 32K всего
Большинство серверов позволяют некоторую форму конфигурации, и разные версии серверного программного обеспечения могут иметь более низкие или более высокие пределы. Вы также должны проверить последнюю документацию, чтобы узнать, включают ли эти пределы другие части запроса (например, cookies) или только регулярные заголовки.
Увеличение предела размера заголовка запроса
Иногда может быть необходимо увеличить предел размера заголовка запроса. Обычно это можно сделать из веб-консоли или CLI для вашего сервера. Если вы разрабатываете локально, обычно есть флаги CLI, которые могут настроить это значение. Вот флаг для настройки пределов размера заголовка запроса в Node JS:
--max-http-header-size=16384
Примечание: Увеличение предела размера заголовка должно выполняться с осторожностью, так как большие заголовки могут потреблять больше памяти и снижать производительность.
Как отправлять ответы с ошибкой HTTP 431
Возможно, вы не хотите полагаться на ваш сервер для определения предела размера заголовка запроса, или, может быть, вы хотите применять собственный предел размера заголовка для каждого конечного пункта API. Следуйте шагам ниже, чтобы узнать, как отправлять свои собственные ошибки 431.
Внедрение пределов размера заголовка запроса в ваш API
Как упоминалось выше, ваша комбинация хоста и сервера, вероятно, автоматически будет применять предел. Чтобы создать свою собственную возможность ограничения размера заголовка запроса в вашем API, вы можете использовать библиотеки, такие как express
в Node.js. Вот пример, иллюстрирующий, как включить ограничения на размеры заголовков запроса:
const express = require("express");
const app = express();
app.get("/", (req, res) => {
const headerSizeInBytes = JSON.stringify(req.headers).length;
const maxHeaderSizeInBytes = 2000; // example limit
if (headerSizeInBytes > maxHeaderSizeInBytes) {
res.status(431).send("Request Header Fields Too Large");
} else {
res.send("Hello World!");
}
});
app.listen(3000, () => {
console.log("Server is running on port 3000");
});
Различие ответов на ошибки между общим размером заголовков запроса и отдельным полем заголовка
При обработке ошибки HTTP 431 убедитесь, что различаете ответы между двумя сценариями:
- Общий размер заголовков запроса слишком велик: Возвращайте ответ, указывающий, что совокупный размер заголовков слишком велик.
- Размер отдельного поля заголовка слишком велик: В этом случае предоставьте ответ об ошибке, который указывает, какое конкретное поле заголовка превышает допустимый размер.
Измените пример из предыдущего раздела для достижения дифференцированных ответов на ошибки:
const express = require("express");
const app = express();
app.get("/", (req, res) => {
const headerSizeInBytes = JSON.stringify(req.headers).length;
const maxHeaderSizeInBytes = 2000; // example limit
const exceededHeaderField = Object.keys(req.headers).find(
(key) => req.headers[key].length > maxHeaderSizeInBytes * 0.1, // example individual field limit
);
if (exceededHeaderField) {
res
.status(431)
.send(
`Size of Individual Header Field '${exceededHeaderField}' Too Large`,
);
} else if (headerSizeInBytes > maxHeaderSizeInBytes) {
res.status(431).send("Total Size of Request Headers Too Large");
} else else {
res.send("Hello World!");
}
});
app.listen(3000, () => {
console.log("Server is running on port 3000");
});
Пример ответа HTTP 431
Мы рекомендуем отвечать вашим пользователям, используя формат ответа API Problem Details.
HTTP/1.1 431 Request Header Fields Too Large
Content-Type: application/problem+json
Content-Language: en
{
"type": "https://httpproblems.com/http-status/431",
"title": "Request Header Fields Too Large",
"detail": "Size of individual header field 'referer' too large",
"instance": "/account/12345/msgs/abc",
"trace": {
"requestId": "4d54e4ee-c003-4d75-aba9-e09a6d707b08"
}
}
Позвольте вашему шлюзу обрабатывать ограничения по размеру заголовков запроса
Если вы используете API-шлюз, вы можете легко добавить политику в ваш конвейер запросов для обработки этого. Вот как это сделать с помощью Zuplo:
Перейдите к вашему маршруту в Дизайнере маршрутов и нажмите Добавить политику в конвейере запросов.
В модальном окне Выбор политики у нас есть два варианта в зависимости от того, что вы хотите сделать.
- Ограничьте весь размер запроса с помощью Политики ограничения размера запроса.
- Используйте Политику ввода пользовательского кода и скопируйте образец кода из вышеуказанного (без частей экспресса) в модуль typescript, который будет подключен к политике.
Заключение
Ошибка HTTP 431 часто вызывается слишком большими заголовками запроса. Вы можете избежать встречи с этой ошибкой, оптимизируя свои заголовки, сжимая их по мере необходимости и внедряя ограничения на размер заголовков запроса в своих API.
Кроме того, внедрение проверок на размер заголовков в вашем API является простым. Большинство серверов уже включают значения по умолчанию, и вы также можете сделать это самостоятельно как на уровне накопительного, так и на уровне индивидуальных заголовков изнутри маршрутов вашего API.
Source:
https://dzone.com/articles/understanding-the-http-431-error