rewrite rule nginx - nginx

Can someone help me for my nginx rewrite rule. I have the problem like this
if file not found in www.abc.com/name_dir/* it will redirect to www.abc.com/name_dir/index.php .
for example :
not found in www.abc.com/xxx/* redirect to www.abc.com/xxx/index.php
not found in www.abc.com/yyy/* redirect to www.abc.com/yyy/index.php
not found in www.abc.com/zzz/* redirect to www.abc.com/zzz/index.php
not found in www.abc.com/kk/* redirect to www.abc.com/kkk/index.php
...
the problem i have thousand of name_dir. I have nginx.conf like this
if (-f $request_filename) {
break;
}
if (-d $request_filename) {
rewrite (^.+$) $1/
break;
}
if (!-e $request_filename) {
rewrite ^/xxx/(.*)$ /xxx/index.php?$1 last;
rewrite ^.+?(/.*\.php)$ $1 last;
}
In configuration above only redirect name_dir xxx. How rewrite rule to redirect all directory ?
Thank for your help

You want to use try_files to check for the existence of files instead of if statements here (because If's are Evil in Nginx).
To to a single directory, it would be like:
location /xxx/{
try_files $uri $uri/ /xxx/index.php;
index index.php
}
What this does is try the uri as a file first. If that doesn't work, it'll try as a directory. If neither work, it'll default to index.php of /xxx/. The extra index line is to keep it from showing a blank page if you go directly to whatever.com/xxx
Using regex, we can expand this rule to work with more than one directory:
location ~* ^(/.*)/{
try_files $uri $uri/ $1/index.php?$uri&$args;
index index.php
}
This should grab the full directory structure and rout it to the appropriate index.
abc.com/yyy/nonexistant.php ==> abc.com/yyy/index.php
abc.com/yyy/zzz/nonexistant.php ==> abc.com/yyy/zzz/index.php
If you only wanted the second example to go to yyy/index.php, use this regex in the location instead:
^(/.*?)/

Related

How to add prefix to html file name in nginx?

I have a front-end folder. For example, there is an index.html file and its German copy, de_index.html. For any html file, there is a version with the de_ prefix.
I want to make it so that, for example, when a user requests an index.html page and they have the lang=de cookie, nginx should return de_index.html. And for example, if the user requests about.html, then the server will give him de_about.html.
To begin with, I decided to try to simply replace all *.html files with their de_ version. And added the following block to the nginx configuration.
location ~ \.(html|htm)$ {
if ($uri !~ \/de_(\w)*.(htm|html)$) {
rewrite "(?<=\/)(\w*).(html|htm)$" de_$1.$2 break;
}
}
location / {
if (!-e $request_filename){
rewrite ^(.*)$ /index.html break;
}
try_files $uri $uri/ /index.php?$args;
}
The purpose of the first block is:
If the location has .htm or .html at the end
If the $uri file does not have the de_ prefix yet
Then change $uri to the same one, just add the de_ prefix to the file name.
But maybe I did something wrong or I don’t understand the meaning of rewrite, because I get a 404 error.

Silly nginx rewrite issue - infinate loop

I'm totally baffled with this one. Its probably something silly, and I'm missing it after along day! Anyway, I have this rewrite rule setup in my nginx config for the site:
location / {
root /srv/www/site.co.uk/www;
index index.html index.htm index.php;
rewrite ^/(.*)/index.html$ http://site.co.uk/$1/ permanent;
rewrite ^/index.html$ http://site.co.uk/ permanent;
}
When I go to:
http://www.example.com/index.html
http://www.example.com/foo/index.html
..then it correctly sends to:
http://www.example.com/
http://www.example.com/foo/
If I comment those 2 rewrite rules out, restart nginx, then retry... the page loads fine!
Can anyone see where I'm going wrong? Maybe I'm just being blind!
You have constructed a rewrite loop.
The index directive effectively generates an internal rewrite to /index.html whenever a URL with a trailing / is presented.
One way to break the loop is to only apply your rewrite rules when the external URL contains index.html. The variable $request_uri contains the external URL and can be tested using an if directive. See this caution regarding if.
if ($request_uri ~* "/index\.html(?|$)") {
rewrite ^(.*/)index\.html$ $scheme://$server_name$1 permanent;
}
location / {
root /srv/www/site.co.uk/www;
index index.html index.htm index.php;
}

