Search code examples
phpapache.htaccessmod-rewriteweb-development-server

I am getting 500 internal error when giving url as dir/file/file


When I am trying to give url as https://example.com/dir/file/file then the request is getting into loop and 500 error comes while it should give file does not exists. I am using LAMP Stack. I am hiding .php in my .htaccess

## hide .php extension
# To externally redirect /dir/foo.php to /dir/foo
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.php [NC]
RewriteRule ^ %1 [R=302,L]

# To internally forward /dir/foo to /dir/foo.php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*?)/?$ $1.php [L]


Solution

  • # To internally forward /dir/foo to /dir/foo.php
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME}.php -f
    RewriteRule ^(.*?)/?$ $1.php [L]
    

    You are getting a rewrite-loop (500 error) because the filename you are checking, ie. %{REQUEST_FILENAME}.php isn't necessarily the same as the file you are rewriting to, ie. $1.php.

    If you request /dir/file/file then the REQUEST_FILENAME server variable is <document-root>/dir/file (no path-info), whereas the captured backreference $1 is /dir/file/file.

    Try the following instead:

    # To internally forward /dir/foo to /dir/foo.php
    RewriteCond %{DOCUMENT_ROOT}/$1.php -f
    RewriteRule ^(.*?)/?$ $1.php [L]
    

    A request for /dir/file/file will now fail with a 404, since it is checking that /dir/file/file.php exists.

    You don't really need to check that the request does not map to a directory before checking that it does map to a file (twice the work), unless you also have directories of the same name and you need the directory to take priority (unlikely).

    See also my answer to the following ServerFault question that goes into more detail: https://serverfault.com/questions/989333/using-apache-rewrite-rules-in-htaccess-to-remove-html-causing-a-500-error