Прежде всего, ваш ^/(123[0-9])$
регулярное выражение будет соответствовать только /1234
URI (или /1230
, /1231
и др.), но не /1234/некоторые/путь
так как вы используете $
якорь на конце струны. Я предполагаю, что это не ошибка, а дизайнерское решение. Если это не так, чтобы соответствовать обоим /1234
и /1234/некоторые/путь
(но не что-то вроде /12345
), вы можете использовать чередование: ^/(123[0-9])(?:/|$)
(Я использую группу без захвата (?:...)
здесь, так как считается, что он имеет немного лучшую производительность, чем группа захвата).
В вашей конфигурации есть целая куча различных ошибок. Давайте рассмотрим каждый.
Ошибка №1: Неправильно переписать... последний;
Применение.
Действительно, вы не можете указать URI для proxy_pass
вверх по течению, как вы пытаетесь сделать с косой чертой
proxy_pass http://localhost:$1/; # добавить косую черту не разрешается
внутри местоположений, совпадающих с регулярными выражениями (а также внутри именованных местоположений), и единственный способ изменить URI, который будет передан серверной части, — это использовать переписать
директива. Однако правильный способ изменить URI внутри место расположения
блок для обработки его позже в том же месте, чтобы использовать переписать... сломать;
поскольку переписать... последний;
заставит nginx искать новое место для переписанного URI. Это означает, что мы должны использовать сломать
флаг для переписать
директива:
переписать ^/[0-9]{4}(.*)$ $1 break;
Остерегаться! Никаких указаний от ngx_http_rewrite_module
будет выполнен после переписать... сломать;
(или просто сломать;
) директива (Обновить: после некоторого тестирования, вопреки тому, что сказано в документация, оказывается верно только для сломать
директива, но не переписать... сломать
один, по крайней мере, для OpenResty 1.17.8.2 на базе ядра nginx 17.8).
Ошибка №2: Вы должны заключать в кавычки любую строку, содержащую фигурные скобки, иначе они будут считаться блоком конфигурации nginx.
Предыдущая директива выдаст нам следующую ошибку:
nginx: директива [emerg] «rewrite» не завершается символом «;»
Чтобы избавиться от этой ошибки, нам нужно заключить наш шаблон регулярного выражения в кавычки из-за использования фигурных скобок:
переписать "^/[0-9]{4}(.*)$" $1 break;
Ошибка № 3: пронумерованные захваты перезаписываются всякий раз, когда вычисляется регулярное выражение.
Предположим, у вас есть URI /1234
:
расположение ~ ^/(123[0-9])$ {
# Здесь значение переменной '$1' равно "1234"
переписать "^/[0-9]{4}(.*)$" $1 break;
# Здесь значение переменной '$1' является пустой строкой!
proxy_pass http://localhost:$1; # Не будет порта для директивы proxy_pass
}
Вы можете сохранить это $1
значение перед тем, как правило перезаписи вычислит собственное регулярное выражение, используя установлен
директива:
расположение ~ ^/(123[0-9])$ {
установить $порт $1;
переписать "^/[0-9]{4}(.*)$" $1 break;
proxy_pass http://localhost:$port;
}
или лучше использовать именованная группа захвата:
расположение ~ ^/(?<порт>123[0-9])$ {
переписать "^/[0-9]{4}(.*)$" $1 break;
proxy_pass http://localhost:$port;
}
Иногда не может быть другого решения, кроме как использовать именованные захваты, отличный пример такой ситуации приведен на это нить.
Ошибка №4: Переписанный URI не может быть пустой строкой.
Опять же, давайте предположим, что у вас есть URI /1234
. После правила перезаписи внутренний nginx $ури
переменная будет иметь пустое значение. Это приведет к ошибке внутреннего сервера HTTP 500, а в журнале ошибок nginx вы увидите следующее сообщение об ошибке:
перезаписанный URI имеет нулевую длину
Чтобы устранить эту ошибку, просто перепишите любой URI на /
:
расположение ~ ^/(?<порт>123[0-9])$ {
переписать ^/перерыв;
proxy_pass http://localhost:$port;
}
Если вам нужно служить любой /<номер_порта>/некоторые/путь
запроса, как указано выше, вы должны использовать следующий блок местоположения, чтобы ваш переписанный URI начинался с косой черты:
расположение ~ ^/(?<порт>123[0-9])(?:/|$) {
переписать "^/\d{4}(?:/(.*))?" /$1 перерыв;
proxy_pass http://localhost:$port;
}
Ошибка № 5: вам нужно указать преобразователь при использовании переменных с proxy_pass
директива.
Приведенная выше конфигурация близка к рабочему решению. Однако он по-прежнему не работает, что приводит к ошибке HTTP 502 Bad Gateway. Вам необходимо указать резольвер
когда вы используете переменные с proxy_pass
директива и ваш апстрим указывается именем домена, а не IP-адресом, иначе вы получите следующую ошибку в журнале ошибок nginx:
не определен преобразователь для разрешения localhost
Как правило, вам придется использовать что-то вроде
резольвер 8.8.8.8;
расположение ~ ^/(?<порт>123[0-9])$ {
переписать ^/перерыв;
proxy_pass http://localhost:$port;
}
но так как ваш восходящий поток локальный хост
, вы можете указать его IP-адрес вместо имени домена, тогда вам это не понадобится. резольвер
директива вообще:
расположение ~ ^/(?<порт>123[0-9])$ {
переписать ^/перерыв;
proxy_pass http://127.0.0.1:$port;
}
Эта конфигурация должна быть полностью работоспособной (наконец-то). И еще раз, если вам нужно будет служить какой-либо /<номер_порта>/некоторые/путь
запрос, как указано выше, вместо этого вы должны использовать следующий блок местоположения:
расположение ~ ^/(?<порт>123[0-9])(?:/|$) {
переписать "^/\d{4}(?:/(.*))?" /$1 перерыв;
proxy_pass http://127.0.0.1:$port;
}