Можно ли использовать переменную сервера mod_rewrite внутри RewriteCond CondPattern?

Используя mod_rewrite, я бы хотел использовать серверную переменную как часть CondPattern для RewriteCond, что-то как:

RewriteCond %{HTTP_HOST} !^%{SERVER_NAME} [NC]
                           ^^^^^^^^^^^^^^

Это было бы действительно полезно. Я знаю, что CondPattern является Perl-совместимым регулярным выражением, и что это означает, например, что символы {} в моем примере нужно каким-то образом избежать. Я оставил его как есть просто, чтобы продемонстрировать идею.

В вышеупомянутых документах ничего не говорится об этом, насколько я могу найти, и googling вокруг я не смог найти ничего окончательного. Моя догадка - ответ: нет, но я хотел бы знать наверняка.

Ответ 1

CondPattern не раскрывает переменные %{VAR} или %N обратные ссылки на предыдущий RewriteCond, поэтому предложение Дэвида

RewriteCond %{SERVER_NAME} ^(.*)$
RewriteCond %{HTTP_HOST} !%1

будет выполняться всякий раз, когда %{HTTP_HOST} не содержит литеральную строку %1, которая не является тем, что вы хотите.

Что вы хотите, в соответствии с вашим примером

RewriteCond %{HTTP_HOST} !^%{SERVER_NAME} [NC]

соответствует, если HTTP_HOST не начинается с SERVER_NAME (без учета регистра). Вы можете реализовать это с помощью единственного RewriteCond, если вы включите SERVER_NAME в TestString, запишите его в регулярное выражение и используйте \N для повторного ссылки на него:

RewriteCond "%{SERVER_NAME} %{HTTP_HOST}" "!(^[^ ]*) \1" [NC]

Регулярное выражение использует пробел для разделения SERVER_NAME и HTTP_HOST, поскольку ни одна переменная не может иметь пробелов.

выражения Apache (версия 2.4 и более поздние)

Если вы действительно хотите проверить, если SERVER_NAME равно HTTP_HOST, было бы проще использовать выражения Apache:

# Case-sensitive comparison.
RewriteCond expr "%{HTTP_HOST} == %{SERVER_NAME}"

или

# Case-insensitive comparison.
RewriteCond expr "tolower(%{HTTP_HOST}) == tolower(%{SERVER_NAME})"

Ответ 2

Нет, вы не можете использовать переменную прямо так, но вы можете сделать что-то вроде этого:

RewriteCond %{SERVER_NAME} ^(.*)$
RewriteCond %{HTTP_HOST} !%1

Первая строка должна всегда совпадать и отображать SERVER_NAME. Вторая строка использует это захваченное значение для сравнения с HTTP_HOST.