# конспект · шаг 7 из 7
Конспект: протокол под nginx
Решение №0: на чём вообще всё держится. Протокол, поверх которого настраивается всё остальное в курсе.
Четыре части сообщения
строка запроса GET /catalog/42?sort=price HTTP/1.1
заголовки Host: shop.local
User-Agent: curl/8.22.0
пустая строка ← признак «заголовки кончились»
тело у GET его нет
У ответа то же самое, только первая строка другая: HTTP/1.1 200 OK.
Адрес по частям
| Часть | Куда попадает |
|---|---|
схема https:// |
в запрос не едет; решает порт и шифрование |
хост shop.local |
заголовок Host |
путь /catalog/42 |
первая строка запроса; по нему выбирается location |
параметры ?sort=price |
там же; в выборе location не участвуют |
фрагмент #otzyvy |
остаётся в браузере, на сервер не уходит |
Три переменные над одним адресом:
| Переменная | Что в ней |
|---|---|
$request_uri |
как прислали, вместе с ? и кодированием |
$uri |
раскодированный и нормализованный путь |
$args |
параметры; не раскодируются вовсе |
В редиректах нужен $request_uri - иначе теряются метки и параметры поиска.
Коды по классам
| Класс | Смысл | Кто обычно назначает |
|---|---|---|
| 1xx | ответ ещё не окончательный | nginx; в access_log не попадает |
| 2xx | готово (200, 204 без тела, 206 кусок) | файл - nginx, данные - приложение |
| 3xx | иди туда; плюс 304 «твоя копия годится» | чаще nginx |
| 4xx | так спросить нельзя | оба; кто - видно по upstream в логе |
| 5xx | сломалось на сервере | 502 и 504 - всегда nginx |
- У 204 и 304 тела нет по определению, у редиректа обязателен
Location. return 301 /pathnginx достраивает до абсолютного адреса изHost.- 301 и 308 постоянные, браузер их запоминает; 307 и 308 сохраняют метод.
Соединение
- Каждый круг по сети стоит времени: TCP - один, TLS 1.3 - ещё один, TLS 1.2 - два, запрос - последний. Замер при задержке 50 мс: http 102 мс, https 163 мс, https с TLS 1.2 - 210 мс.
- Соединение живёт дольше запроса:
keepalive_timeout, по умолчанию 75 с. - Где кончается ответ, говорят
Content-Length(длина известна) илиTransfer-Encoding: chunked(длина неизвестна). Без одного из них соединение не переиспользовать. - В HTTP/1.1 очередь в соединении одна - отсюда HTTP/2.
Заголовки при проксировании
Участковые (hop-by-hop) - не пересылаются никогда: Connection,
Keep-Alive, Upgrade, Transfer-Encoding, TE, Trailer,
Proxy-Authenticate, Proxy-Authorization.
Всё остальное сквозное и обязано дойти до приложения без изменений.
proxy_set_header Host $host; # иначе бэкенд увидит имя upstream
proxy_set_header Accept-Encoding ""; # пустое значение = удалить заголовок
Ловушки джокера
- Имя заголовка с подчёркиванием отбрасывается молча.
X-Api_Keyне дойдёт ни до переменной, ни до бэкенда, и строки в логе не будет. Лечитсяunderscores_in_headers on, но правильнее переименовать вX-Api-Key. proxy_set_headerнаследуется «всё или ничего». Одна своя директива вlocationотменяет все унаследованные - вместе с заботливо поставленнымHost.- Одно имя заголовка может прийти дважды. Бэкенду уедут обе строки, а в
переменной nginx они склеятся через запятую (
a, b) - наивная проверка «равно a» так обходится. %2Fв пути становится настоящим слешем до выбораlocation:denyне обойти, но и слеш внутри имени файла не сохранить.- Фрагмент после
#в конфиге недоступен - его нет в запросе. - Слишком длинный адрес - 414, и объяснение пишется на уровне
info.
Комментарии
Пока нет комментариев. Будь первым!
Оставить комментарий