location prefix matching nginx doesn't work with variables - nginx

Hi Earlier I was matching location prefix uri matching to get the redirection to website www.example.com/abc/ from www.example.com/bbb/abc(requested uri).
server {
location /bbb/ {
proxy_pass http://www.example.com/;
}
}
Earlier I was requesting on www.example.com/bbb/abc and getting redirected to www.example.com/abc
as I required
However now the problem is I've resolver and I'm also using variable. This is done to ensure that nginx starts even if one of the upstream services are down and it won't show the error of
[nginx] host upstream not found
server {
location /bbb/ {
resolver 127.0.0.11 valid=some secs;
set $example www.example.com
proxy_pass http://$example/;
}
}
Now that I'm using variable, I think url location prefix match is not working as I am sending request on www.example.com/bbb/abc , and it shows the nginx 404 not found.
Can anyone guide me how redirect properly with variable and resolver included.

Related

Removing location without removing the rest of the path

According to many old posts here and in other places on the internet, the following nginx configuration should proxy http://nginx-service/foo/bar to http://web.default.svc.cluster.local:8080/bar.
In other words, it should strip the /foo part in the path (the location matched) while appending the rest (/bar) when proxying it on.
That is not what I observe in practice; the full path is removed and / is proxied on.
How could I proxy this to the upstream service while keeping /bar?
You didn't add any config in your question but any of the following should work:
location /foo/ {
proxy_pass http://web.default.svc.cluster.local:8080/;
}
or
location /foo/bar {
proxy_pass http://web.default.svc.cluster.local:8080/bar;
}

Nginx server returns 308 status code when trying to proxy pass to external hosted service

I am trying to proxy pass one of my nginx server endpoint to an external service that intern redirects calls to another service with in it.
my config looks like below
location = /proxy/live {
proxy_pass <externalservice ip:port>/live;
proxy_pass_request_body on;
}
with in the external service /live endpoint redirects to another service that is unknown to my nginx server.
with the above configuration I am getting 308 error code (redirection issue). while trying to access /proxy/live endpoint. How can i resolve this issue and get the proxy_pass call through external service up till the end service.
If the URL argument of the proxy_pass directive ends with a trailing slash - then the location path is not appended to this URL. However, if the URL does not end with a trailing slash - then the location path is appended to this URL when passing to the upstream.
This is not very clear from the nginX documentation where they simply refer to the proxy_pass as being either specified with an URI or without an URI:
If the proxy_pass directive is specified with a URI, then when a request is passed to the server, the part of a normalized request URI matching the location is replaced by a URI specified in the directive:
location /name/ {
proxy_pass http://127.0.0.1/remote/;
}
If proxy_pass is specified without a URI, the request URI is passed to the server in the same form as sent by a client when the original request is processed, or the full normalized request URI is passed when processing the changed URI:
location /some/path/ {
proxy_pass http://127.0.0.1;
}

Routing in nginx URI with same prefix as another URI

Currently trying to use Nginx as a proxy and finding some difficulties with routes having another URI as a prefix. Example :
location /api/route/to/specific/application {
proxy_pass http://proxying.to/site/A;
}
location /api {
proxy_pass http://proxying.to/another/site/B;
}
When visiting http://mysite.io/api/route/to/specific/application, I get a 404 from Nginx while when I visit http://proxying.to/site/A directly I get the expected page.
Any idea how I can make it work ?
Thanks

nginx variables (cname) in proxy_pass

i am trying dynamically set a the proxy_pass destination where the variable would be the cname of the original request.
what i have right now is:
server {
listen 8888;
server_name (.*).domain.com;
location / {
proxy_pass http://$1.otherdomain.com;
proxy_set_header Host $1.otherdomain.com;
but unfortunately this ends up in a 502 bad gateway.
nothing really works when using a variable in proxy_pass and proxy_set_header.
i also tried to use (?<cname>.+) or (?P<cname>.+) in the server name and $cname as the variable.
what is wrong and why does it end up in a 502?
To use regex in server name, you need to prepend the name with a tilde "~"
server_name ~(.*).domain.com;
[UPDATE]
Tried it and it successfully set the value in $1. But still get 502 and my nginx error log shows
no resolver defined to resolve xyz.otherdomain.com
even though I point that name to my localhost in my /etc/hosts file.
Find this article that explains this issue well. Basically in this special case (variable in upstream domain name), you need to use the "resolver" directive to point to a dns server (e.g., 8.8.8.8 from google dns server) that can resolve this dynamic domain name.
resolver 8.8.8.8;
It works in my test with a public upstream domain name. If you upstream domain names are local, you need to set up a local dns server for them.
The server name for proxy_pass using variables, will be a special situation.
proxy_pass http://$1.otherdomain.com;
In this case, the server name is searched among the described server groups, and, if not found, is determined using a resolver.
If you do not like to use resolver. You can use below like hosts file.
upstream www1.otherdomain.com { server 10.x.x.1; }
upstream www2.otherdomain.com { server 10.x.x.2; }

NGINX Location troubles

I have django and flask applications running on the same machine through different ports:
Django runs on server:8088
Flask runs on server:666
In NGINX.conf I have the following code:
location / {
proxy_pass http://127.0.0.1:8088;
}
location ^/server2 {
proxy_pass http://127.0.0.1:666;
}
Django has been running for over a year successfully with this set up, where as flask is a new addition. Any time I try to access one of the Flask urls I either get a "this url does not exist on this server" error, or on occasion a 500 error (when i've been fiddling).
If I write location information for a specific flask url like this:
location /server2/splash {
proxy_pass http://127.0.0.1:666/splash;
}
It works, but I obviously don't want to write individual location information for each and every URL in the flask application.
I've gone through many of the existing Nginx location posts on stackoverflow but I've not been able to get it working. Any ideas?
Thanks!
EDIT
this is an example of what I'm trying to achieve, but rather than an individual mapping for each URL, I want a single mapping that covers all URLs:
location /server2{
proxy_pass http://127.0.0.1:666/splash;
}
location /server2/split {
proxy_pass http://127.0.0.1:666/split;
}
location /server2/export {
proxy_pass http://127.0.0.1:666/export;
}
location /server2/import {
proxy_pass http://127.0.0.1:666/import;
}
Why do you use the ^ sign? Just remove it I think it will work:
location /server2 {
proxy_pass http://127.0.0.1:666;
}
Note that when you use location /server2 the server2 is still being passed to your flask application.
In this case Nginx is doing the following:
server.com/server2 => http://127.0.0.1:666/server2
server.com/server2/splash => http://127.0.0.1:666/server2/splash
In this case location is not doing a rewrite. Always check /var/log/nginx (or wherever your logs are located) to check the requests done by the browser and what Nginx looks for after the rules for your site are processed.
What you probably want is to set an upstream directive:
upstream flask_server {
server 127.0.0.1:666;
}
server {
...
location /server2 {
proxy_pass http://flask_server;
}
}

Resources