HTTP из терминала: curl, заголовки, тело и коды ответа

curl помогает разделить сетевое соединение, TLS, HTTP-status, headers и response body. По умолчанию HTTP 404 не делает сам curl неуспешным, поэтому надёжная проверка API должна…

curl помогает разделить сетевое соединение, TLS, HTTP-status, headers и response body. По умолчанию HTTP 404 не делает сам curl неуспешным, поэтому надёжная проверка API должна явно определить, какие уровни считаются ошибкой.

Наблюдаемый GET

Флаг --show-error сохраняет причину при silent-режиме, --location следует redirects, --dump-header отделяет headers, --output сохраняет body.

headers=$(mktemp)
body=$(mktemp)
curl --silent --show-error --location \
  --connect-timeout 5 --max-time 15 \
  --dump-header "$headers" \
  --output "$body" \
  https://example.com/
sed -n '1,12p' "$headers"
wc -c "$body"

Для script добавьте --fail-with-body: HTTP 400+ даст ненулевой status, но тело останется доступно для диагностики. Не печатайте response с токенами в общий CI log.

Метод, headers и JSON

curl --silent --show-error --fail-with-body \
  --request POST \
  --header 'Content-Type: application/json' \
  --data '{"name":"demo"}' \
  https://api.example.test/items

--data выбирает POST и посылает байты как указано; сервер интерпретирует их по Content-Type. Не собирайте JSON конкатенацией пользовательских строк. Создайте его сериализатором и передайте через файл с --data-binary @payload.json.

Status curl и status HTTP

curl exit code сообщает о работе клиента: DNS, connect, TLS, timeout, запись файла или policy --fail. HTTP status находится в ответе. Для краткой метрики без смешивания с body используйте write-out.

curl --silent --show-error --output /dev/null \
  --write-out 'http=%{http_code} total=%{time_total}\n' \
  https://example.com/

Значение 000 обычно означает, что HTTP-response не получен; причину ищите в stderr и exit code.

Ошибка и диагностика

Не начинайте с -k/--insecure при TLS error: он отключает проверку сертификата. Проверьте системное время, hostname URL, цепочку CA и SNI. При timeout разделите connect-timeout и max-time, добавьте --verbose только в защищённый log и посмотрите, остановка произошла на DNS, TCP, TLS или после отправки request.

Практика

Получите example.com, сохранив headers/body отдельно, и выведите http_code через write-out. Запросите заведомо отсутствующий path сначала без --fail, затем с --fail-with-body и сравните exit status с HTTP-status. Не отключайте TLS-проверку.

Что важно запомнить

Источники