Я пытаюсь настроить NGINX / OpenResty для прокси-вызовов SOAP на 2 разных сервера на основе строки, присутствующей в запросе SOAP.
Что я могу сделать: я могу отправлять запросы прокси на 2 разных сервера в зависимости от пути, который вызывает клиент SOAP:
location /pathA {
proxy_pass http://www.ServerA.com/PathA/;
}
location /pathB {
proxy_pass http://www.ServerB.com/PathB/;
}
Что я не могу сделать:
Я не могу разделить трафик по содержанию запроса. Основная причина, по которой я считаю, заключается в том, что я не могу правильно собрать сценарий LUA для извлечения информации и последующего использования его для проксирования запроса.
location / {
conten_by_lua '
ngx.req.read_body()
local match = ngx.re.match(ngx.var.request_body,"STRING TO FIND")
if match then
proxy_pass http://www.ServerA.com/PathA/;
else
proxy_pass http://www.ServerB.com/PathB/;
как я могу этого добиться?
Я установил OpenResty, и LUA работает нормально.
Кажется, я где-то читал, что если запрос не является HTTP POST ngx.req.read_body()
не будет работать. Это правильно?
Спасибо за помощь.
Вы почти сделали это сами, единственное, что я бы сделал иначе - это использовать rewrite_by_lua
вместо того content_by_lua
:
location / {
set $proxy "";
rewrite_by_lua '
ngx.req.read_body()
local match = ngx.re.match(ngx.var.request_body, "STRING TO FIND")
if match then
ngx.var.proxy = "www.ServerA.com"
else
ngx.var.proxy = "www.ServerB.com"
end
';
proxy_pass http://$proxy$uri;
}
Если запрос не является HTTP POST или имеет пустое тело, ngx.req.read_body()
вернется nil
, поэтому лучше добавить дополнительную проверку:
location / {
set $proxy "";
rewrite_by_lua '
ngx.req.read_body()
local body = ngx.var.request_body
if (body) then
local match = ngx.re.match(body, "STRING TO FIND")
if match then
ngx.var.proxy = "www.ServerA.com"
else
ngx.var.proxy = "www.ServerB.com"
end
else
ngx.status = ngx.HTTP_NOT_FOUND
ngx.exit(ngx.status)
end
';
proxy_pass http://$proxy$uri;
}
Вы также можете ограничить разрешенные методы:
location / {
limit_except POST { deny all; }
...
}
Еще кое-что. В этой конфигурации, если вы укажете свои серверные ВМ с доменными именами вместо IP-адресов, вам понадобится resolver
директиву в вашем config. Вы можете использовать свой локальный сервер имен, если он у вас есть, или использовать что-то внешнее, например общедоступный DNS Google (8.8.8.8) или DNS, предоставленный вам вашим интернет-провайдером.