rich remer
rich remer

Reputation: 3577

nginx serving some PHP URLs as downloads instead of executing

Some PHP URLs are being downloaded instead of executed by Nginx. I have an existing web application which is functioning fine. I'm tasked with adding additional mounted applications within folders of the primary application. Each of these applications has its own front controller index.php script.

For this setup, I've created symlinks inside $document_root/app, and the symlinks point to a folder containing an index.php front controller.

When I navigate to most URLs, everything works fine, the primary application front controller is executed, and I get expected results. When I navigate to a non-existent app, I get 404 Not Found from nginx, which is expected. But when I navigate to one of the applications, the browser downloads the application front controller.

root                    /my/web/root;

location / {
    try_files           $uri
                        /$server_name$uri
                        /shared$uri
                        /index.php$is_args$args;
}

location ~ [^/]\.php(/|$) {
    disable_symlinks    off;
    fastcgi_split_path_info ^(.+\.php\b)(.*)$;
    fastcgi_param       SERVER_NAME $host;
    fastcgi_param       PATH_INFO $fastcgi_path_info;
    fastcgi_param       SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param       SCRIPT_NAME /index.php;
    fastcgi_index       index.php;
    include             fastcgi.conf;
    fastcgi_pass        php-fpm;
}

location ~ ^/app/([a-z-]+)(/.*)?$ {
    try_files           $uri
                        /app/$1/index.php$is_args$args
                        =404;
}

URL which triggers download: /app/my-app/ (exists)
URL which 404s: /app/foo/ (does not exist)
URL which executes: /foo

Upvotes: 2

Views: 691

Answers (1)

Richard Smith
Richard Smith

Reputation: 49672

The .php file needs to be processed by the location ~ [^/]\.php(/|$) block. You have a common document root which makes things simpler.

However, look at this document regarding the location directive.

You will see that the regex locations are considered in order and the first matching location will be used to process the request.

In short, you need to place the location ~ [^/]\.php(/|$) block before any other conflicting regex location, if you want your .php files to be processed correctly.

Upvotes: 3

Related Questions