![Директива Nginx map не соответствует правилам](https://rvso.com/image/697395/%D0%94%D0%B8%D1%80%D0%B5%D0%BA%D1%82%D0%B8%D0%B2%D0%B0%20Nginx%20map%20%D0%BD%D0%B5%20%D1%81%D0%BE%D0%BE%D1%82%D0%B2%D0%B5%D1%82%D1%81%D1%82%D0%B2%D1%83%D0%B5%D1%82%20%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D0%BB%D0%B0%D0%BC.png)
У меня есть такой файл конфигурации nginx:
map $request_uri $new_uri {
default DEFAULT;
/shell http://shell.com;
/lol http://lol.com;
}
map $request_uri $ret_code {
default 301;
/shell 301;
/lol 302;
}
server {
listen 80;
server_name TestDomain.com www.TestDomain.com;
location / {
add_header X-request_uri $request_uri;
add_header X-new_uri $new_uri;
add_header X-return_code $ret_code;
if ($new_uri = "DEFAULT") {
return 301 https://ashfame.com$request_uri;
}
if ($ret_code = 301) {
return 301 $new_uri;
}
if ($ret_code = 302) {
return 302 $new_uri;
}
}
}
Директива map вообще не работает, а просто по умолчанию принимает то, что определено в ней по умолчанию.
Например:
$ curl -I testdomain.com/lol
HTTP/1.1 301 Moved Permanently
Server: nginx/1.10.0 (Ubuntu)
Date: Sun, 22 Jan 2017 20:04:06 GMT
Content-Type: text/html
Content-Length: 194
Connection: keep-alive
Location: https://ashfame.com/lol
X-request_uri: /lol
X-new_uri: DEFAULT
X-return_code: 301
/lol
следовало бы установить $new_uri
как http://lol.com
и $ret_code
как 302
, но если посмотреть на X-
заголовки, то они просто принимают значения по умолчанию, указанные в сопоставлении.
Неделю назад я заставил работать эту же конфигурацию nginx, и с тех пор никаких изменений не было. У меня включены автоматические обновления безопасности Ubuntu, но не думаю, что nginx вообще обновлялся. Запускается v1.10.0
. Не могу точно сказать, почему это перестало работать.
Редактировать: Только что проверил эту же конфигурацию на другом VPS, той же версии nginx, и там все работает правильно. Как мне теперь это исправить?
решение1
Я разобрался с проблемой. У меня было несколько таких файлов конфигурации для каждого домена, и поскольку map определен в контексте http, последний перезаписывал значение переменных. Я исправил это, добавив суффикс к имени переменной в каждом файле конфигурации, чтобы переменные были уникальными:
map $request_uri $new_uri_5 {
default DEFAULT;
/shell http://shell.com;
/lol http://lol.com;
}
map $request_uri $ret_code_5 {
default 301;
/shell 301;
/lol 302;
}
server {
listen 80;
server_name TestDomain.com www.TestDomain.com testdomain.com www.testdomain.com;
location / {
add_header X-request_uri $request_uri;
add_header X-new_uri $new_uri_5;
add_header X-return_code $ret_code_5;
if ($new_uri_5 = "DEFAULT") {
return 301 https://ashfame.com$request_uri;
}
if ($ret_code_5 = 301) {
return 301 $new_uri_5;
}
if ($ret_code_5 = 302) {
return 302 $new_uri_5;
}
}
}
5 — это идентификатор этого конкретного домена в моей системе.
решение2
Я столкнулся с той же проблемой в Nginx 1.12.2 — директива map не соответствовала ни одному из шаблонов, даже самым простым и тривиальным, таким как /
, и всегда использовала значение по умолчанию.
Проблема была вызвана использованием переменной $uri
в отображении. Некоторые конфигурации Nginx неявно изменяли $uri
исходное значение, добавляя /index.php
префикс, что приводило к несоответствию шаблона. Такое поведение $uri
является намеренным и точное различие между$request_uri
и $uri
переменные.
Исправление заключалось в замене переменной URI в конфигурации Nginx:
map $uri $result_var {
# ...
}
со следующим:
map $request_uri $result_var {
# ...
}