Skip to content
Advertisement

Getting a 500 Internal Server Error when rewriting 2 specific URLs

I keep getting a 500 internal server error when trying to rewrite these one specific URLs/files (item.php & purchase.php), the rest works.

I have tried many ways to fix this but nothing seemed to work, which is weird because all other URLs do work, but these 2 just seem to not want to work for some reason.

.htaccess file

JavaScript

item.php

JavaScript

purchase.php

JavaScript

Advertisement

Answer

JavaScript

These directives should be at the end of your .htaccess file, after the other rewrites. They are also incorrect – although by placing them at the end of the file it will avoid the immediate issue, but could still cause problems with other URLs.

In its current state, when you request example.com/market/item/1 (where it would seem, /market is a physical directory, and /item.php is a file in that directory) then…

In brief… it results in an endless rewrite loop:

JavaScript

Which breaks (after 10 iterations) with a 500 response being sent to the browser.

A very similar process happens when requesting /market/item/1/purchase:

JavaScript

In detail…

  1. REQUEST_FILENAME is /market/item (ignoring the directory-prefix) and PATH_INFO is /1 (important for later). /market/item is not a directory (1st condition), but /market/item.php is a file (2nd condition) – so both conditions are successfully met.

  2. The RewriteRule directive then rewrites /market/item/1 to /market/item/1.php (clearly incorrect and not the intention). Since there is no L flag on this rule, processing continues… for the sake of the remaining rules, the PATH_INFO (from the initial request, /1) is appended to the resulting URL to become /market/item/1.php/1 (the DPI flag – discard path info – was created to prevent this specific behaviour).

  3. /market/item/1.php/1 does not match any further rules in the current pass, so the rewrite engine starts over at the top with /market/item/1.php.

  4. REQUEST_FILENAME is again /market/item and PATH_INFO is now /1.php. /market/item is not a directory (1st condition), but /market/item.php is a file (2nd condition) – so both conditions are successfully met a second time.

  5. The RewriteRule directive then rewrites /market/item/1.php to /market/item/1.php.php. Since there is no L flag on this rule, processing continues… for the sake of the remaining rules, the PATH_INFO (from the request, /1.php this time) is appended to the resulting URL to become /market/item/1.php.php/1.php.

  6. /market/item/1.php.php/1.php does not match any further rules in the current pass, so the rewrite engine starts over at the top with /market/item/1.php.php.

  7. GOTO #4 (with updated URL-path) etc. etc. etc. rewrite loop, 500 error.

And a very similar process happens when requesting /market/item/1/purchase. The REQUEST_FILENAME is the same /market/item (so it again checks that /market/item.php exists, not purchase.php), except that the PATH_INFO is /1/purchase (not /1). And the initial URL-path that the .php extension is appended to is naturaly /market/item/1/purchase (not /market/item/1).

Fix

If you’ve followed that “confusing muddle”, you’ll see that the condition that checks for the existence of the “path/to/file” + “.php” is not necessarily the same as the rule that actually rewrites the request to “URL-path” + “.php”. (“path/to/file” is not the same as the “URL-path”). To fix this, it should be written as:

JavaScript

No real need for the directory check here, since if it was a directory, the file check that follows must fail (unless you have directory names that end in .php). The %{DOCUMENT_ROOT}/$1.php check is now effectively “the same” as $1.php (the file being rewritten to).

The literal dot does not need to be backslash escaped in the RewriteCond TestString – this is an “ordinary” string, not a regex.

Don’t forget the L flag(s). And this rule block should now go at the end of the .htaccess file.

Summary

JavaScript
User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement