BlueHorizon
BlueHorizon

Reputation: 217

500 Internal Server Error instead of: 404 - Not Found

Apparently these lines in my .htaccess cause the server to output a 500 instead of a 404 error which should appear when trying to access a non-existant site.

RewriteEngine On
# Don't rewrite requests to /de or other real files
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^.*/(css|scripts)
# Rewrite incoming requests to their equivalent behind /de
RewriteRule ^(.*)$ de/$1 [L,QSA]

Alas I'm very unfamiliar with .htaccess. Where's the mistake in this one which causes the 500 instead of the 404 error?

This is the error in the logfile:

Request exceeded the limit of 10 internal redirects due to probable configuration error. Use 'LimitInternalRecursion' to increase the limit if necessary. Use 'LogLevel debug' to get a backtrace.

Edit:

RewriteRule ^(.*)$ de/$1 [L,QSA]

This part is responsible for the error. Why does it prevent the 404-error page though?

Upvotes: 2

Views: 6445

Answers (1)

Jon Lin
Jon Lin

Reputation: 143906

This part is responsible for the error. Why does it prevent the 404-error page though?

The reason why this isn't producing a 404 error page is because of the conditions which prevent the blind match from being rewritten to de/.

These are the 3 preventative conditions you have:

# these prevent rewriting if the URI doesn't point to a resource
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f

# this prevents scripts from being rewritten
RewriteCond %{REQUEST_URI} !^.*/(css|scripts)

However, nothing is preventing a rewrite if, for example, /de/blahblah doesn't exist. Thus if someone requests /blahblah, this is what happens:

  1. URI = /blahblah
  2. checks first condidion: blahblah is not a directory
  3. checks second condition: blahblah is not a file
  4. checks third condition: blahblah isn't a css or script
  5. rewrites to /de/blahblah
  6. Rewrite engine loops, URI = /de/blahblah
  7. checks first condidion: de/blahblah is not a directory
  8. checks second condition: de/blahblah is not a file
  9. checks third condition: de/blahblah isn't a css or script
  10. rewrites to /de/de/blahblah
  11. etc. etc.

You need to add an additional set of conditions to rewrite IF the target exists:

RewriteCond %{DOCUMENT_ROOT}/de%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}/de%{REQUEST_URI} -d

Thus, you should have something like:

RewriteEngine On
# Don't rewrite requests to /de or other real files
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^.*/(css|scripts)
# make sure rewrite target actually exists as a file or directory
RewriteCond %{DOCUMENT_ROOT}/de%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}/de%{REQUEST_URI} -d
# Rewrite incoming requests to their equivalent behind /de
RewriteRule ^(.*)$ de/$1 [L,QSA]

This way, a 404 will get returned because nothing is ever rewritten into the de/ directory.

Upvotes: 2

Related Questions