NGINX try_files with name as the last word in the $uri
Asked Answered
M

1

3

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!

Maraud answered 8/11, 2020 at 19:27 Comment(0)
M
3

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.

Malachi answered 8/11, 2020 at 20:9 Comment(5)
Thank you! It works now, however I have to navigate to example.com/pp1 (with the slash at the end) - it doesn't work when I navigate to example.com/pp1 (without the slash) is there a way like a rewrite to remedy this?Maraud
I meant https://example.com/pp1/ and I want it to be accessible from https://example.com/pp1 (no slash at the end)Maraud
Strangely curl -I https://kni.mini.pw.edu.pl/pp1 shows it redirecting to http. The configuration in your question or my answer shouldn't do that. Is this server terminating the SSL connection?Malachi
I am behind a proxy administered by someone else. I've got no access to how he / she handles the ssl certbots. My problem is, however, independent of that, I do believe (or is it not??). I would like the the uri : https://kni.mini.pw.edu.pl/pp1 be handled like https://kni.mini.pw.edu.pl/pp1/. The first one is always treated as if it were just https://kni.mini.pw.edu.pl. Could the problem be connected with the fact that under location / resides a docker with wordpress?Maraud
Are you still using $uri/ as one of the file terms in your try_files statement?Malachi

© 2022 - 2024 — McMap. All rights reserved.