// Engineering Log
HTTP, HTTPS и TLS: Часть 1 — Что такое HTTP: запрос, ответ, методы и коды состояния
Опубликовано 25.09.2026
// Быстрый маршрут
Эта статья относится к теме Сети и маршрутизация.
HTTP (HyperText Transfer Protocol) — протокол прикладного уровня, по которому браузер, мобильное приложение или скрипт запрашивает у сервера ресурс и получает ответ. Ресурсом может быть HTML-страница, картинка, JSON из API или файл для скачивания. HTTP не хранит состояние между запросами: каждый запрос сервер обрабатывает отдельно, а «память» о пользователе — сессию, корзину, вход в личный кабинет — обеспечивают cookie и токены, которые клиент передаёт в заголовках.
Сейчас HTTP описан набором документов IETF 2022 года: RFC 9110 задаёт общую семантику (методы, коды, заголовки), а RFC 9112, 9113 и 9114 — способ передачи по сети для HTTP/1.1, HTTP/2 и HTTP/3. Семантика у всех версий одна, различается только то, как байты идут по проводу. Поэтому всё, что написано в этой части, верно для любой версии.
Как выглядит обмен
Клиент открывает TCP-соединение с сервером (для HTTP — порт 80, для HTTPS — 443), отправляет запрос и ждёт ответ. В HTTP/1.1 это обычный текст, его удобно разглядывать через curl -v:
curl -v http://example.com/Строки с > — то, что отправил curl, с < — ответ сервера:
> GET / HTTP/1.1
> Host: example.com
> User-Agent: curl/8.7.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: text/html
< Content-Length: 1256
< Cache-Control: max-age=3600
<
<!doctype html>
...Из чего состоит запрос
- Стартовая строка: метод, путь и версия протокола —
GET /catalog?page=2 HTTP/1.1. Путь включает строку запроса (?page=2), но не включает фрагмент (#section) — фрагмент браузер на сервер не отправляет. - Заголовки: пары
Имя: значение, по одной на строку. Обязателен толькоHost— по нему сервер понимает, какой из сайтов на этом IP-адресе нужен клиенту. - Пустая строка — конец заголовков.
- Тело — необязательно. Его передают методы, которые отправляют данные: POST, PUT, PATCH. Длину тела сервер узнаёт из заголовка
Content-Lengthили из разбивки на частиTransfer-Encoding: chunked.
Регистр в именах заголовков не важен: Content-Type и content-type — один заголовок. В HTTP/2 и HTTP/3 имена всегда передаются строчными буквами.
Из чего состоит ответ
- Строка состояния: версия, код и поясняющая фраза —
HTTP/1.1 404 Not Found. Фраза нужна только человеку, программы смотрят на код; в HTTP/2 и HTTP/3 её нет вовсе. - Заголовки ответа: тип содержимого, длина, правила кеширования, cookie, заголовки безопасности.
- Пустая строка и тело.
Методы
Метод говорит серверу, что клиент хочет сделать с ресурсом. RFC 9110 определяет восемь методов, ещё один (PATCH) — отдельный RFC 5789.
| Метод | Назначение | Безопасный | Идемпотентный | Тело запроса |
|---|---|---|---|---|
| GET | получить ресурс | да | да | не используется |
| HEAD | то же, что GET, но только заголовки | да | да | нет |
| POST | передать данные на обработку: форма, создание объекта | нет | нет | да |
| PUT | создать или целиком заменить ресурс по адресу | нет | да | да |
| PATCH | частично изменить ресурс | нет | нет | да |
| DELETE | удалить ресурс | нет | да | обычно нет |
| OPTIONS | узнать, какие методы доступны; используется в CORS | да | да | обычно нет |
| CONNECT | открыть туннель через прокси, чаще всего для HTTPS | нет | нет | нет |
| TRACE | вернуть запрос обратно для отладки; на серверах обычно выключен | да | да | нет |
Безопасный метод не меняет состояние на сервере: его можно вызывать сколько угодно, ничего не сломав. Поэтому поисковые роботы и функция предзагрузки в браузере свободно ходят по ссылкам — ссылки всегда ведут на GET. Если удаление записи в админке сделано через GET /delete?id=5, рано или поздно его выполнит какой-нибудь робот или антивирус, проверяющий ссылки из писем.
Идемпотентный метод даёт тот же результат при повторе. PUT /users/5 с одинаковым телом дважды оставит пользователя в том же состоянии, а два одинаковых POST /orders создадут два заказа. Это важно для повторов: клиенты, прокси и балансировщики имеют право сами повторить идемпотентный запрос после обрыва соединения, но не POST. Отсюда предупреждение браузера «Отправить данные формы повторно?» при обновлении страницы после POST.
Тело у GET формально не запрещено, но смысла по стандарту не имеет, и многие прокси и серверы его отбрасывают. Параметры GET передаются в строке запроса.
Коды состояния
Код — трёхзначное число, первая цифра задаёт класс.
1xx — информационные. Промежуточные ответы, после которых придёт окончательный.
100 Continue— сервер готов принять большое тело (клиент спрашивает об этом заголовкомExpect: 100-continue; curl добавляет его сам при отправке больших тел);101 Switching Protocols— сервер переходит на другой протокол, например WebSocket (подробнее — «Переход на HTTPS и заголовок Upgrade»);103 Early Hints— ранние подсказки: сервер ещё готовит страницу, но уже сообщает, какие стили и скрипты стоит начать загружать.
2xx — успех.
200 OK— обычный успешный ответ;201 Created— ресурс создан, его адрес в заголовкеLocation;204 No Content— успех, тела нет (частый ответ на DELETE и PUT);206 Partial Content— отдана часть файла по запросуRange; на этом работают докачка и перемотка видео.
3xx — перенаправления. Адрес, куда идти, — в заголовке Location.
301 Moved Permanentlyи308 Permanent Redirect— ресурс переехал навсегда; поисковики переносят вес страницы на новый адрес, браузер запоминает редирект;302 Foundи307 Temporary Redirect— временное перенаправление;304 Not Modified— ресурс не изменился, можно взять копию из кеша.
Разница между 301/302 и 308/307 в методе: при 301 и 302 браузеры исторически превращают POST в GET и теряют тело, а 307 и 308 обязывают повторить запрос тем же методом с тем же телом. Для редиректа API или формы используйте 307/308.
4xx — ошибка клиента. Запрос неправильный, повторять его без изменений бесполезно.
400 Bad Request— синтаксически неверный запрос, битый JSON;401 Unauthorized— нужна аутентификация (несмотря на название, речь о том, что клиент не представился); сервер присылает заголовокWWW-Authenticateсо способом входа;403 Forbidden— клиент известен, но доступа нет;404 Not Found— ресурса нет;405 Method Not Allowed— метод не поддерживается для этого адреса;408 Request Timeout— клиент слишком долго передавал запрос;409 Conflict— конфликт с текущим состоянием, например версия объекта устарела;413 Content Too Large— тело больше допустимого (в Nginx —client_max_body_size, по умолчанию 1 МБ);415 Unsupported Media Type— сервер не принимает такойContent-Type;429 Too Many Requests— сработало ограничение частоты; в заголовкеRetry-Afterможет быть время ожидания;451 Unavailable For Legal Reasons— доступ закрыт по требованию закона.
5xx — ошибка сервера. С запросом всё в порядке, сломалось на стороне сервера.
500 Internal Server Error— необработанная ошибка в приложении;502 Bad Gateway— прокси или балансировщик не получил корректный ответ от приложения за ним: приложение упало, закрыло соединение или ответило мусором;503 Service Unavailable— сервис временно недоступен: перегрузка, обслуживание;504 Gateway Timeout— прокси не дождался ответа от приложения.
Коды 502 и 504 почти всегда отдаёт не само приложение, а стоящий перед ним Nginx, HAProxy или CDN. Если вы видите 502, смотрите журнал прокси — там будет причина вроде connect() failed (111: Connection refused) while connecting to upstream.
URL и что уходит на сервер
Адрес https://user@shop.example.ru:8443/catalog/phones?sort=price#reviews разбирается так:
https— схема, она определяет протокол и порт по умолчанию;user@— данные пользователя; браузеры их больше не поддерживают, curl превращает их в заголовокAuthorization;shop.example.ru— хост, его резолвят в IP через DNS и передают вHost(а при HTTPS ещё и в SNI);8443— порт, если он не стандартный;/catalog/phones— путь;sort=price— строка запроса;reviews— фрагмент, остаётся в браузере.
Символы вне ASCII и служебные символы в пути и параметрах кодируются процентами: пробел — %20, кириллическая «я» — %D1%8F. Кириллический домен кодируется иначе — в Punycode (пример.рф → xn--e1afmkfd.xn--p1ai), и именно в таком виде он уходит в DNS и в Host.
Соединения и keep-alive
В HTTP/1.0 на каждый запрос открывалось новое TCP-соединение. В HTTP/1.1 соединение по умолчанию остаётся открытым, и следующие запросы идут по нему же: не нужно заново проходить тройное рукопожатие TCP и, для HTTPS, рукопожатие TLS. Закрыть соединение после ответа просит заголовок Connection: close.
Запросы по одному соединению HTTP/1.1 идут строго по очереди: следующий можно отправить только после ответа на предыдущий. Поэтому браузеры открывают к одному сайту до шести соединений параллельно. Эту проблему решили HTTP/2 и HTTP/3.
HTTP и HTTPS
HTTPS — это тот же HTTP, но переданный внутри зашифрованного соединения TLS. Запрос и ответ выглядят так же, меняется транспорт: сначала клиент и сервер договариваются о ключах и проверяют сертификат, и только потом по защищённому каналу идут HTTP-сообщения. Без TLS всё, что написано выше, — адрес, cookie, пароли из форм, содержимое страниц — видит и может изменить любой узел на пути: Wi-Fi в кафе, провайдер, прокси.
Попробуйте сами
HTTP/1.1 — текстовый протокол, и запрос можно набрать вручную, без браузера и curl. Команды ниже работают в Linux и macOS.
Запрос по HTTP через nc. Каждая строка заканчивается \r\n, после заголовков — пустая строка. sleep нужен, чтобы nc не закрыл соединение раньше, чем придёт ответ:
{ printf 'GET / HTTP/1.1\r\nHost: example.com\r\nConnection: close\r\n\r\n'; sleep 2; } | nc example.com 80 | head -6HTTP/1.1 200 OK
Date: Thu, 24 Sep 2026 04:54:21 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: close
Server: cloudflareУберите строку Host — сервер ответит 400 Bad Request: без неё он не знает, какой сайт вам нужен.
Тот же запрос по HTTPS. openssl s_client устанавливает TLS-соединение и передаёт в него ввод как есть:
printf 'HEAD / HTTP/1.1\r\nHost: example.ru\r\nConnection: close\r\n\r\n' \
| openssl s_client -quiet -connect example.ru:443 -servername example.ru 2>/dev/nullМетоды и коды состояния. Посмотрите, как ваш сайт отвечает на разные методы и на несуществующий адрес:
curl -s -o /dev/null -w '%{http_code}\n' https://example.ru/ # 200
curl -s -o /dev/null -w '%{http_code}\n' https://example.ru/no-such-page/ # должен быть 404, а не 200
curl -s -o /dev/null -w '%{http_code}\n' -X DELETE https://example.ru/ # 405 или 403
curl -si -X OPTIONS https://example.ru/ | grep -iE '^(HTTP|allow)' # какие методы разрешены
curl -s -o /dev/null -w '%{http_code} -> %{redirect_url}\n' http://example.ru/ # 301 на httpsЕсли на несуществующий адрес сайт отвечает 200 со страницей «Не найдено», поисковики считают такие страницы настоящими и индексируют их — это называется soft 404, и Google Search Console отмечает такие страницы отдельно.
Сам HTTP-запрос из curl. С ключом -v видно, какие заголовки curl добавил сам, — сравните их с тем, что отправляет браузер (DevTools → Network → Headers → Request Headers):
curl -sv -o /dev/null https://example.ru/ 2>&1 | grep '^>'Типичные ошибки
- Изменение данных через GET — робот или предзагрузка выполнит действие без ведома пользователя.
- Редирект форм и API через 301/302 — тело POST теряется. Нужен 307 или 308.
- 200 с текстом ошибки в теле вместо кода 4xx/5xx — мониторинг и кеши считают ответ успешным, CDN может закешировать страницу ошибки.
- 401 вместо 403 и наоборот — клиент не понимает, нужно ли ему войти или вход не поможет.
- Автоматический повтор POST в собственном клиенте после таймаута — двойные заказы и платежи. Для безопасного повтора используют ключ идемпотентности в заголовке (так делают платёжные API).
// Похожая задача
Если у вас похожая ситуация
Эта статья относится к одной из рабочих тем. Можно продолжить чтение по теме, перейти на главную, чтобы понять, чем я занимаюсь, или сразу открыть услуги.
Тема статьи
Сети и маршрутизация
MikroTik, VPN, маршрутизация, DNS, BGP, доступ и проблемы связности.
Часто с этим приходят
- Поднять VPN и безопасный доступ в офис или облако
- Починить маршрутизацию, DNS или нестабильный канал
- Настроить MikroTik, firewall и внешние подключения
// Следующий шаг
Если вам нужна не только статья, а помощь по этой теме, удобнее сразу перейти в услугу. Главная и подборка материалов остаются рядом.
Открыть услуги// Contact
Нужна помощь?
Свяжись со мной и я помогу решить проблему
Написать в TelegramОтвечаю в течение рабочего дня (03:00–13:00 GMT)
Или оставьте заявку здесь:
// Related