% N backreference внутри RewriteCond

Я работаю над системой виртуальных доменов. У меня есть подстановочный DNS, настроенный как *.loc, и я пытаюсь работать с моим файлом .htaccess. Следующий код работает:

RewriteEngine On
RewriteCond %{HTTP_HOST} ^(www.)?example\.loc$ [NC]
RewriteCond %{REQUEST_URI} !^/example/
RewriteRule (.*) /example/$1 [L,QSA]

Но я хочу, чтобы это работало со всем, что я вставил. Однако мне нужно, чтобы %{REQUEST_URI} проверял текст, найденный в качестве домена. Я пытался использовать этот код:

RewriteEngine On
RewriteCond %{HTTP_HOST} ^(www.)?([a-zA-Z0-9-]*.)?([a-zA-Z0-9-]+)\.loc$ [NC]
RewriteCond %{REQUEST_URI} !^/%3/
RewriteRule (.*) /%3/$1 [L,QSA]

Но строка RewriteCond %{REQUEST_URI} !^/%3/ заставляет мой код выдавать внутреннюю ошибку сервера. Я понимаю, что это связано с% N в моем коде, но есть ли способ работать с ним? Мне нужна эта строка, в противном случае мой код не из внутренних перенаправлений.

Я надеюсь, что это имеет смысл для кого-то. Все, что мне нужно, это иметь возможность ссылаться на RewriteCond в следующем RewriteCond.

Ответы

Ответ 1

Там 2 вещи, которые вы здесь делаете неправильно.

Во-первых, регулярное выражение %{HTTP_HOST} не подходит. Вам нужно избегать точек ., иначе они будут рассматриваться как "любой символ, который не является символом новой строки". Это по существу делает обратную ссылку %3 последним символом имени хоста перед TLD (например, http://blah.bar.loc, % 3= r).

Во-вторых, вы не можете использовать обратные ссылки в регулярном выражении RewriteCond, только в левой части строки, это своего рода странное ограничение. Однако вы можете использовать ссылки \1 в регулярном выражении, чтобы вы могли построить умную левую боковую строку для сопоставления. Что-то вроде %3::%{REQUEST_URI}, а затем вы можете так: !^(.*?)::/\1/?. Это регулярное выражение, по существу, говорит: "сопоставьте и сгруппируйте первый блок текста перед ::, затем убедитесь, что блок текста, следующий за ::, начинается с /(first block)".

Итак, ваши правила должны выглядеть так:

RewriteEngine On
RewriteCond %{HTTP_HOST} ^(www\.)?([a-zA-Z0-9-]*\.)?([a-zA-Z0-9-]+)\.loc$ [NC]
RewriteCond %3::%{REQUEST_URI} !^(.*?)::/\1/?
RewriteRule (.*) /%3/$1 [L,QSA]