mod_rewrite регулярное выражение (слишком много перенаправлений) - PullRequest
1 голос
/ 01 ноября 2010

Я использую mod_rewrite для преобразования поддоменов в URL-адреса каталогов. (решение отсюда ). Когда я подробно пишу правило для одного субдомена, оно отлично работает:

RewriteCond %{HTTP_HOST}   ^[www\.]*sub-domain-name.domain-name.com [NC]
RewriteCond %{REQUEST_URI} !^/sub-domain-directory/.*
RewriteRule   ^(.*)  /sub-domain-directory/$1  [L]

Однако, если я попытаюсь сопоставить все субдомены, это приведет к внутренней ошибке 500 (журнал сообщает, что слишком много перенаправлений). Код:

RewriteCond %{HTTP_HOST}   ^[www\.]*([a-z0-9-]+).domain-name.com [NC]
RewriteCond %{REQUEST_URI} !^/%1/.*
RewriteRule   ^(.*)  /%1/$1  [L]

Кто-нибудь может подсказать, что пошло не так и как это исправить?

1 Ответ

3 голосов
/ 02 ноября 2010

Ваш второй RewriteCond никогда не вернет false, потому что вы не можете использовать обратные ссылки в своих тестовых предложениях (они компилируются во время синтаксического анализа, что делает это невозможным, поскольку расширение переменных не будет иметь места).Вы на самом деле проверяете пути, начинающиеся с буквального текста /%1/, а это не то, что вы хотели.Учитывая, что вы работаете в контексте каждого каталога, набор правил в конечном итоге будет применен снова, что приведет к преобразованию, подобному следующему:

path -> sub/path
sub/path -> sub/sub/path
sub/sub/path -> sub/sub/sub/path
...

Это продолжается около десяти итераций перед серверомрасстраивается и выбрасывает 500 ошибок.Есть несколько разных способов исправить это, но я выберу тот, который наиболее похож на подход, который вы пытались использовать.Я бы также изменил этот первый RewriteCond, так как регулярное выражение немного ошибочно:

RewriteCond %{HTTP_HOST}       ^([^.]+)\.example\.com$ [NC]
RewriteCond %1                !=www
RewriteCond %1#%{REQUEST_URI} !^([^#]+)#/\1/
RewriteRule .* /%1/$0 [L]

Во-первых, оно проверяет значение HTTP_HOST и захватывает поддомен, каким бы он ни был.Затем, предполагая, что вы не хотите, чтобы это преобразование имело место в случае с www, он удостоверяется, что захват не соответствует этому.После этого он использует собственные внутренние обратные ссылки регулярного выражения, чтобы увидеть, начинается ли REQUEST_URI со значения субдомена.Если это не так, он добавляет субдомен в качестве каталога, как у вас сейчас.

Потенциальная проблема этого подхода заключается в том, что он не будет работать правильно, если вы обращаетесь к пути, начинающемуся с того же имени, что исубдомен, в который отправляется запрос, например sub.example.com / sub / .Альтернативой является проверка переменной среды REDIRECT_STATUS, чтобы увидеть, было ли уже выполнено внутреннее перенаправление (то есть, этот предварительный шаг уже выполнен):

RewriteCond %{HTTP_HOST}           ^([^.]+)\.example\.com$ [NC]
RewriteCond %1                     !=www
RewriteCond %{ENV:REDIRECT_STATUS}  =""
RewriteRule .* /%1/$0 [L]
...