Я пытаюсь преобразовать обратный прокси-сервер, используя интересную настройку Apache mod_rewrite, чтобы использовать вместо него Nginx (из-за внешних проблем мы переходим с Apache на Nginx, и почти все работает отлично, кроме этой части).
Моя первоначальная установка состояла в том, чтобы прочитать HTTP-cookie (установленный некоторым приложением) и, в зависимости от его значения, направить обратный прокси-сервер в разные бэкэнды. Это пошло примерно так:
RewriteCond %{HTTP_COOKIE} proxy-target-A
RewriteRule ^/original-request/ http://backend-a/some-application [P,QSA]
RewriteCond %{HTTP_COOKIE} proxy-target-B
RewriteRule ^/original-request http://backend-b/another-application [P,QSA]
RewriteRule ^/original-request http://primary-backend/original-application [P,QSA]
Я пытаюсь добиться того же, используя Nginx, и моя первоначальная конфигурация была примерно такой (где proxy_override - это имя файла cookie):
location /original-request {
if ($cookie_proxy_override = "proxy-target-A") {
rewrite . http://backend-a/some-application;
break;
}
if ($cookie_proxy_override = "proxy-target-B") {
rewrite . http://backend-b/another-application;
break;
}
proxy_pass http://primary-backend/original-application;
}
Но это не так. Я попытался выяснить, может ли Nginx прочитать мой файл cookie, написав основной прокси-сервер для перенаправления на что-либо на основе, ${cookie_proxy_override}
и я вижу, что он хорошо читает содержимое, но if
кажется, что всегда происходит сбой.
Моя следующая попытка, согласно ответу Рикиха, была такой:
location /original-request {
if ($http_cookie ~ "proxy-target-A") {
rewrite . http://backend-a/some-application;
break;
}
if ($http_cookie ~ "proxy-target-B") {
rewrite . http://backend-b/another-application;
break;
}
proxy_pass http://primary-backend/original-application;
}
И теперь я вижу, что if
блок активируется, но вместо того, чтобы проксировать запрос (как я и думал), он возвращает перенаправление 302 на указанный URL-адрес - это не то, что я пытаюсь сделать: мне нужен сервер прозрачно передать запрос бэкэндам и передать ответ исходному клиенту.
Что я делаю неправильно?
if
), и я ее реализовал. Однако есть одна проблема - Nginx (по крайней мере, моя версия: 1.0.0) не любит пронумерованные записиmap
, поэтому мне пришлось использовать~^(?P<name>[\w-]+) $name;
вместо этого. Я отредактировал ваш ответ соответственно.Со временем мое решение сводится к следующему:
Тест проводится в области
server
действия для каждого запроса (до разрешения фактического перенаправления) и просто используется для установки переменной - это, очевидно, поддерживаемое использование модуля перезаписи Nginx. Он также проверяет все$http_cookie
как предложено @Rikih, но включает в себя имя куки, чтобы убедиться, что я не сопоставляю случайные вещи, которые люди могут бросать на меня.Затем в
location
области, где я хочу выполнить перенаправление, я использую имя переменной, которая либо содержит исходную конфигурацию по умолчанию, либо была перезаписана файлом cookie.источник
Вы пробовали $ http_cookie? http://wiki.nginx.org/HttpRewriteModule
if ($ http_cookie ~ * "proxy-target-A") {foo; }
источник
rewrite
что на самом деле не происходит перезапись прокси, а вместо этого возвращает перенаправление клиенту, и я не могу использовать proxy_pass вif
блоке. Я обновил вопрос соответственно.У меня есть пример, который я использую для определения заголовка запроса на основе UDID, и он работает, может быть, вы получите некоторое представление.
источник
nginx: [emerg] "proxy_pass" may not have URI part in location given by regular expression, or inside named location, or inside the "if" statement, or inside the "limit_except" block in /etc/nginx/conf.d/proxy.conf:47
proxy_pass
команде, поэтому я не уверен, как он может работать для вас, учитывая вышеупомянутое обсуждение на форуме.