Как на самом деле работает mod_rewrite
Важно понимать, что изменение запроса не заканчивается на последнем RewriteRule. После того, как сработало последнее правило RewriteRule, mod_rewrite смотрит, изменился запрос или нет. Если запрос изменился, его обработка начинается заново с начала .htaccess.
Адрес
admin/run.php
успешно совпадает с шаблоном
^admin/(.*)$
и происходит бесконечный цикл.
После исчерпания LimitInternalRecursion обработка запроса завершается с ошибкой 500.
Достаточно добавить исключение для
admin/run.php
RewriteCond %{REQUEST_URI} !^/admin/run\.php
RewriteRule ^admin/(.*)$ /admin/run.php?request=$1 [QSA,L]
Или так
RewriteCond $1 !^run\.php
RewriteRule ^admin/(.*)$ /admin/run.php?request=$1 [QSA,L]
Или добавить проверку, что адрес не является существующим файлом
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^admin/(.*)$ /admin/run.php?request=$1 [QSA,L]
В переменной %{ENV:REDIRECT_STATUS} сохраняется код с которым завершилось предыдущее внутреннее перенаправление. Эта переменная пуста только на первой итерации обработки запроса.
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^admin/(.*)$ /admin/run.php?request=$1 [QSA,L]