Регулярное выражение Nginx не работает с пропуском прокси

44

Я пытаюсь заставить эти 2 директивы определения местоположения работать в Nginx, но я получаю некоторые ошибки при загрузке Nginx.

   location ~ ^/smx/(test|production) {
        proxy_pass   http://localhost:8181/cxf;
    }

    location ~ ^/es/(test|production) {
        proxy_pass   http://localhost:9200/;
    }

Это ошибка, которую я получаю:

nginx: [emerg] "proxy_pass" cannot have URI part in location given by regular expression, or inside named location, or inside "if" statement, or inside "limit_except" block

Звучит ли это кому-нибудь знакомо? Что мне здесь не хватает?

Нильс
источник

Ответы:

49

Небольшое дополнение к великолепному ответу Хавиара :

Если вы не очень хорошо знакомы с nginx, есть важная разница между добавлением косой черты в конце proxy_passдирективы.

Следующее не работает:

location ~* ^/dir/ {
  rewrite ^/dir/(.*) /$1 break;
  proxy_pass http://backend/;

но этот делает:

location ~* ^/dir/ {
  rewrite ^/dir/(.*) /$1 break;
  proxy_pass http://backend;

Разница заключается /в конце proxy_passдирективы.

отметка
источник
1
Этот трейлинг /исправил мою проблему с конфигурацией, это было трудно поймать, спасибо!
Йорк
Сводил меня с ума, спасибо за указание на это!
Cyrrill
22

Он говорит вам, что URI в директиве proxy pass нельзя использовать в расположении регулярного выражения. Это связано с тем, что nginx не может заменить часть URI, совпадающую с регулярным выражением в locationблоке, частью, переданной в proxy_passдирективе общим способом.

Просто представьте, что ваше регулярное выражение местоположения есть /foo/(.*)/bar, и вы указываете proxy_pass http://server/test, что nginx придется сопоставить ваше регулярное выражение местоположения с другим на верхнем уровне, потому что вы не хотите заканчивать, /foo/test/bar/somethingа только /test/something. Так что это не возможно изначально.

Таким образом, для этой части должно работать следующее:

server {

   [ ... ]

    location ~ ^/smx/(test|production) {
        rewrite ^/smx/(?:test|production)/(.*)$ /cxf/$1 break;
        proxy_pass http://localhost:8181;
    }

    location ~ ^/es/(test|production) {
        rewrite ^/es/(?:test|production)/(.*)$ /$1 break;
        proxy_pass http://localhost:9200;
    }

}

Однако невозможно будет переписать перенаправления в соответствии с шаблоном URI блока местоположения, поскольку он перезаписывает текущий обрабатываемый URI, что делает невозможным изменение Locationзаголовка на основе первоначального запроса перед перезаписью.

Ксавье Лукас
источник
2
перемещение пути в правило перезаписи сработало для меня. Спасибо.
sonjz