You can still use proxy_pass within content_by_lua, with a little indirection. That's what I was doing before I rewrote my code to use the lua-resty-http library I was recommending you consider. But it does have downsides, as Thibault indicated. What I had been doing previously was setting up a 'proxy' location:
location /proxy {
rewrite ^/proxy/+(.*) /$1 break;
...
proxy_pass http://$proxy_host;
}
And then calling it via ngx.location.capture from within the content_by_lua block:
location / {
content_by_lua_block {
...
local response = ngx.location.capture("/proxy" .. $request_uri, {
method = $request_method,
body = $request_body,
}
...
for k, v in pairs(response.header) do
ngx.header[k] = v
end
ngx.header["date"] = ngx.http_time(ngx.time())
ngx.status = response.status
if response.body then
ngx.print(response.body)
end
}
}
The downside is that the entire proxied request is captured before 'response' is returned by ngx.location.capture, so if it's large and slow then you are forced to wait for it. NGINX will even do things like automatically streaming to a local tempfile if it's a very large (or very slow, I think) response so as to not overwhelm the memory resources.
This is the reason I ended up switching to lua-resty-http and implementing streaming response logic with it. While the technique above worked fine for proxying requests to services that returned small payloads quickly, the delay to start serving things like large pdfs was noticeable. The total time to serve via /proxy wasn't actually bad, but a 3-second delay before the response starting appearing to the client was.
On Sunday, October 14, 2018 at 7:32:16 PM UTC-7, Sudip Datta wrote:
Hi,
Thanks for the responses and sorry for the delay in my reply.
I guess, I missed a critical point in my question. Before stating "capture the http response", I should have stated that I need to proxy_pass the request to another server, and the response ('R') from there needs to be captured. Hence, I attempted body_filter_by_lua.
Further, the response contains some information 'R.A'. 'R.A' needs to be queried on a separate Redis instance and response from Redis determines the final R (including a possible ngx.HTTP_SERVICE_UNAVAILABLE) that's sent to the client.
I believe, the use of proxy_pass eliminates the chance to use content_by_lua.
Any other alternatives?
Thanks again,
Sudip