Как сервер определяет формат тела HTTP запроса
Что проверяют
Знаете ли вы роль заголовка Content-Type и чем он отличается от Accept. Для тестировщика следом идёт практика: что должен ответить сервер на неверный или пропущенный формат и как это проверить.
Как отвечать
Сервер не угадывает формат по содержимому, он читает заголовок Content-Type запроса и по нему выбирает парсер. Значение состоит из медиатипа и параметров:
application/json: тело в JSON, кодировка UTF-8;application/x-www-form-urlencoded: парыключ=значениечерез&, так отправляет обычная HTML-форма;multipart/form-data; boundary=...: форма с файлами, части разделены строкой изboundary, без неё сервер тело не разберёт;- прочие:
text/plain,application/xml,application/octet-streamдля текста, XML и произвольных байтов.
Рядом работают другие заголовки: Content-Length или Transfer-Encoding: chunked сообщают, где тело кончается, Content-Encoding: gzip говорит, что его нужно распаковать. А Accept относится к ответу: клиент просит нужный формат, и если сервер его не умеет, правильный код 406 Not Acceptable.
Что проверять:
- неподдерживаемый тип: ожидается
415 Unsupported Media Type; - тип верный, тело битое: ожидается
400, а FastAPI при ошибке валидации схемы отдаёт422; - заголовок пропущен: многие фреймворки просто не запускают парсер, и тело оказывается пустым;
- ни в одном случае не 500: падение сервера на кривом вводе это баг.
Где спотыкаются
Отправляют JSON через curl -d без заголовка. По умолчанию curl ставит application/x-www-form-urlencoded, и сервер отвечает ошибкой, которую принимают за баг. Нужен -H 'Content-Type: application/json' или флаг --json в свежих версиях curl.
Путают Content-Type и Accept и заводят баг на формат ответа, проверяя заголовок запроса.
Вручную выставляют Content-Type: multipart/form-data при отправке FormData из браузера или в Postman. Заголовок теряет boundary, и сервер не может разделить части, поэтому его оставляют на клиент.