Redirection in nginx - redirect

I'm very new to nginx and hit the wall configuring simple redirection.
Here is my very simple config trying redirection:
server {
listen 80 default_server;
set $mobile "false";
if ($http_user_agent ~* '(phone|droid)') {
set $mobile "true";
}
if ($mobile = true) {
return 301 http://X.X.X.X/mobile$request_uri;
}
location /mobile {
include uwsgi_params;
uwsgi_pass unix:/var/www/video_m/video.sock;
}
location / {
include uwsgi_params;
uwsgi_pass unix:/var/www/video/video.sock;
}
}
When go to site from desktop everything is ok and my request is going to uwsgi.
But from mobile device I get an error from browser ERR_TOO_MANY_REDIRECTS and request url looks like http://X.X.X.X/mobile/mobile/mobile/mobile/mobile/mobile/mobile/mobile
There is obviously something essential and possibly very simple piece that I missing. Please help me out.

You have created a loop. The first time it hits the if/return a /mobile prefix is added. Then the URI is presented again and it hits the same statement adding another /mobile prefix, and this continues to be repeated.
To break the loop, you need to protect the if/return within a path that is not taken once the /mobile prefix is added the first time.
Maybe:
server {
listen 80 default_server;
location /mobile {
include uwsgi_params;
uwsgi_pass unix:/var/www/video_m/video.sock;
}
location / {
if ($http_user_agent ~* '(phone|droid)') {
return 301 $scheme://$host/mobile$request_uri;
}
include uwsgi_params;
uwsgi_pass unix:/var/www/video/video.sock;
}
}

Related

why nginx proxy_pass to sub directory is not working?

I am trying to do a proxy_pass to a subdirectory http://ms.server.com:8085/ms. So whenever anyone hit on http://ms.example.com' it should be redirected tohttp://ms.example.com/ms`. I am trying to do that through below configuration
upstream example {
server ms.server.com:8085;
}
server {
server_name ms.example.com;
location / {
proxy_pass http://example/ms;
}
}
Now I am redirecting to "Nginx Test page".
proxy_pass is used to inform Nginx where to send proxied requests at a host level, and does not account for the URI.
What you want to use instead is a return statement, like so:
upstream example {
server ms.server.com:8085;
}
server {
server_name ms.example.com;
location = / {
return 301 http://ms.example.com/ms;
}
location / {
proxy_pass http://example;
}
}
This will redirect requests to the root URL of the server_name http://ms.example.com using a 301 redirect, and all other traffic will be passed through to the defined upstream.

Add slash to redirect if URL is not ending with slash in Nginx

I wanted to add a slash to a redirect URL because the target (Wordpress) also redirects if the url does not end with a slash. This would result in two redirects.
My current config doesn't seem to work
server {
listen 80;
server_name old.domain.com;
location ~ ^(.*)[/]$ {
return 302 https://new.domain.com/$request_uri;
}
location ~ ^(.*)[^/]$ {
return 302 https://new.domain.com/$request_uri/;
}
}
Try to put url with '/' before without '/', might it matching with first without slash and redirecting it
Try this
server {
listen 80;
server_name old.domain.com;
location ~ ^(.*)[/]$ {
return 302 https://new.domain.com/$request_uri/;
}
location ~ ^(.*)[^/]$ {
return 302 https://new.domain.com/$request_uri;
}

nginx conditional redirects rules

I have such a task:
http://www.realtyadvisorselite.com/homes-for-sale/skokie
to redirect permanently to
http://www.realtyadvisorselite.com/residential/homes-for-sale/skokie
another words add "residential" subfolder if it is missing from url
I have such server blocks in nginx.conf
server {
listen 80;
server_name realtyadvisorselite.com;
return 301 http://www.realtyadvisorselite.com$request_uri;
}
server {
listen 80;
server_name www.realtyadvisorselite.com;
location / {
proxy_pass http://repar;
}
}
Sorry, seems like a simple task but I cannot understand nginx regexp approach... Thank you!
You question implies that it is a single URL that requires redirection. So a simple option is to use an exact match location and a return statement:
location = /homes-for-sale/skokie {
return 301 /residential/homes-for-sale/skokie;
}
If you wanted all URIs that begin with /homes-for-sale to be prefixed with /residential, you could use a prefix location and a return statement:
location ^~ /homes-for-sale/ {
return 301 /residential$request_uri;
}
See this document for more.

Nginx Exclude a query string url from being redirected

I am currently redirecting my root domain to a subfolder. However I want to exclude a query string url which is used for an ajax call (www.example.com/?act=12). I am however unsure of how to do this in nginx.
This is my current nginx config file
server {
listen 80;
server_name example.com;
return 301 http://www.example.com$request_uri;
}
server {
listen 80;
server_name www.example.com;
root /var/www/example.com/public;
index index.php index.html;
location = / {
return 301 http://www.example.com/it/;
}
location / {
proxy_pass http://localhost:8080;
include /etc/nginx/proxy_params;
}
location ~* \.(js|css|jpg|jpeg|gif|png|svg|ico|pdf|html|htm)$ {
expires 30d;
}
location ~ /\.ht {
deny all;
}
}
Any help will be appreciated.
That can be achieved by using the evil if block.
The query string arguments are presented as variables with a $arg_ prefix. If you just need to test that act is set, try this:
location = / {
if ($arg_act) {
rewrite ^ /my/ajax/call last;
}
return 301 http://www.example.com/it/;
}
If you need to test for a specific value of $arg_act use the = operator.
See this document for details.

How to redirect a specific path to the same path without www in nginx

I've encountered an issue during server configuration: I require a 301 redirect from http://www.example.com to http://example.com just for one specific url alias - like /partners.
the expected output- http:// www.example.com/partners/stuff -> http:// example.com/partners/stuff.
I've tried adding the following code to the vhosts already:
server {
server_name http://www.example.com/partners;
return 301 $scheme://example.com/partners;
}
but vhosts gives me an error telling me this code isn't valid.
What's the correct way of implementing such rewrite?
server_name is for domain only. I can suggest you 2 solutions.
Copy configs between servers. This is the best solution recommended by nginx's author.
server {
server_name example.com;
include example.com.conf;
}
server {
server_name www.example.com;
include example.com.conf;
location /partners/ {
return 301 $scheme://example.com$request_uri;
}
}
Or using if. Bad solution due performance
server {
server_name .example.com;
...
location /partners/ {
if ($host = "www.example.com") {
return 301 $scheme://example.com$request_uri;
}
}
}
http://wiki.nginx.org/IfIsEvil
http://wiki.nginx.org/Pitfalls#Server_Name