1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6

# конспект · шаг 6 из 6

Конспект: фазы, return и rewrite

выжимка - её можно унести в заметки

Фазы обработки и две директивы, которые заканчивают запрос досрочно.

Конвейер целиком

server rewrite   → return / rewrite / set / if прямо в server {}
find location    → выбор location по URI
rewrite          → return / rewrite / set / if внутри location
preaccess        → limit_req, limit_conn
access           → allow / deny, auth_basic, auth_request, satisfy
try_files        → проверка файлов на диске
content          → отдача файла, proxy_pass, autoindex
filters          → add_header, expires, gzip

Три следствия, которые спрашивают:

  1. return в location срабатывает раньше deny - замер даёт 200 против 403 у того же блока без return;
  2. return в server{} бьёт выбор location вообще;
  3. лимиты считаются после перезаписи URI: перезапись из свободного блока в ограниченный дала 200 503 503 503.

return: четыре формы

return 404;                             # код без тела
return 200 "ok\n";                      # код с телом
return 301 https://$host$request_uri;   # код и адрес
return https://shop.local/;             # адрес без кода = 302, а не 301
return 444;                             # закрыть соединение без ответа
замер что видит клиент
return 301 /new Location: http://<Host>/new - достроен до абсолютного
return 418 строка ответа 418 без названия
return 444 соединения нет, curl отвечает кодом 52

error_page

error_page 404 /404.html;          # своя страница, код остаётся 404
error_page 404 =200 /empty.json;   # знак равенства и код БЕЗ пробела
error_page 502 = @zaglushka;       # код возьмётся от ответа цели

error_page 404 = 200 ... с пробелом не грузится: invalid value "=". Отсутствующая цель не роняет сервер: клиент получает обычную стандартную страницу, а в error_log появляется open() ... failed (2: No such file or directory).

rewrite

rewrite ^/old/(.*)$ /new/$1 permanent;   # 301 клиенту
rewrite ^/old/(.*)$ /new/$1 redirect;    # 302 клиенту
rewrite ^/api/(.*)$ /$1 break;           # переписать и остаться здесь
rewrite ^/api/(.*)$ /$1 last;            # переписать и искать location заново
Флаг Что делает
last новый круг поиска location
break остаться в этом location и оборвать остальные директивы фазы
redirect / permanent внешний редирект 302 / 301
без флага, замена со схемы тоже внешний редирект (302)

Замена - это весь новый URI, несовпавший хвост не сохраняется: /хвост/длинный/путь при rewrite ^/хвост/ /короткий даёт ровно /короткий. Знак ? в конце замены отбрасывает исходные параметры.

Предел - десять перезаписей. Замер цепочкой: десять проходят, одиннадцатая даёт 500 и строку rewrite or internal redirection cycle while processing "…" в error_log.

Ловушки джокера

  • $uri вместо $request_uri в редиректе - теряется строка запроса, а с ней метки рассылок; замечают через месяц по отчёту.
  • rewrite ... last перед proxy_pass уходит на новый круг вместо прокси; для прокси нужен break.
  • return вместо deny - код выполнится раньше проверки доступа, и «закрытая» директория ответит 200.
  • return 200 в тестовой заглушке отменяет и limit_req: блок отвечает быстрее, чем считаются лимиты, и проверка защиты показывает не то.
  • break обрывает и то, что написано ниже - return после него не выполнится, запрос уйдёт на фазу контента с новым URI.

Комментарии

Пока нет комментариев. Будь первым!

Оставить комментарий

Комментарий появится после проверки. Email не публикуется. Войти, чтобы не вводить имя каждый раз.