Skip to content

Regression: Apache Content Negotiation Options +MultiViews Now Broken in FCGID PHP Mode #1036

@Deltik

Description

@Deltik

Summary

After a change in Virtualmin 7.30.3, the MultiViews functionality no longer works correctly for PHP files in domains using FCGID PHP mode (FastCGI in Apache). This prevents accessing PHP files without their extensions (e.g., accessing example.com/page to load page.php), despite having Options +MultiViews set. This is a regression from previous versions where this functionality worked correctly.

Environment

  • Virtualmin version: 7.30.3 or newer
  • PHP mode: FCGID (also affects PHP-FPM, but not a regression)
  • Apache version: 2.4.x

Steps to Reproduce

  1. Create a new domain in Virtualmin or use an existing one.
  2. Configure the domain to use FCGID as the PHP execution mode (Web Configuration » PHP Options » PHP options for this domain » PHP script execution mode » FCGI).
  3. Ensure Options +MultiViews is in the domain's .htaccess file.
  4. Create a simple PHP file, e.g., phpinfo.php in the domain's public_html.
  5. Try to access the file without extension: https://example.com/phpinfo
  6. Observe HTTP 404 error.

Observed Behavior

  • The URL without extension returns an HTTP 404 Not Found error.
  • Access with the full file extension works fine: https://example.com/phpinfo.php

Expected Behavior

  • The URL without the extension should load the PHP file.
  • Apache should perform content negotiation and find the .php file.

This worked correctly in Virtualmin versions prior to 7.30.3 for FCGID mode.

Root Cause

The issue was introduced by commit 0b9d830, which changed the PHP configuration for FCGID mode. The commit removed the line that added the MIME type directive:

-		elsif ($mode eq "mod_php" || $mode eq "fcgid") {
+		elsif ($mode eq "mod_php") {
 			push(@types, "application/x-httpd-php .php");
 			}

As a result, domains using FCGID mode no longer get the required AddType application/x-httpd-php .php directive in their Apache configuration. Without this MIME type mapping, Apache's MultiViews content negotiation mechanism cannot identify PHP files as candidates during the negotiation process, even if the files exist on disk.

MultiViews relies on MIME type mappings to know which file extensions to consider when looking for alternatives to a requested URL. Without the application/x-httpd-php MIME type being associated with .php files, Apache doesn't know to include these files in the negotiation process.

Verification

I verified this was the issue through several methods:

  1. By adding AddType application/x-httpd-php .php manually to the domain's Apache configuration, and after a restart of Apache, MultiViews began working as expected.
  2. By temporarily reverting commit 0b9d830 on my installation, which restored the original PHP option updating behavior.
  3. By examining the Apache configuration for FCGID mode before and after the change, confirming the MIME type directive was indeed removed.
  4. By observing that the PHP-FPM mode also lacks this directive and exhibits the same issue with MultiViews not functioning.

Impact

This affects all Virtualmin users who:

  1. Use FCGID as their PHP execution mode,
  2. Rely on MultiViews to allow access to PHP files without extensions, and
  3. Have updated to Virtualmin 7.30.3 or newer.

This is a significant usability regression, especially for:

  • Domains migrated from other platforms where URLs without extensions were previously working,
  • Content management systems and frameworks that generate clean URLs without file extensions, and
  • Sites that have been running with this functionality for years and suddenly stop working after an update.

Suggested Fix

Instead of simply reverting the change, I suggest implementing a more comprehensive fix that ensures consistent behavior across all PHP execution modes:

  1. For FCGID mode: Restore the previously removed MIME type mapping:

    elsif ($mode eq "mod_php" || $mode eq "fcgid") {
        push(@types, "application/x-httpd-php .php");
    }
  2. For PHP-FPM mode: Add the same MIME type mapping in the appropriate configuration section to ensure MultiViews works consistently:

    push(@types, "application/x-httpd-php .php");

The goal should be consistent behavior: if a user enables MultiViews, it should work the same way regardless of which PHP execution mode they're using. Currently, MultiViews functions with mod_php, worked with FCGID before this change, but doesn't work properly with PHP-FPM.

This MIME type directive doesn't conflict with the handler directives used by different PHP modes – it simply tells Apache about the content type associated with .php files so that content negotiation can work properly.

Temporary Workaround

Site admins can add the following to their .htaccess file:

AddType application/x-httpd-php .php

Server admins can revert the change in Virtualmin until the next upgrade with:

echo -e 'diff --git a/usr/share/webmin/virtual-server/php-lib.pl~ b/usr/share/webmin/virtual-server/php-lib.pl
index 02e2239..e36be46 100755
--- a/usr/share/webmin/virtual-server/php-lib.pl~
+++ b/usr/share/webmin/virtual-server/php-lib.pl
@@ -399,7 +399,7 @@ foreach my $p (@ports) {
 \t\tif ($mode eq "cgi") {
 \t\t\tpush(@types, "application/x-httpd-php$ver .php");
 \t\t\t}
-\t\telsif ($mode eq "mod_php") {
+\t\telsif ($mode eq "mod_php" || $mode eq "fcgid") {
 \t\t\tpush(@types, "application/x-httpd-php .php");
 \t\t\t}
 \t\t@types = &unique(@types);' | patch /usr/share/webmin/virtual-server/php-lib.pl

Additional Notes

This issue highlights the importance of the relationship between MIME types and content negotiation in Apache. The MIME type directive and the handler directive serve different purposes:

  • AddType tells Apache what kind of content a file contains
  • AddHandler/FCGIWrapper tells Apache how to process that content

Both are needed for full functionality, especially when features like MultiViews are being used.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions