In one project, I need to inject a script to some requested page. With the proviso that the script is to be provided from yet another host (currently for test purposes loaded statically from localhost). I decided to use Ngnix + lua as a proxy.
Configuration is very simple:
sites-avaliable/default:
upstream app {
server main_app:8080;
}
server {
listen 80 default_server;
root /usr/share/nginx/html;
index index.html index.htm;
server_name localhost;
location / {
proxy_pass http://app;
}
location /login.html {
content_by_lua '
local res_main, res_guard = ngx.location.capture_multi{
{ "/main"..ngx.var.uri, {share_all_vars=true, always_forward_body=true}},
{ "/static/lore_ipsum.txt" },
}
local output = res_main.body
output = string.gsub(output, "</head>", res_guard.body.."<!-- Agent JS -->")
ngx.print(output)
';
}
location /main {
proxy_pass http://app;
}
Location /
works fine, but in /login.html
variable res_main
always is empty.
The problem probably is in the /main
location. I checked in tcpdump and I saw:
http://app
request to main_app contains /main/login.html
instead of /login.html
http://app/
(with slash at end) request is //login.html
/main/login.html
nor //login.html
not exist.
Is any way to use proxy_pass from lua? Maybe someone has an idea how else to do something like that?
P.S. Also try body_filter_by_lua
but (from lua_nginx docs):
Subrequest API functions (e.g., ngx.location.capture and ngx.location.capture_multi)
are currently disabled within this context due to
the limitations in NGINX output filter's current implementation
This is the expected behaviour according to your configuration. If you
to strip the /main prefix for the proxy in location /main, then you
need to strip it yourself. Nginx has no way to guess your mind for
that. A simple way is to write (untested)
location /main {
rewrite ^/main '' break;
proxy_pass ...;
}