Conditionally make Nginx redirects to index.html - redirect

how to redirect to index.html for all the url except when the url has one particular QueryString?
For example:
Redirect all other url with Query strings to index.html except when it has ngsw-cache-bust
example.com/ngsw.json?ngsw-cache-bust=0.24039143891136616
i tried the following code
server {
index index.html;
root /dist;
listen 80;
location / {
try_files $uri$args $uri$args/ /index.html;
}
}
what am i missing?

Perhaps you could try something like this
server {
index index.html;
root /dist;
listen 80;
location / {
if($arg_ngsw-cache-bust == "") {
rewrite ^(.*)$ /index.html last;
}
}
}

Related

How can I make multi language config in Nginx?

I have following Nginx config default.conf:
map $http_accept_language $browser_lang {
default en;
~ru ru;
}
map $cookie_lang $lang {
default $browser_lang;
~en en;
~ru ru;
}
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/log/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
How can I do following:
1) Pass all /* requests to /en/* or /ru/* depending of language?
2) Pass all /en/* to /usr/share/nginx/html/<request>?lang=en and /ru/* to /usr/share/nginx/html/<request>?lang=ru?
3) If language is not en and ru path to all /* requests to /en/*?
You need to apply two separate location blocks for root url and for your language sections like so:
location = / {
rewrite ^ $scheme://$host/$lang$uri$is_args$args break;
}
location ~ '^/(?<lang_code>[\w-]{2})' {
rewrite ^/(?<lang_code>[\w-]{2})/(.*)$ /$1?lang=$lang_code last;
...
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
...
}
First location block answers to you questions 1) and 3) where the root url will be rewritten with your $lang variable in it that comes from map section and the last one defines that you will be using en language as default.
Second location block is for your questions 2) where you accept your language param as two-char path and then rewrite your url to suit your needs.
This code may not be 100% working, but it should give you an idea.
UPDATE
Well, actually you can do this in one single pass:
location / {
if ($uri !~ '^/([a-z]{2})(/.*)?$') {
rewrite ^ $scheme://$host/$lang$uri permanent;
rewrite ^/([a-z]{2})(/.*)?$ /$2?lang=$1;
}
...
}

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 redirect to URL with rand key using nginx

How redirect from main page url.
For example
site.ru
to
site.ru/?rnd=[random key]
using nginx.
My config:
server {
listen 1.1.1.1:80;
server_name dev.site.ru;
root /home/deploy/htdocs/dev.site.ru/current/dist;
location / {
try_files $uri /index.html;
}
}

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

domain to www.domain redirection

I have an nginx server behind varnish and I am trying to do a domain to www.domain redirection .
I tried using these rules on nginx
rewrite ^(.*) http://www.domain.com$1 permanent;
return 301 ^ $scheme://www.domain.com$request_uri;
return 301 http://www.domain.com$request_uri;
But I get an error in chrome as website running into a redirection loop.
As the about solution did not work I tried an alternative writing rules in varnish
sub vcl_recv {
// ...
if ( req.http.host == "domain.com" ) {
error 750 "http://www." + req.http.host + req.url;
}
// ...
}
sub vcl_error {
// ...
if (obj.status == 750) {
set obj.http.Location = obj.response;
# Set HTTP 301 for permanent redirect
set obj.status = 301;
return(deliver);
}
// ...
}
I am using varnish 4 and I get an error that varnish can't compile the code.
Message from VCC-compiler:
Expected an action, 'if', '{' or '}'
('input' Line 29 Pos 3)
error 750 regsub(req.http.host, "^www\.(.*)", "http://\1");
--#####------------------------------------------------------------------------------------------------------------------------
Could some one please help me in fixing this?
My server block is a follows:
server {
listen 127.0.0.1:8080;
root /home/webadmin/html/livesite;
index index.php index.html index.htm;
server_name www.domain.com;
# rewrite ^(.*) http://www.domain.com$1 permanent;
# return 301 ^ $scheme://www.domain.com$request_uri;
# return 301 http://www.domain.com$request_uri;
location / {
try_files $uri $uri/ /index.php?q=$uri&$args;
}
error_page 404 403 /error/eror.html;
location = /error/error.html {
root /home/webadmin/html/livesite;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /home/webadmin/html/livesite;
}
#pass the PHP scripts to FastCGI server listening on 127.0.0.1:9$
location ~ \.php$ {
#fastcgi_pass 127.0.0.1:9000;
# With php5-fpm:
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
}
This would be a correct way to do it while preserving the uri and the query string,
return 301 $scheme://www.domain.com$request_uri$is_args$query_string;
The problem isn't in this part, the problem is where you are redirecting to, probably redirecting to another locations that also does another redirect, I would guess you don't have another server block to handle the www server separately, so you keep redirecting to the same place over and over, wouldn't know for sure till you post the rest of the config.
EDIT:
The issue like I said is that you are redirecting the www to the www server, to avoid that you should create a new server that isn't with the www to do the redirection
server { # the redirecting server
listen 8080; # according to your config
server_name domain.com; #without www
return 301 $scheme://www.domain.com$request_uri$is_args$query_string;
}
server { # the actual serving server
listen 8080;
server_name www.domain.com;
# the rest of your actual settings
}
Use varnish for this instead, and skip the apache rewrites.
This example is to always redirect to https, but the semantics is the same..
In sub vcl_recv:
if ( req.http.host ~ "^(?i)domain.com" )
{
set req.http.X-Redir-Url = "https://domain.com" + req.url;
error 750 req.http.x-Redir-Url;
}
and then in sub vcl_error:
if (obj.status == 750) {
set obj.http.Location = obj.response;
set obj.status = 302;
return (deliver);
}