Я пытаюсь динамически разрешить значение proxy_pass (через веб-api) в nginx.
Мне нужно что-то вроде ниже:
Пример взят из: https://www.nginx.com/resources/wiki/start/topics/depth/ifisevil/
location /proxy-pass-uri {
set $urlToProxy = CallWebAPI("http://localhost:8081/resolver?url = " + $url);
proxy_pass $urlToProxy;
}
Итак, мой вопрос в том, можно ли сделать HTTP-запрос или написать такой метод, как CallWebAPI?
Я знаю, что это может быть плохой практикой, но на веб-сайте, с которым я имею дело, есть тысячи веб-адресов, которые отображаются как пары ключ-значение, и 90% из них не подчиняются каким-либо конкретным правилам регулярных выражений. Итак, у меня есть база данных с отображением контента, и мне нужно динамически получать входящий URL-адрес с контентом.
Я пытаюсь использовать очень легкую веб-службу для поиска URL-адресов из Redis и возврата URL-адреса прокси.
Будет ли это допустимым сценарием, или есть какое-либо другое встроенное решение в nginx, подобное этому?

Я сомневаюсь, что это можно сделать с "чистым" nginx, но это определенно можно сделать с помощью открытость или ngx_http_lua_module с помощью метода ngx.location.capture. Например:
resolver 8.8.8.8;
location ~/proxy-pass-uri(/.*)$ {
set $url $1;
set $proxy "";
access_by_lua_block {
res = ngx.location.capture("http://localhost:8081/resolver?url = " .. ngx.var.url)
ngx.var.proxy = res.body
}
proxy_pass $proxy$url;
}
Существует также ngx_http_js_module (документация, GitHub), который может выполнять подзапросы (пример), но я никогда не использовал его и не могу сказать, можно ли его использовать таким образом.
Важное обновление
Спустя почти три года с момента написания этого ответа выяснилось, что мне самому понадобилась аналогичная функциональность, и оказалось, что приведенный выше ответ полностью сломан и неработоспособен. Вы не можете выполнить подзапрос через ngx.location.capture ни к чему другому, кроме как к другому местоположению nginx. Итак, правильный (проверенный и подтвержденный работоспособностью) пример для вышеуказанного вопроса:
resolver 8.8.8.8;
location /resolver {
internal;
proxy_pass http://localhost:8081;
}
location ~ ^/proxy-pass-uri(/.*)$ {
set $url $1;
set $proxy "";
access_by_lua_block {
res = ngx.location.capture("/resolver?url = " .. ngx.var.url)
if res.status == ngx.HTTP_OK then
ngx.var.proxy = res.body
else
ngx.exit(res.status)
end
}
proxy_pass $proxy$url$is_args$args;
}
В приведенном выше примере предполагается, что служба разрешения прокси действительно ожидает запроса в форме /resolver?url=<uri>. location /resolver { ... }, будучи внутренним, ведет себя как любое другое местоположение префикса, поэтому, если префикс /resolver для этого местоположения не может быть использован по какой-либо причине, его можно записать как
resolver 8.8.8.8;
location /get_proxy {
internal;
proxy_pass http://localhost:8081/resolver;
}
location ~ ^/proxy-pass-uri(/.*)$ {
set $url $1;
set $proxy "";
access_by_lua_block {
res = ngx.location.capture("/get_proxy?url = " .. ngx.var.url)
if res.status == ngx.HTTP_OK then
ngx.var.proxy = res.body
else
ngx.exit(res.status)
end
}
proxy_pass $proxy$url$is_args$args;
}
Один JavaScript выглядит очень многообещающим, я проверю это и дам вам знать, спасибо!