How to set the proxy_pass to get the desired address? - nginx

I have been struggling with setting up Nginx for our use case.
When I set up Nginx with the following config:
location /dep-core {
proxy_pass http://node-server:7070/;
}
and call the server with following endpoint:
<END-POINT>/dep-core/api/login
the call is redirected to
<ADDRESS-AFTER-RESOLUTION>//api/login
with two leading //s.
and when I remove the trailing / in proxy_pass after 7070:
location /dep-core {
proxy_pass http://node-server:7070;
}
the call is redirected to
<ADDRESS-AFTER-RESOLUTION>/dep-core/api/login
with leading /dep-core appended.
I want my call to redirect my call to:
<ADDRESS-AFTER-RESOLUTION>/api/login
What would be the standard way to achieve this??

For correct translation from /dep-core/foo to /foo, the location directive requires a trailing /.
For example:
location /dep-core/ {
proxy_pass http://node-server:7070/;
}
See this document for details.
To translate /dep-core to /, you can use a rewrite...break with a clever regular expression in the second block of your question. But a simple solution is to add an exact match location for that single edge case.
For example:
location = /dep-core {
rewrite ^ $uri/ last;
}
location /dep-core/ {
proxy_pass http://node-server:7070/;
}

Related

how in nginx to redirect location to any host received urls?

I need to get the host address from the request and redirect to another host with the rewritten address, but in all possible ways I failed
Here's an example (one of the attempts):
location / {
proxy_pass http://...;
...
}
location /service/(.*)$/ {
rewrite /service/$1/(.*)$ /$2 break;
proxy_pass http://$1.localhost:8080/;
...
}
Works only if hardcoded:
location /service/hostaname/ {
rewrite /service/hostaname/(.*)$ /$1 break;
proxy_pass http://hostaname.localhost:8080/;
...
}
But this is not a suitable solution for me
Help meeeeeee, thanks!
Your location syntax is invalid, as it is missing the regular expression operator. The rewrite statement contains an invalid regular expression.
You do not need the rewrite statement as you can extract the parts of the URI from the location statement.
For example:
location ~ ^/service/([^/]+)/(.*)$ {
proxy_pass http://$1.localhost:8080/$2;
}
You may need to define a resolver statement as the proxy_pass contains variables. See this document for details.

nginx proxy_pass with new URI does not work if host is varaible

I am trying to use variable to set the hostname in a proxy_pass, but once I try that, the path after the location is ignored.
If I try and get localhost:8001/dirA/x/y/z.html. The following returns the file from http://server1:8888/dirB/dirC/x/y/z.html. This is what I expect to happen.
location ^~ /dirA/ {
proxy_pass http://server1:8888/dirB/dirC/;
But if I try the following config which is just using a variable for hostname... and try and get localhost:8001/dirA/x/y/z.html
location ^~ /dirA/ {
set $endpoint server1;
proxy_pass http://$endpoint:8888/dirB/dirC/;
I get http://server1:8888/dirB/dirC/index.html returned instead.
That's just how proxy_pass works. If you use a variable in the value, you need to provide the entire URI. See this document for details;
You could use a regular expression location. For example:
location ~ ^/dirA/(.*)$ {
set $endpoint server1;
proxy_pass http://$endpoint:8888/dirB/dirC/$1;
}
Note that the order of regular expression locations is significant. See this document for details.
Alternatively, a rewrite...break should also work.
location ^~ /dirA/ {
set $endpoint server1;
rewrite ^/dirA/(.*)$ /dirB/dirC/$1 break;
proxy_pass http://$endpoint:8888;
}

nginx server: how to remove first directory from URL

Can anybody please help me to remove first directory name from URL?
My Image location is _data/hotel/3/15377/hotel_image.jpg
But Image path gets changed due to relative URL in code and it become to something like this.
example.com/france/_data/hotel/3/15377/hotel_image.jpg
example.com/usa/_data/hotel/3/15377/hotel_image.jpg
example.com/india/_data/hotel/3/15377/hotel_image.jpg
is their any possibilities to remove dynamic country name from above URL
If you want to rewrite only this particular URL, you can use this location block in your config:
location ~ /[a-z]+/_data/hotel/3/15377/hotel_image.jpg {
try_files /_data/hotel/3/15377/hotel_image.jpg;
}
If you want to rewrite all URLs which lead to /<country>/_data/..., you can use:
location ~ /[a-z]+/_data/(.+) {
try_files /_data/$1;
}
or for stricter URL checking:
location ~ /(?:france|usa|india)/_data/(.+) {
try_files /_data/$1;
}
#Ivan Shatsky's answer is great for files but also if we want to redirect a general url is better if you use the rewrite directive.
Depending where you define the rewrite directive you have two ways to implement it:
A. In the server context
server {
...
rewrite ^/[a-z]+/_data/(.+)$ /_data/$1 last;
...
}
B. In the location context
location ~ /[a-z]+/_data/(.+) {
rewrite ^/[a-z]+/_data/(.+)$ /_data/$1 break;
proxy_pass http://backend;
}
Teo, why did you change the flag to break?* Because, if this directive is put inside of a location context, the last flag might make nginx to run 10 cycles and return the 500 error.
Note:
Remember not add / at the end of the proxy_pass directive. This example wont work:
...
proxy_pass http://backend/;
...

how to get url parameter and pass to proxy_pass using nginx

I need to get the parameter from an URL, for example, abc=MY_STRING:
https://my-address/test?abc=MY_STRING
And at the reverse proxy (my-address), is configured like this:
location /test?(.*) {
proxy_pass http://local-server:1234/test?$args
}
but it is not working.
I tried another configuration:
location /test?(.*) {
proxy_pass http://local-server:1234/test?$1
}
but not worked too.
You cannot match the query string part of the URI with a location or rewrite statement, as it is not part of the normalized URI.
But you don't need to. The URI (complete with query string) will be passed upstream
unless you redirect it using a rewrite or try_files statement.
For example:
location /test {
proxy_pass http://localhost:1234;
}
The URI /test?abc=MY_STRING will match the location and be passed to localhost:1234 exactly the same. See this document for more.

"proxy_pass" cannot have URI part in location given by regular expression inside "if"

I want to match request parameter and direct to my gateway, I do like this
location /app/share {
if ($args ~ action=encode) {
proxy_pass http://192.168.1.249:11201/openmallservice/corp/app/share/;
}
}
what's wrong?
Check this answer.
/some-url/ part is not allowed in proxy_pass in if statement and regular expressions like location ~ whatever
# add uri here and break to stop searching another locations
rewrite ^(.*)$ /your-path$1 break;
# proxy without uri
proxy_pass http://111.222.33.44:8000;

Resources