С чего начать Первые шаги трек · 15 ступеней
Linux Labs

curl — HTTP-запросы из консоли

6 мин Ubuntu 24.04 · curl 8.5

curl шлёт HTTP- и HTTPS-запросы из консоли: код ответа, заголовки, весь обмен, проверка сайта по имени и сертификату.

Шпаргалка

9 команд Версия для печати
  • curl -i http://site.lab.test/ код, заголовки, тело
  • curl -I http://site.lab.test/ только заголовки (HEAD)
  • curl -v -o /dev/null http://site.lab.test/ весь обмен
  • curl -s -o /dev/null -w '%{http_code}\n' http://site.lab.test/
  • curl -H 'Host: docs.lab.test' http://127.0.0.1/
  • curl --resolve shop.lab.test:443:127.0.0.1 https://shop.lab.test/
  • curl --cacert ca.pem https://shop.lab.test/ доверять своему CA
  • curl --unix-socket /run/app/app.sock http://localhost/
  • curl -X POST -H 'Content-Type: application/json' -d '{"a":1}' URL

Обзор

curl шлёт запрос и печатает тело ответа в stdout, ошибки — в stderr. Для отладки сайтов и прокси это первый инструмент: видно код ответа, заголовки и то, что curl делал до HTTP — DNS, соединение, TLS. Как устроены запрос и ответ — в статье http.

Код выхода curl говорит, дошло ли дело до HTTP. Ответ с любым кодом, даже 404 или 502, — это успех curl, код выхода 0. Ненулевой код — ответа нет или он не прошёл проверку:

Код выхода Что случилось
6 имя не превратилось в адрес
7 соединение не открылось
28 истекло время ожидания
35 TLS не договорился: например, https:// на HTTP-порт
52 сервер закрыл соединение без ответа
60 сертификат не прошёл проверку
22 с -f: ответ 4xx или 5xx

Ключи

18

Таблица ниже — основные ключи. -s прячет и прогресс, и ошибки; в скриптах его пишут вместе с -S, чтобы ошибка осталась видна.

Ключ Что делает Пример
-s --silent Без прогресс-бара и ошибок соединения; удобно для скриптов. curl -s https://example.com
-f --fail Завершиться с ошибкой на HTTP 4xx/5xx вместо вывода тела ошибки — важно для скриптов. curl -sf https://example.com
-L --location Идти по редиректам (3xx). curl -L https://example.com
-I --head Только заголовки ответа (запрос HEAD). curl -I https://example.com
-v --verbose Показать весь обмен — запрос, ответ, TLS-рукопожатие. curl -v https://example.com
-X --request method HTTP-метод запроса (POST, PUT, DELETE…). curl -X POST https://api.example.com/x
-d --data data Отправить данные в теле (по умолчанию как POST, form-urlencoded). curl -d 'a=1&b=2' https://api.example.com/x
-H --header header Добавить свой заголовок запроса. curl -H 'Authorization: Bearer TOKEN' https://api.example.com/x
-i --include Напечатать строку статуса и заголовки ответа перед телом. curl -i http://site.lab.test/
-S --show-error Показывать ошибку даже вместе с -s. curl -sS https://example.com
-w --write-out format Вывести метрику после запроса — код ответа, время, размер. curl -s -o /dev/null -w '%{http_code}\n' https://example.com
-o --output file Сохранить тело ответа в указанный файл. curl -o out.bin https://example.com/x
-O --remote-name Сохранить под именем, взятым из URL. curl -O https://example.com/file.tar.gz
--resolve host:port:address Подменить DNS-разрешение имени для этого запроса. curl --resolve example.com:443:10.0.0.1 https://example.com
--cacert file Доверять корневому сертификату из файла для этого запроса. curl --cacert ca.pem https://shop.lab.test/
--unix-socket path Соединяться через unix-сокет вместо TCP; имя из адреса идёт только в Host. curl --unix-socket /run/app/app.sock http://localhost/
-m --max-time seconds Предел времени на весь запрос; истёк — код выхода 28. curl -m 5 http://site.lab.test/
-k --insecure Не проверять TLS-сертификат сервера — только для отладки, не для прода. опасно curl -k https://self-signed.local