nginx rewrite with try_files 403

I have a webserver with /usercp/ and usercp.php. I'm using tryfiles and re-write to see if file.php exists do file, otherwise goto /file/ (in my case file = usercp)
Here is my nginx conf.
location / {
try_files $uri $uri/ #extension-php;
}
location #extension-php {
rewrite ^(.*)$ $1.php last;
}
This also makes site.com/usercp/ give a 403 error. Any ideas?
The problem is that you are prioritizing the folder indexing over the php file if you want the opposite I recommend not to use the autoindex on because it exposes the contents of your folder and swap the last 2 items in the try_files, try this
location / {
try_files $uri $uri.php $uri/;
}
PS: $uri/ will always return 403 if it doesn't contain the index file specified in index because by default it forbids folder listing, you should either put the index file if that's what you intend to do, or just remove the whole $uri/ from the try_files so that it would return 404 instead of 403
http://nginx.org/r/try_files
What it does is simply checks the existence of files, and then serves the file that exists.
You claim /usercp/ exists. As such, that's what it'll try to serve. But you probably don't have autoindex on, hence, directory listing is disallowed — 403 Forbidden.

nginx rewrite nice urls with homemade CMS

I have a home-made CMS, serving a site which I inherited. I'm not really familiar with nginx rewrite rules, although I could set up tiny URLs. Here is my relevant part of the configuration:
*location / {
index index.php index.html;
root /var/www/www.valami.hu;
try_files $uri $uri/ #seo;
}
location #seo {
rewrite ^/([a-z]+)$ /index.php?oldal=$1 last;
break;
}*
The problem is that the site has a blog which is located on blogspot.com and the stuff from the blog is taken from there. So what I need help with is a rule for this sort of URL:
http://www.valami.hu/index.php?oldal=blog&options=2012/01/some-title-here.html
So, it would be fine like:
http://www.valami.hu/blog/2012/01/some-title-here
The most important is the first rule should be work also as it is more frequently used.
This is actually trivial. Watch and learn!
location / {
try_files $uri $uri/ #site;
}
location #site {
rewrite ^/blog/(.+)$ /index.php?oldal=blog&options=$1 last;
rewrite ^(.+)$ /index.php?oldal=$1 last;
}
The order makes all the difference. You can also do it by removing the last flag and redirecting to /blog with the options query string parameter explicitely set. No if is needed.
well seems we only have 2 cases, the /blog and the non /blog, I'd write 2 location blocks
location ~ ^/blog/(.*) {
try_files $uri /index.php?oldal=blog&options=$1;
}
location ~ /(.*) {
try_files $uri /index.php?oldal=$1;
}
I would have used just / and $request_uri in the second location but that would put a preceeding / in olda1, if that wouldn't matter with you then i'd prefer that method, cause it doesn't involve regex.
About index index.php index.html; and root /var/www/www.valami.hu;, it's better if you move them to the server block instead of the location block, if possible of course.

Look for file in subfolders in nginx

I am changing the file structure.
Some of the urls, that were previously available at root level of the site are now moved to a subfolder.
So I have an $uri.
I try_files $uri #check_subfolder;
If the file (normal .html file) still exists at the root level, or it's url is written properly, then try_files $uri works as it should.
But if the file is moved to a subfolder, then I enter
location #check_subfolder {
}
And if here I just make a redirection rewrite ^(.*) $scheme://$host/articles$1 permanent; then everything is still perfect.
But I want first to check if the $uri really exist in the /articles subfolder or not.
So I do
location #check_subfolder {
if (-f "/articles${uri}") {
rewrite ^(.*) $scheme://$host/articles$1 permanent;
}
}
It just falls down to error 404. Redirection doesn't happen. Without the if redirection works. So obviously the problem in the way how I formulate the condition.
if (-f "/articles${uri}") doesn't work.
if (-f "/articles${request_filename}") doesn't work.
if (-f "/articles/${request_filename}") doesn't work.
if (-f /articles/$request_filename) doesn't work.
if (-f /articles/$uri) doesn't work.
I obviously write wrong concatenation.
My answer is that I didn't think that -f looks for file in filesystem, not for a web-page, so I had to include $document_root.
So now it works like
location #check_subfolders {
if (-f $document_root/articles/$uri ) {
rewrite ^(.*) $scheme://$host:8090/articles$1 permanent;
}
}

Resources