We are migrating off an old api onto a new api. We will eventually update the front end code but for now are doing it in nginx.
#location /vapi {
# old api
location ~ ^/vapi/(?!(sites))/.+$ {
add_header Access-Control-Allow-Origin $cors_header;
access_log logs/vapi.proxy.log lfupstream;
error_log logs/vapi.error.log error;
rewrite ^/vapi/(.*)$ /$1 break;
proxy_pass http://vapi;
}
# new api
location ~ ^/vapi/sites/.+$ {
add_header Access-Control-Allow-Origin $cors_header;
access_log logs/vapi.portal.proxy.log lfupstream;
error_log logs/vapi.portal.error.log error;
rewrite ^(.*)$ /api/$1 break;
proxy_pass https://portal;
}
The old api is matching https://exa.valor.network/vapi/sites/SITE-NAME Have also tried:
location /vapi {
...
}
location /vapi/sites {
...
}
and
location /vapi {
...
}
location ~^/vapi/sites/.+$ {
...
}
Ref: Nginx location "not equal to" regex
Ref: Nginx location priority
Beside the fact I was on a test nginx and not the dev nginx Richard Smith's comment was a solution that worked. I had misread how nginx selected regex location as the longest had the highest priority. I ended up going with a regex for the new api and left the old api as is with a Prefix match thus the new api location takes priority if matched otherwise the old api gets the match.
Thanks to Richard Smith.
# new api
location ^~ /vapi/sites {
rewrite ^/(.*)$ /api/$1 break;
proxy_pass https://portal;
}
# old api
location /vapi {
rewrite ^/vapi/(.*)$ /$1 break;
proxy_pass http://$vapi_service;
}
Related
Navigate to localhost/app1 redirects me on localhost/login, expected - localhost/app1/login.
Is it possible to change the application redirect to the right place using nginx?
location /app1/ {
proxy_pass http://localhost:8080/;
}
Used Referer URL to make the right way redirection. The configs below:
nginx.conf - get application name from $http_referer
http {
map $http_referer $app {
~*//[a-z0-9_.-]+/([a-z0-9_.-]+) $1;
}...
}
root.conf - redirect wrong URLs to $app$uri
location / {
if ($http_referer != "") {
rewrite ^(.*)$ /$app$uri redirect;
}
app1.conf - important! The Referer header must be added!
location /app1/ {
proxy_pass http://localhost:8080/;
proxy_set_header Referer $http_referer;
...
}
I have my nginx conf like :
location ^~ /mount_points/mount_point1 {
internal;
alias /repos/mount_point_one;
}
location ^~ /to_proxy {
internal;
proxy_pass http://myproxy:5000;
}
When I request for 'http://localhost/mount_points/mount_point1/myfile.zip' I get "/repos/mount_point_one/myfile.zip" as expected.
While request for 'http://localhost/to_proxy/myfile2.html', I get "http://myproxy:5000/to_proxy/myfile2.html".
In the first case, the "/mount_points/mount_point1" part was removed, and in the second case, the "/to_proxy" part still there, I have to fake a "/to_proxy" address in the upstream server to find out this.
Did I missed something? If I just have to rewrite the url, how can I delete the "/to_proxy" part issue to the upstream server?
Thank you.
The proxy_pass directive can perform an aliasing function, but only if an optional URI is provided.
location ^~ /to_proxy/ {
internal;
proxy_pass http://myproxy:5000/;
}
To make the alias mapping work correctly, a trailing / is also added to the location parameter.
See this document for details.
If the trailing / on the location parameter causes problems, you can use a rewrite ... break instead:
location ^~ /to_proxy {
internal;
rewrite ^/to_proxy(?:/(.*))?$ /$1 break;
proxy_pass http://myproxy:5000;
}
I'm trying to load balance a web application through nginx, It works fine for all will my web application calls a service with sub-path.
for example it works
http://example.com/luna/
but not for
http://example.com/luna/sales
My nginx.conf
user nobody;
worker_processes auto;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream lunaups {
server myhostserver1.com:8080;
server myhostserver2.com:8080;
}
server {
listen 80;
server_name example.com;
proxy_pass_header Server;
location = / {
rewrite ^ http://example.com/luna redirect;
}
location /luna {
rewrite ^$/luna/(.*)/^ /$1 redirect;
proxy_pass http://lunaups;
#add_header X-Upstream $upstream_addr;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
my web application calls a service with additional subpath like /luna/sales fails to return response. What am i missing here?
It works if i remove one of my host server from upstream, But when I add second host on upstream it fails to return response.
Is my rewrite rule wrong or my configurations as whole is wrong?
There are four suffixes to the rewrite directive and they all have specific uses. See this document for details.
If you want the URI / to be mapped to /luna without changing the URL in the browser, you would use an internal rewrite with rewrite ... last. For example:
location = / {
rewrite ^ /luna last;
}
In the location /luna block, you need to rewrite the URI before sending it to proxy_pass statement (without leaving the location block), which requires a rewrite ... break. For example:
location /luna {
rewrite ^/luna(/.*)$ $1 break;
rewrite ^ / break;
proxy_pass http://lunaups;
}
The first rewrite changes any URI with a sub-path, and the second rewrite handles the URI without a sub-path.
See this useful resource on regular expressions.
A proxy app proxies to other apps with some regex in the location blocks of the nginx.conf. For example to a signup app called proxy-signup-app.
This works, but it has 3 location blocks:
location ~* ^/signup/(.*)/$ {
proxy_pass https://proxy-signup-app.herokuapp.com/?proxy_regex=$1;
}
location ~* ^/signup/(.*)$ {
proxy_pass https://proxy-signup-app.herokuapp.com/?proxy_regex=$1;
}
location ~* ^/signup$ {
proxy_pass https://proxy-signup-app.herokuapp.com/?proxy_regex=$1;
}
It should proxy
/signup
/signup/
/signup/rainyday
/signup/rainyday/
Where the proxy app would receive on proxy_regex:
$1 = ''
$1 = ''
$1 = 'rainyday'
$1 = 'rainyday' (not /rainyday/, rainyday/ or /rainyday)
It should not redirect
/signups
How to merge these location blocks into one?
not sure if it's the best way, but it should work
location ~* ^/signup(/(.*?)/?|)$ {
proxy_pass https://proxy-signup-app.herokuapp.com/?proxy_regex=$2;
}
I have written the following rule in a nginx server block:
location /s/sport(/)$ {
if ($args ~ country){
rewrite ^(.*) /s/sport/country/$arg_country? break;
}
}
The goal here is to transform legacy URLs such as http://example.com/rankings/soccer?country=de to http://example.com/rankings/soccer/country/de. This could of course be implemented in the app itself, but we need to do it before hitting the app for performance reasons; these URLs break our caching strategy.
The trouble is when this rule is applied, the following URL formats start to 404:
/s/sport
/s/sport?country={iso_code}
/s/sport/country/{iso_code}
nginx reports that the request failed (2: No such file or directory) which leads me to believe that it is now looking for a physical file with that name instead of passing the path to the app.
How do I fix the rule?
EDIT: Here's the full server config I'm trying to add on to:
server {
listen *:80;
server_name example.com;
passenger_enabled on;
access_log /path/to/app/logs/access.log main;
error_log /path/to/app/logs/error.log error;
root /path/to/app/current/public;
location ~* \.(ico|css|js|gif|jp?g|png|swf)(\?[0-9]+)?$ {
expires max;
break;
}
if (-f $document_root/maintenance.html) {
return 503;
}
error_page 503 #maintenance;
location #maintenance {
rewrite ^(.*)$ /maintenance.html break;
}
}