Reputation: 2707
I am tearing my hair out on this one while configuring some rewrite rules on nginx. I am running nginx 1.2.1 on a Debian Wheezy machine.
Considering the following tree:
/
├── index.html
├── folder/
│ └── index.html
└── file.html
I would like those files to be served by nginx so that there would be no need to specify any .html
in the URL, and that any call to a folder/index.html
is rewritten in folder/
, any call to file.html
is rewritten in index
.
Here is the formal version of this description. Request examples are on the left and the corresponding response I am trying to get are on the right (HTTP code 301 + redirected location or HTTP code 200 + file to be displayed):
1. http://example.com/ -> 200 (/index.html)
2. http://example.com/index.html -> 301 http://example.com/
3. http://example.com/index -> 301 http://example.com/
4. http://example.com/file -> 200 (/file.html)
5. http://example.com/file.html -> 301 http://example.com/file
6. http://example.com/folder/ -> 200 (/folder/index.html)
7. http://example.com/folder -> 301 http://example.com/folder/
8. http://example.com/folder/index.html -> 301 http://example.com/folder/
9. http://example.com/folder/index -> 301 http://example.com/folder/
10. http://example.com/foobar -> 404
So far, my closest attempt is the following configuration of /etc/nginx/sites-enabled/example.com
:
server {
server_name example.com;
root /var/www/example.com/public_html;
rewrite ^(.*/)index(\.html)*$ $1 permanent; # Applies to 2, 3, 8, 9
rewrite ^(/.+)\.html$ $1 permanent; # Applies to 5
try_files $uri $uri.html "${uri}index.html" =404; # Handles 1, 4, 6, 10
}
As you can see, case 7
is missing. For now, I got:
7'. http://example.com/folder -> 404
I also managed to have:
7''. http://example.com/folder -> 200 (/folder/index.html)
But it is definitely something I don't want SEO wise (among others), as 2 different URLs (with and without trailing slash) returns the same content.
Every configuration did not pass all of my test cases.
Note that when I simply disable the 2 rewrite
s and the try_files
, 7
applies as expected (as well as 1
, 6
, 10
but not the other ones), the redirection is valid by default. I don't understand how and where this redirection rule, so here are my formal questions: how can I make this redirection re-appear and, by extension, how can I have my 10 test cases properly working?
Thanks a lot, and I really mean it :)
PS: I try my best, but of course if there is anything unclear, do not hesitate to ask for clarification!
Upvotes: 2
Views: 2595
Reputation: 42799
You got a couple of things wrong, first you won't do any 301 redirects, redirects are using if you are accessing something, but then you want it to go to something else, like for example if we're doing an upgrade.
http://example.com/index.html =>redirects to=> http://example.com/maintenance.html
What you need is a changing the format of something to something else, your rewrites are swapped by the way, rewrites work like this
rewrite [what to match] [what to do with it]
Your rewrites are saying when I get a URL to /index.html
it will redirect to /index
which then will give you a 404
because you don't have a real file called /index
I'd like to do it with try_files
server {
server_name example.com www.example.com;
root /my/root/path;
location / {
try_files $uri $uri/ $uri.html;
}
Try this and tell me how it goes.
Upvotes: 2