Is it possible to send a http subrequest in a location block and use the response in the proxy_pass directive?
use case
My upstream application needs some additional information from an API. I've written a location block that proxies request with the proxy_pass directive. Before nginx sends the request to my application. I'd like to send an HTTP request to my API and use several response headers as request headers to my application.
This is the outline of what I want to achieve:
server {
server_name ...;
location {
# perform subrequest to fetch additional information from an api
proxy_pass myapplication;
proxy_set_header X-Additional-Info "some information from the subrequest";
}
}
The behaviour is similar to the auth_request module. However, I can't find documentation of sending an additional blocking HTTP request before inside a location block using standard nginx configuration.
You can't do it using regular nginx
directives but it's quite easy using lua-nginx-module.
This module embeds Lua, via the standard Lua 5.1 interpreter or LuaJIT 2.0/2.1, into Nginx and by leveraging Nginx's subrequests, allows the integration of the powerful Lua threads (Lua coroutines) into the Nginx event model.
Here's how to accomplish what you need:
conf.d/
test.conf
and header.lua
into it (see the contents below)docker run -p8080:8080 -v your_path/conf.d:/etc/nginx/conf.d openresty/openresty:alpine
server {
listen 8080;
location /fetch_api {
# this is a service echoing your IP address
proxy_pass http://api.ipify.org/;
}
location / {
set $api_result "";
access_by_lua_file /etc/nginx/conf.d/header.lua;
proxy_set_header X-Additional-Info $api_result;
# this service just prints out your request headers
proxy_pass http://scooterlabs.com/echo;
}
}
local res = ngx.location.capture('/fetch_api', { method = ngx.HTTP_GET, args = {} });
ngx.log(ngx.ERR, res.status);
if res.status == ngx.HTTP_OK then
ngx.var.api_result = res.body;
else
ngx.exit(403);
end
curl http://localhost:8080/
Simple webservice echo test: make a request to this endpoint to return the HTTP request parameters and headers. Results available in plain text, JSON, or XML formats. See http://www.cantoni.org/2012/01/08/simple-webservice-echo-test for more details, or https://github.com/bcantoni/echotest for source code.
Array
(
[method] => GET
[headers] => Array
(
[X-Additional-Info] => my-ip-address
[Host] => scooterlabs.com
[Connection] => close
[User-Agent] => curl/7.43.0
[Accept] => */*
)
[request] => Array
(
)
[client_ip] => my-ip-address
[time_utc] => 2018-01-23T19:25:56+0000
[info] => Echo service from Scooterlabs (http://www.scooterlabs.com)
)
Notice the X-Additional-Info
header populated with the data obtained in /fetch_api
handler
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With