Nginx proxy_pass with variables are hard to understand. Can some one explain how would i acheive the below scenario.
#first call /?proxytohost=http://blahblah.com
#second redirection to /
#third call /home
location / {
if ($arg_proxytohost) {
set $proxytohost $arg_proxytohost;
rewrite ^.*$ / break;
}
proxy_pass https://$proxytohost; #first call it may recognize, third call definitely it cant
proxy_intercept_errors on;
error_page 301 302 307 = @handle_redirects;
}
location @handle_redirects {
set $saved_redirect_location '$upstream_http_location';
proxy_set_header Host $proxy_host;
proxy_pass $proxytohost$saved_redirect_location; #this has proxytohost, i dont think it can recognize the variable here
}
EDIT:
Wanted to reverse proxy few instances which are dynamic (a.blahblah.com, b.blahblah.com, etc.). Each of those service instances has multiple redirects where i need to store cookies and redirect them (thats why i have @handle_redirects section).
If I set the variable $proxytohost
above the location declaration as a.blahblah.com, then its working as expected.
But if i want to send that $proxytohost
as a dynamic argument to first request and then set it to a variable and then proxy_pass it, it doesnt work.
For example, if assume my nginx is running in localhost:8080
, this is what my expectation is
If i curl below
http://localhost:8080/?proxytohost=a.blahblah.com?authToken=aksdfkj
it should take me to a home page after using that token for authentication and redirecting to the home page,
http://localhost:8080/home
in this case /home
is a content thats served from https://a.blahblah.com/home
.
Best Answer
That will not work.
If I understand correctly you want to proxy to the same host on successive request. Nginx handles request independent of each other. So on the 2nd and 3rd request if
$arg_proxytohost
is absent and the default you provided is used.I suggest using Cookies for this. A little example below.
This needs to be in the http{} could be in conf.d in a separate file
next we have the locations that go in to the server{}
usage / explanation:
mapping
The mapping is used to avoid nasty if statements. If the cookie is set it is used as the hostname ( correct or not we don't check or care ). If it is not set (null/empty) we use the $host variable. Can change that to anything you want there.
first location
(http://localhost:8080/proxy/sethost/example.com) will set a cookie with the host set to example.com. Anything after /proxy/sethost/ will count as the host name!
second location
(http://localhost:8080/proxy) will now proxy to example.com. Added a resolver for dynamic lookups if not already somewhere else in the config. We need to set the Host header of the proxy request to the one requested and off we go.
Hope this helps. The redirect voodoo is another topic