nginx: read response header in njs subrequest - nginx

I'm trying to chain two requests together using nginx's njs module and subrequests. I can see that special_value comes back in the response headers but I don't know how to read the value using proxy_set_header. The code below results in a blank value in X-Special-Value
nginx.conf:
location ~* /step_one {
js_content njs_func;
}
location ~* /step_two {
proxy_pass http://some_other/api;
proxy_set_header X-Special-Value $http_special_val;
}
http.js
function njs_func(r) {
r.headersOut['special_val'] = '42';
r.subrequest('/step_two')
.then(reply => r.return(reply.status, reply.responseBody));
}

you could do something like this:
nginx.conf
set $specialValue "";
location ~* /step_one {
js_content njs_func;
}
location ~* /step_two {
proxy_pass http://some_other/api;
proxy_set_header X-Special-Value $specialValue;
}
https.js
function njs_func(r) {
r.variables.specialValue = '42';
r.subrequest('/step_two')
.then(reply => r.return(reply.status, reply.responseBody));
}

Related

how to add multiple location blocks for proxy pass in nginx for specific region/URL

I am trying to setup nginx for reverse proxy. But I have to do it for multiple servers which are basically for different regions. I have three regions APAC, Australia, Japan
location /au/myEndPoint1 {
proxy_pass https://AUSTRALIA_SERVER/myEndPoint1 ;
}
location /jp/myEndPoint1 {
proxy_pass https://JAPAN_SERVER/myEndPoint1 ;
}
location /myEndPoint1 {
proxy_pass https://APAC_SERVER/myEndPoint1 ;
}
location /au/myEndPoint2 {
proxy_pass https://AUSTRALIA_SERVER/myEndPoint2 ;
}
location /jp/myEndPoint2 {
proxy_pass https://JAPAN_SERVER/myEndPoint2 ;
}
location /myEndPoint2 {
proxy_pass https://APAC_SERVER/myEndPoint2 ;
}
But when I test this for /au/myEndPoint1, I received request sometimes on location /myEndPoint1 and sometimes on /au/myEndPoint1.

How to specify correctly Nginx reverse proxy configuration for POST /some_endpoint/<product>/<component>/<key> using Regex

How to write properly configuration for Nginx in order to map incoming POST /some_endpoint/product/component/key to the appropriate node?
Product, component, key are different from request to request.
I have tried some variants, no lack.
location /some_endpoint/([0-9A-Za-z]+)$/([0-9A-Za-z]+)$/([0-9A-Za-z]+)$ {
proxy_pass http://first-node:8080/some_endpoint/$1/$2/$3;
}
location /some_endpoint/(~*)$/(~*)$/(~*)$ {
proxy_pass http://first-node:8080/some_endpoint/$1/$2/$3;
}
I have achieved needed behaviour using the following configurations:
location ~/rest-endpoint1/(.*)$ {
proxy_pass http://first-node:8080/rest-endpoint1/$1$is_args$args;
}
location ~/rest-endpoint2/(.*)$ {
proxy_pass http://first-node:8080/rest-endpoint2/$1$is_args$args;
}
location ~/rest-endpoint3/(.*)$ {
proxy_pass http://second-node:8081/rest-endpoint3/$1$is_args$args;
}
location ~/rest-endpoint4/(.*)$ {
proxy_pass http://second-node:8081/rest-endpoint4/$1$is_args$args;
}

nginx extract a value from post and get

I need to make a reverse proxy using nginx that proxy clients according to a specific id that they provides inside they post/get:
clientid=<value from the clientid inside the post/get>
if clientid=XXX {
ProxyPass server1
}
if clientid=YYY {
ProxyPass server2
}
How can I achieve that with nginx ?
with #workaround comments, i get something like this:
location ~ ^/(api|newapi)/(v2/)?(xxxx|yyyy|zzzz) {
echo_read_request_body;
echo $request_body;
if ($request_body ~* (.*)?clientid=2621(.*)?) {
proxy_pass https://apiold;
}
proxy_pass https://apinew;
include proxy.conf;
}
According to official nginx documentation try using:
if (($request_body ~* (.*)clientID#1(.*)) )
{
proxy_pass server1;
}
if (($request_body ~* (.*)clientID#2(.*)) ) {
proxy_pass server2;
}
}

How can we compare request parameters of a request against an array of strings in Nginx

In Nginx, we can compare request parameters of a request like this.
location / {
if ( $arg_cmd = "export_query" ) {
add_header x-served-from "replica";
proxy_pass http://replica-first;
break;
}
...
Currently, we are trying redirect requests with some specific params to a different server. These parameters are in hundreds.
How can we do parameter matching against an array in nginx?
map $arg_cmd $replica {
"export_query" replica-first;
}
server {
...
location / {
if ($replica) {
add_header x-served-from $replica;
proxy_pass http://$replica;
break;
}
}
...
Documentation on map is here.
Note: using variables in proxy_pass will require resolver.

call a location and use the returened header status

I've two locations on my Nginx config:
location /ok {
return 200;
}
location /check {
# pseudo code
if (call(http://localhost:9090/ok) == 200) do something
}
I just can use Nginx and think one solution it can be proxy_pass /check to /ok and if everything were OK proxy_pass request again to a new location, Any idea?
Thanks

Resources