Ничего не найдено. Попробуй запрос короче.

Рецепты

5

Код ответа для проверки

bash
curl -s -o /dev/null -w '%{http_code}\n' http://site.lab.test/
curl -sf -o /dev/null http://site.lab.test/health || echo FAIL

Первая команда печатает код; 000 — ответа HTTP не было. Вторая полагается на код выхода: -f превращает 4xx и 5xx в ошибку 22.

Сайт по имени без DNS

bash
curl -H 'Host: docs.lab.test' http://127.0.0.1/
curl --resolve docs.lab.test:443:127.0.0.1 https://docs.lab.test/

-H 'Host: …' меняет только заголовок — сервер выберет сайт по нему. Для HTTPS нужен --resolve: имя из адреса идёт и в SNI, и в проверку сертификата.

HTTPS со своим CA

bash
curl --cacert ca.pem https://shop.lab.test/
curl -v --cacert ca.pem https://shop.lab.test/ -o /dev/null 2>&1 \
  | grep -E 'subject:|issuer:|expire date|verify'

--cacert добавляет доверенный корень для одного запроса. -v показывает, какой сертификат пришёл и чем закончилась проверка: SSL certificate verify ok. или причина отказа.

Запрос в unix-сокет

bash
curl --unix-socket /run/app/app.sock http://localhost/

Соединение идёт в файл сокета, имя localhost попадает только в Host. Права и ошибки сокетов — unix-sockets.

Данные и заголовки

bash
curl -X POST -d 'a=1&b=2' http://site.lab.test/form
curl -H 'Content-Type: application/json' -d '{"k":"v"}' URL
curl -H 'Authorization: Bearer TOKEN' https://api.lab.test/x
curl -O https://site.lab.test/file.tar.gz     # имя файла из адреса

С -d curl сам выбирает POST, -X POST можно не писать.

Неполадки

6

curl: (7) Failed to connect … Couldn't connect to server

На адресе и порту никто не слушает или соединение режет файрвол. Проверь sudo ss -tlnp на сервере. С --unix-socket curl пишет то же самое — Failed to connect to localhost port 80 — и когда нет файла, и когда нет прав.

curl: (6) Could not resolve host

Имя не нашлось: опечатка, нет записи в DNS или в /etc/hosts. Проверь getent hosts <имя> (dns-resolv) или обойди DNS через --resolve.

curl: (60) SSL certificate problem

Сертификат не прошёл одну из трёх проверок: доверие (unable to get local issuer certificate, self-signed certificate), имя (no alternative certificate subject name matches) или срок (certificate has expired). Разбор каждой — openssl-tls.

curl: (35) … wrong version number

https:// ушёл на порт, где сервер говорит обычным HTTP. Поправь схему или порт.

Код 0, а сайт отвечает ошибкой

Без -f ответ 404 или 502 — нормальный ответ для curl. В проверках смотри -w '%{http_code}' или добавляй -f.

curl: (52) Empty reply from server

Соединение открылось, но сервер закрыл его без ответа: приложение упало на запросе или слушает другой протокол. Смотри журнал приложения.

Опасно

2

-k вместо исправления

-k (--insecure) отключает проверку сертификата целиком. Проверка с -k проходит и при подмене сервера, и при истёкшем сертификате. Нужен свой CA — --cacert.

Пароли в командной строке

-u user:pass и -H 'Authorization: …' видны в истории оболочки и в ps других пользователей. Для скриптов — файл с правами 600 (-K файл или --netrc).

Термины

1
тайм-аут timeout
Завершение ожидания по установленному пределу времени; само по себе не определяет причину задержки. Ещё встречается в: stress-ng, Цели загрузки: default, multi-user, rescue и emergency, Коды завершения: $?, && и ||, HAProxy и ещё 13

См. также

  • http — запрос, ответ, коды и заголовки.
  • nginx — сервер, которому чаще всего шлёшь запросы.
  • openssl-tls — сертификаты и ошибки (60).
  • unix-sockets — --unix-socket и права на сокет.
  • dns-resolv — как имя превращается в адрес.
  • ss — кто слушает порт, если (7).
  • wget — скачивание файлов и сайтов.
Загрузка…