1

Scenario

I have a website with the following structure:

/index.html
/about/index.html
/contact/index.php
/contact/send_email.php

I would have liked to make the URL's cleaner, so I would be the equivalent structure with:

/ => /index.html
/about/ => /about/index.html
/contact/ => /contact/index.html
/contact/send_email.php => /contact/send_email.php

Basically an Nginx configuration that removes all index.html or index.php file names from the URI.

My Attempted Configuration

server {
    listen 80;
    root /home/www/mysite;
    server_name www.mysite.com;        

    location ^~* /[a-z]+/index\.(html|php)$ {
        rewrite ^(/[a-z]+/)index\.(html|php)$ http://www.mysite.com$1? permanent;
    }

    try_files $uri $uriindex.html $uriindex.php =404;

    location ~ \.php$ {
        include /etc/nginx/fastcgi_params;
        fastcgi_pass unix:/var/run/php5.sock
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}

The Problem

In short - it doesn't work. When I go to /about/index.html it should permanently redirect to /about/ but it just stays on /about/index.html. I have tested the regular expressions and they seem to be fine - i.e. the capturing group defined in the rewrite works.

1 Answer 1

2

Which version of nginx are you using?

I've tried your configuration with nginx 1.4.2 and it detected a few syntax errors:

  1. invalid location modifier "^~*" in your first location directive - I changed it to ~
  2. unknown "uriindex" variable in your try_files directive - I changed both $uriindex.html and $uriindex.php to $uri/index.html and $uri/index.php

At this point I believe the setup does most of what you want:

  1. Going to www.mysite.com/about/index.html you're redirected to www.mysite.com/about/
  2. Going to www.mysite.com/contact/index.html you're redirected to www.mysite.com/contact/
  3. Going to www.mysite.com/contact/send_email.php no redirect takes place

Now for www.mysite.com/index.html to redirect to www.mysite.com/, you'll need another "location" directive and rewrite rule:

location ~ /index\.html$ {
    rewrite ^/index\.html$ http://www.mysite.com permanent;
}

And as for www.mysite.com/contact/ to be executed with PHP-FPM as www.mysite.com/contact/index.php script, you'll also need a specific location directive. The fastcgi_index index.php line here is really important:

location = /contact/ {
    include /etc/nginx/fastcgi_params;
    fastcgi_pass unix:/var/run/php5.sock
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}

Hope this helps :)

3
  • Thanks for the changes. I am running nginx version 1.1.19. My only problem now is when I try to go to /contact/index.php it downloads the PHP page instead of running it through PHP-FPM. The location ~\.php$ block doesn't seem to catch the $uri/index.php directive in try_files.
    – Hzmy
    Sep 17, 2013 at 15:07
  • location ~\.php$ doesn't catch /contact/index.php because its rewritten to /contact/. You need one more location directive, I've updated the answer above to show this.
    – zygis
    Sep 17, 2013 at 16:24
  • I thought about doing this originally, but I would have to add a new location =/xxxx/ block for any directory with an index.php.
    – Hzmy
    Sep 18, 2013 at 14:44

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .