Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NGINX try_files with name as the last word in the $uri

I've got an nginx on my server and I am trying to get it to open the file '/config/www/pp1/index.php' for address https://example.com/pp1 and '/config/www/interpreter/index.html' for https://example.com/interpreter. Furthermore all things like https://example.com/interpreter/res/docs should fire up '/config/www/interpreter/res/docs.html'. I have made many attempts. Currently my default config file in /site-confs looks like this:

server {
        listen 80;
        listen 443 ssl http2;
        server_name kni.mini.pw.edu.pl;

        # Path for SSL config/key/certificate
        ssl_certificate /config/keys/cert.crt;
        ssl_certificate_key /config/keys/cert.key;

        location / {
                proxy_read_timeout    90;
                proxy_connect_timeout 90;
                proxy_redirect        off;
                proxy_pass http://kni_website;
                proxy_set_header      X-Real-IP $remote_addr;
                proxy_set_header      X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header      Host $host;
        }

         location /pp1 {
                root /config/www;
                index index.html index.htm index.php;
                try_files $uri $uri/ index.php $uri/index.php /config/www/pp1/index.php index.php; #/index.php?$args =404;
                location ~ \.php$ {
                        fastcgi_split_path_info ^(.+\.php)(/.+)$;
                        # With php5-cgi alone:
                        fastcgi_pass 127.0.0.1:9000;
                        # With php5-fpm:
                        #fastcgi_pass unix:/var/run/php5-fpm.sock;
                        fastcgi_index index.php;
                        include /etc/nginx/fastcgi_params;
                }
        }
         location /interpreter {
                if ($request_uri ~* "([^/]*$)" ) {
                        set  $last_path_component  $1;
                }
                root /config/www;
                index index.html index.htm index.php $last_path_component.html;
                try_files /interpreter/res/$last_path_component.html $uri.html $uri.html $uri $uri/ /index.html index.php /$uri.html  /index.php?$args =404;
                location ~ \.php$ {
                        fastcgi_split_path_info ^(.+\.php)(/.+)$;
                        # With php5-cgi alone:
                        fastcgi_pass 127.0.0.1:9000;
                        # With php5-fpm:
                        #fastcgi_pass unix:/var/run/php5-fpm.sock;
                        fastcgi_index index.php;
                        include /etc/nginx/fastcgi_params;
                }
        }

}

server {
        listen 80 default_server;

        listen 443 ssl;

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

        server_name _;

        ssl_certificate /config/keys/cert.crt;
        ssl_certificate_key /config/keys/cert.key;

        client_max_body_size 0;

        location / {
                try_files $uri $uri/ /index.html /index.php?$args =404;
        }

        location ~ \.php$ {
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                # With php5-cgi alone:
                fastcgi_pass 127.0.0.1:9000;
                # With php5-fpm:
                #fastcgi_pass unix:/var/run/php5-fpm.sock;
                fastcgi_index index.php;
                include /etc/nginx/fastcgi_params;

        }
}

Quite frankly, I thought I knew what I was doing, however right now I am pretty certain that the location block location /interpreter is not being checked at all and the insides of location /pp1 are causing some crazy mumbo-jumbo.

Please help a newbie in need!

like image 342
Brotholomew Avatar asked Jan 28 '26 02:01

Brotholomew


1 Answers

The main problem is that try_files will process its file elements within the current context, so you cannot handle your .html and .php URIs in the same statement. See this document for details.

One solution is to use a named location to split the try_files statement into two. First to test $uri, $uri.html and $uri/index.html, then a second to test $uri.php and $uri/index.php.

For example:

root /path/to/root;

location /foo {
    try_files $uri $uri.html $uri/index.html @php;
    location ~* ^(.*)\.php$ { return 301 $1; }
}
location @php {
    try_files $uri.php $uri/index.php =404;
    fastcgi_pass  ...;
    ...
}

The location ~* ^(.*)\.php$ block is added to handle URIs that end with .php correctly. The simplest solution is to redirect them to a URI with the .php removed.

like image 192
Richard Smith Avatar answered Jan 29 '26 14:01

Richard Smith



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!