I’d like to build a proxy_pass in NGINX that proxies a request to a downstream server. The special case is that the target URI consists of some domain and a path and parameters that need to be built based on a parameter value of the incoming request.
For example, consider the following request that gets sent to my proxy:
curl 'https://example.com/proxy?forward=%2Fapi%2Fv1%3Fparam1%3Dval1%26param2%3Dval2' -v -X POST --data-raw '{ "key": "value" }'
I would like to then decode the value of the forward
parameter, which, in this case, would be: /api/v1?param1=val1¶m2=val2
. Then, this decoded string would have to be appended to some base URI, say https://example-proxy.com/
, such that the resulting request looks as follows:
curl 'https://example-proxy.com/api/v1?param1=val1¶m2=val2' -v -X POST --data-raw '{ "key": "value" }'
I’d like to forward the body, the headers, and add possibly additional headers to the forwarded request, such as X-Forwarded-For
.
The contents of the forward
parameter are not known in advance (neither the path, nor the parameters).
In case this makes any difference: I’m using ingress-nginx on Kubernetes.
I tried to build a location like this:
location /proxy {
proxy_pass https://example-proxy.com$arg_forward;
}
However, it seems like $arg_forward
is not being decoded. Is there any way to decode the parameter, preferably without installing additional modules?
I tried manually decoding the arguments, but my approach won’t scale, as I would have to repeat the if
statements many times since I don’t know how often any given character might occur:
location /proxy {
# fix all / (/api/v1)
if ( $arg_forward ~ (.*)%2F(.*) ){
set $arg_forward $1/$2;
}
if ( $arg_forward ~ (.*)%2F(.*) ){
set $arg_forward $1/$2;
}
if ( $arg_forward ~ (.*)%2F(.*) ){
set $arg_forward $1/$2;
}
# fix the ? (/api/v1?param)
if ( $arg_forward ~ (.*)%3F(.*) ){
set $arg_forward $1?$2;
}
# fix the = (/api/v1?param=val)
if ( $arg_forward ~ (.*)%3D(.*) ){
set $arg_forward $1=$2;
}
# ...and so on, many many more times
proxy_pass https://example-proxy.com$arg_forward;
}