Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nginx & Handling Files Without Extension

Tags:

nginx

I'm trying to get Nginx to handle php files without an extension (i.e. to handle http://localhost/sample the same way it would handle http://localhost/sample.php).

This is my site configuration:

server {
    listen 80 default_server;
    listen [::]:80 default_server ipv6only=on;

    server_name localhost;

    root /var/www;
    index index.html index.php;

    location ~ \.(hh|php)$ {
        fastcgi_keep_conn on;
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location / {
        try_files $uri $uri/ $uri.html @extensionless =404;
    }

    location @extensionless {
        rewrite ^(.*)$ $1.php last;
    }
}

As far as I know it should do the trick. However - it doesn't. Trying http://localhost/sample just gets me to a 404 page (whereas http://localhost/sample.php works fine).

When turning on debugging, I see the following in the logs:

2015/07/19 15:37:00 [debug] 4783#0: *1 http script var: "/sample"
2015/07/19 15:37:00 [debug] 4783#0: *1 trying to use file: "/sample" "/var/www/sample"
2015/07/19 15:37:00 [debug] 4783#0: *1 http script var: "/sample"
2015/07/19 15:37:00 [debug] 4783#0: *1 trying to use dir: "/sample" "/var/www/sample"
2015/07/19 15:37:00 [debug] 4783#0: *1 http script var: "/sample"
2015/07/19 15:37:00 [debug] 4783#0: *1 http script copy: ".html"
2015/07/19 15:37:00 [debug] 4783#0: *1 trying to use file: "/sample.html" "/var/www/sample.html"
2015/07/19 15:37:00 [debug] 4783#0: *1 trying to use file: "@extensionless" "/var/www@extensionless"
2015/07/19 15:37:00 [debug] 4783#0: *1 trying to use file: "=404" "/var/www=404"

Which is weird. It basically looks like @extensionless is treated as a plain filename (instead of a location leading to a rewrite of the URL).

What am I missing? :) Thanks!

like image 803
Assaf Hershko Avatar asked Jul 19 '15 14:07

Assaf Hershko


Video Answer


2 Answers

Just updating (in case anyone finds this useful) that I got it to work, eventually.

This is the configuration that did the trick:

server {
    listen 80;

    root /var/www;
    index index.html index.htm index.php;

    server_name localhost;

    location / {
        if (!-e $request_filename){
            rewrite ^(.*)$ /$1.php;
        }
        try_files $uri $uri/ =404;
    }

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}
like image 184
Assaf Hershko Avatar answered Sep 22 '22 07:09

Assaf Hershko


    try_files $uri $uri/ $uri.html @extensionless =404;

Yes, @extensionless is treated like a normal file, and that's because you've added an extra =404 after @extensionless within try_files -- the @extensionless part would only work as the last parameter as an internal redirect to another context.

If you want not only to support handing requests without .php, but to also strip .php from any requests, you might want to do the following:

location / {
    if (-e $request_filename.php){
        rewrite ^/(.*)$ /$1.php;
    }
}
location ~ \.php$ {
    if ($request_uri ~ ^/([^?]*)\.php(\?.*)?$) {
        return 302 /$1$2;
    }
    fastcgi_...
}
like image 31
cnst Avatar answered Sep 24 '22 07:09

cnst