I'm trying to get the following pattern to work. I need to specify a dynamic path in my client side code to be able to switch to a few predefined hosts. I map these hosts by appending their alias to a /fwd/ url. The alias is mapped to the real server in nginx like this:
map $uri $repoUrl {
default invalid;
~^/fwd/foo/.* http://foo.domain.nl/;
~^/fwd/bar/.* http://bar.domain.nl/;
}
Then in the server config part I catch any url starting with fwd and apply the mapped alias value. The remaining part of the url, after the alias should be appended to the url as well.
location /fwd/(\w+)/(.*)$ {
add_header X-FwdHost "$repoUrl$2";
add_header Access-Control-Allow-Origin "*";
proxy_pass "$repoUrl$2";
proxy_redirect off;
access_log on;
}
If I test this with:
curl -i http://localhost:8080/fwd/foo/something/else
I get:
X-FwdHost: http://foo.domain.nl/
But when test the results from the regexp I get:
$1: foo
$2: something/else
So overall it seems to be working. The regex appears to be ok, but I can't get it to concatenate into one string? Any ideas or is there an easier/better way to accomplish the same?
[EDIT]
I found a possibly much easier way to do this, by using a query parameter named forward. First map the query parameter to a the right host:
map $arg_forward $repo_forward {
default http://invalid_repo_forward/;
foo http://foo.domain.nl/;
bar http://bar.domain.nl/;
}
Then use the parameter in the path to be forwarded:
location /fwd/ {
add_header X-FwdHost $repo_forward;
add_header Access-Control-Allow-Origin "*";
proxy_pass $repo_forward;
proxy_redirect off;
access_log on;
}
I would expect and url like:
http://localhost:8080/fwd/?forward=foo
To result in:
http://foo.domain.nl/
...but still this doesn't work. I get a 404 returned. What am I missing?
I eventually went back to the first approach, because it's not convenient to add a query parameter to a url for this. It makes the client logic unnecessary complex.
I found the solution to my first approach. The regex in the location statement was wrong. You need to capture the regex in variable names by using ? like this:
location ~ ^/fwd/(?<fwd_alias>\w+)/(?<fwd_path>.*)$
Then $fwd_alias will contain the alias like foo or bar. $fwd_path with contain the whole path after that.
To pass on the full path including optional query parameters you specify the proxy_pass as:
proxy_pass http://$repo_url$fwd_path$is_args$args;
That's it!
So now, including the mapping in the first example, and adding the resolver, it comes down to:
location ~ ^/fwd/(?<fwd_alias>\w+)/(?<fwd_path>.*)$ {
resolver 8.8.8.8;
add_header Access-Control-Allow-Origin "*";
proxy_pass http://$repo_url$fwd_path$is_args$args;
proxy_redirect off;
access_log on;
}
And a request with the following path:
http://localhost:8080/fwd/foo/something/else?with=query
maps to:
http://foo.domain.nl/something/else?with=query
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