← Сеть: основы
19 мин · просто · Урок 4 из 13

HTTP и HTTPS

Request/response, методы, статусы, заголовки. HTTP/1.1 vs 2 в двух абзацах.

Модель request/response

HTTP устроен как разговор по очереди: клиент спросил, сервер ответил. В HTTP/1.1 в одном соединении нет одновременных потоков и сервер не отвечает по своей инициативе (в HTTP/2 запросы мультиплексируются, см. ниже).

Запрос:

POST /api/login HTTP/1.1
Host: example.com
Content-Type: application/json
Authorization: Bearer eyJhbG...
Content-Length: 42

{"email":"a@b.com","password":"secret"}

Ответ:

HTTP/1.1 200 OK
Content-Type: application/json
Set-Cookie: session=abc123; HttpOnly; Secure
Content-Length: 27

{"token":"eyJhbGciOiJI..."}

Структура одинаковая: первая строка (метод+путь или статус), затем заголовки, пустая строка, тело.

Но до того, как клиент сможет отправить этот запрос, TCP должен открыть соединение — три пакета между клиентом и сервером:

Клиент Сервер SYN seq=x SYN+ACK seq=y, ack=x+1 ACK ack=y+1 ESTABLISHED
Три пакета до первого байта данных: это и есть себестоимость TCP-соединения.

Дальше, если это HTTPS, сразу после TCP идёт TLS-handshake, и только потом клиент отправляет HTTP-запрос и получает ответ. Эти три пакета SYN/SYN-ACK/ACK — «себестоимость» любого TCP-соединения, ~1 RTT накладных.

Методы

МетодЧто делаетИдемпотентныйС телом
GETпрочитать ресурсдане принято¹
POSTсоздать / любое действиенетда
PUTзаменить ресурс целикомдада
PATCHчастично обновитьнет²да
DELETEудалитьдаредко
HEADкак GET, но без тела (только headers)данет
OPTIONSкакие методы доступны (используется CORS)данет

Идемпотентность — «повторный вызов даёт тот же результат». Это важно для retry-логики: GET и PUT можно безопасно повторять, POST — нет (можно случайно создать два заказа).

¹ Тело у GET стандарт не запрещает (RFC 9110), но серверы и прокси его обычно игнорируют, поэтому так не делают. ² PATCH не идемпотентен по определению (RFC 5789), но конкретный патч можно спроектировать идемпотентным (например, «установить поле в X»).

Статусы

Первая цифра задаёт класс:

Самые ходовые наизусть:

КодКогда
200 OKстандартный успех
201 Createdсоздан новый ресурс (после POST)
204 No Contentуспех, тела ответа нет (после DELETE)
301 Moved Permanentlyредирект навсегда (кешируется)
302 Foundредирект временный
304 Not Modifiedу тебя свежая копия, отдавать заново нечего
400 Bad Requestзапрос невалиден, исправь
401 Unauthorizedне аутентифицирован, залогинься
403 Forbiddenаутентифицирован, но прав нет
404 Not Foundресурс не существует
409 Conflictконфликт состояния (имя занято, версия устарела)
422 Unprocessable Entityсинтаксически ок, семантически нет
429 Too Many Requestsклиент превысил лимит запросов в секунду/минуту, нужно подождать (часто в заголовке Retry-After указано сколько)
500 Internal Server Errorсервер упал
502 Bad Gatewayпрокси не дозвонился до апстрима
503 Service Unavailableсервис временно недоступен
504 Gateway Timeoutпрокси дозвонился, но апстрим не успел ответить

502/503/504 — три ошибки, которые DevOps видит чаще всего. Учись различать:

502 Bad Gateway backend не отвечает на соединение Клиент nginx backend refused 502 504 Gateway Timeout соединение есть, но ответа нет в таймаут Клиент nginx backend connected ждём proxy_read_timeout… 504
Слева соединения нет вовсе, справа оно есть, но ответа не дождались.

Заголовки, которые встретишь

ЗаголовокЗачем
Content-Typeкакой формат у тела: application/json, text/html
Content-Lengthразмер тела в байтах
Authorizationтокен / basic-auth / Bearer
Cookie / Set-Cookieсессия и состояние
User-Agentкто клиент (браузер, бот, curl)
Cache-Controlкак клиенту/прокси кешировать
ETag / If-None-Matchусловный запрос: верни только если изменилось
Hostкакой домен запрашивается (важно при multi-tenant nginx)
X-Forwarded-Forоригинальный IP клиента, когда есть прокси

HTTPS

HTTPS — это HTTP, обёрнутый в TLS. Что добавляется:

Сертификаты сегодня бесплатные (Let's Encrypt), сайт на обычном HTTP без TLS в проде — редкий артефакт. Caddy и Traefik выпускают и обновляют сертификат автоматически — тебе достаточно указать домен.

Подробности TLS (handshake, версии 1.2 vs 1.3, как именно работает шифрование) — это отдельная большая тема, к HTTP она прилипает только снаружи. На уровне приложения с HTTPS работаешь как с обычным HTTP.

HTTP/1.1 vs 2 vs 3

HTTP/1.1 — текстовый, одно TCP-соединение = одна запрос/ответ за раз. Чтобы открыть страницу с 50 ресурсами, браузер открывает 6 параллельных коннектов и плачет.

HTTP/2 — бинарный, мультиплекс в одном TCP: десятки запросов одновременно. Headers сжимаются (HPACK). Сервер-push был, но Chrome выключил его поддержку в 2022. Похожую задачу частично решает 103 Early Hints (отдельная фича, не прямая замена): сервер успевает подсказать клиенту, какие ресурсы скоро понадобятся, ещё до основного ответа.

HTTP/3 — построен поверх QUIC (это уже UDP, не TCP). Решает проблему head-of-line blocking при потере пакетов. Заметно лучше на мобильных и нестабильных сетях. Поддержка в браузерах и серверах есть, но не везде в инфраструктуре.

Тебе как DevOps интересно: nginx, Caddy, ALB — все умеют h2 и h3 (h3 - не всегда), включается обычно одной опцией. Видеть это можно в curl -v --http2 и curl --http3.

CORS — почему «работает локально, не работает в браузере»

CORS (Cross-Origin Resource Sharing) — механизм браузера, который запрещает страницам с одного origin (например https://app.example.com) дёргать API на другом origin (https://api.example.com), если сервер явно не разрешил.

Как это выглядит у юзера: фронт делает fetch("https://api.example.com/me"), в браузере красная ошибка про CORS, в консоли что-то типа «No 'Access-Control-Allow-Origin' header». А curl https://api.example.com/me из терминала работает — CORS это правило браузера, не сервера.

Как сервер разрешает:

Типовые ошибки на проде:

curl как способ всё посмотреть глазами

curl -v https://example.com          # все заголовки + handshake + ответ
curl -I https://example.com          # только response headers (HEAD)
curl -H "Authorization: Bearer X" ... # добавить заголовок
curl -X POST -d '{"a":1}' \
     -H "Content-Type: application/json" \
     https://api.example.com/x
curl --json '{"a":1}' https://api.example.com/x  # curl 7.82+, короче
curl -L https://example.com          # следовать редиректам
curl -o file.zip https://...         # сохранить тело в файл
curl --resolve host:443:1.2.3.4 https://host/   # подменить DNS-резолв

curl -v показывает весь handshake, сертификат, заголовки в обе стороны. Так выглядит вывод (строки * — это диагностика curl, > — запрос, < — ответ):

$ curl -v https://example.com
*   Trying 93.184.216.34:443...
* TLSv1.3 (OUT), TLS handshake, Client hello
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
> GET / HTTP/2
> Host: example.com
> user-agent: curl/8.5.0
< HTTP/2 200
< content-type: text/html; charset=UTF-8
< content-length: 1256

Видно цепочку: TCP-соединение, TLS-handshake с версией и шифром, потом сам HTTP-запрос и ответ. Это базовый инструмент диагностики HTTP-проблем.

На собесе спросят

Короткие ответы, которые надо уметь проговорить:

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

HTTP это request/response: метод+путь, заголовки, опционально тело. Методы делятся на идемпотентные (GET/PUT/DELETE) и нет (POST/PATCH).

Пять классов статусов: 1/2/3/4/5xx. На проде чаще всего видишь 502 (прокси не дозвонился) и 504 (бэкенд не успел) — не путай.

HTTPS — тот же HTTP, обёрнутый в TLS и работающий на 443.

HTTP/2 даёт мультиплекс в одном TCP-соединении, HTTP/3 переезжает на UDP/QUIC. На уровне приложения разницы нет, включается опцией прокси.

CORS — правило браузера, не сервера. Из curl не воспроизведёшь.

curl -v показывает handshake, заголовки и ответ — с него удобно начинать разбор HTTP-проблем.

В следующем уроке — набор утилит, которыми чинят сеть, когда что-то сломалось.

Дрилл · вопросы как на собесе

Проверь себя без подсказок

Сформулируй ответ вслух или письменно, потом раскрой и честно отметь: знал или нет.

01

Какие методы HTTP бывают?

NET-010
02

Какие коды ответов HTTP бывают?

NET-011

Прошли материал до конца? Отметьте урок пройденным.