Apache htaccess multiple rewrite conditions for multiple rules

I took over a website and noticed the previous developer had multiple .htaccess rewrite rules, this is a short example:

RewriteCond %{REQUEST_URI} !^/[0-9]+\..+\.cpaneldcv$
RewriteCond %{REQUEST_URI} !^/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/[0-9a-zA-Z_-]+$
RewriteCond %{REQUEST_URI} !^/\.well-known/pki-validation/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteRule ^(.*)/landing/(.*)/(.*)$ landing.php?page=$1&id=$2&mid=$3
RewriteCond %{REQUEST_URI} !^/[0-9]+\..+\.cpaneldcv$
RewriteCond %{REQUEST_URI} !^/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/[0-9a-zA-Z_-]+$
RewriteCond %{REQUEST_URI} !^/\.well-known/pki-validation/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteRule ^(.*)/landing/(.*)$ landing.php?page=$1&id=$2
RewriteCond %{REQUEST_URI} !^/[0-9]+\..+\.cpaneldcv$
RewriteCond %{REQUEST_URI} !^/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/[0-9a-zA-Z_-]+$
RewriteCond %{REQUEST_URI} !^/\.well-known/pki-validation/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteRule ^(.*)/landing$ landing.php?page=$1

The Rewrite Condition is always the same for all rules, is there a way to combine the Rewrite Rules so the conditions just have to be written once?

I have looked into the skipping flag but it has no backreference possible. As far as I see I do not need backreferences with those conditions, however, is skipping the best approach? Or is there a best practice on how to achieve this? (Someone suggested to me to use the QSA flag, however, upon research I don't think that has anything to do with what I want to accomplish.)

2
задан 24 November 2017 в 01:24
1 ответ
 RewriteCond% {REQUEST_URI}! ^ / [0-9] + \ .. + \. Cpaneldcv $
RewriteCond% {REQUEST_URI}! ^ / [A-F0-9] {32} \. Txt (?: \ Comodo \ DCV)? $
RewriteCond% {REQUEST_URI}! ^ / \. Well-known / acme-challenge / [0-9a-zA-Z _-] + $
RewriteCond% {REQUEST_URI}! ^ / \. Well-known / pki-validation / [A-F0-9] {32} \. Txt (?: \ Comodo \ DCV)? $
 

Этот беспорядочный блок условий автоматически вводится cPanel перед каждой директивой RewriteRule , когда он автоматически обновляет сертификат безопасности SSL (Let's Encrypt?). Эти условия гарантируют, что файл проверки (необходимый для обновления сертификата SSL) доступен.

К сожалению, я не смог понять, почему cPanel делает это таким образом - это может быть кошмаром обслуживания и я встречал директивы, которые были нарушены этими условиями (правда, директивы изначально были не совсем идеальными). (Я пробовал спрашивать на форумах cPanel, но у меня никогда не было хорошего ответа.)

... есть ли способ объединить правила перезаписи, чтобы условия просто нужно было написать один раз?

Да. Вы можете переместить эти условия в отдельный блок в начале файла .htaccess и перевернуть их значение,поэтому вместо запуска RewriteRule только тогда, когда запрос не соответствует шаблону (с использованием инвертированного регулярного выражения). Вы можете предотвратить дальнейшие перезаписи, когда запрос действительно соответствует шаблону. Например:

# BEGIN cPanel SSL CERT RENEWAL
RewriteCond %{REQUEST_URI} ^/[0-9]+\..+\.cpaneldcv$ [OR]
RewriteCond %{REQUEST_URI} ^/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$ [OR]
RewriteCond %{REQUEST_URI} ^/\.well-known/acme-challenge/[0-9a-zA-Z_-]+$ [OR]
RewriteCond %{REQUEST_URI} ^/\.well-known/pki-validation/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteRule ^ - [L]
# END cPanel SSL CERT RENEWAL

Обратите внимание на удаление префикса ! (отрицание) в CondPattern и дополнительного флага OR в первых трех условиях. RewriteRule затем предотвращает дальнейшую обработку директив mod_rewrite в случае совпадения запроса.

(В Apache 2.4.8+ эти директивы могут быть полностью перемещены в конфигурацию сервера. С помощью RewriteOptions InheritDownBefore .)

Затем следуют только директивы RewriteRule , которые у вас были раньше (хотя я добавил флаг L ):

RewriteRule ^(.*)/landing/(.*)/(.*)$ landing.php?page=$1&id=$2&mid=$3 [L]
RewriteRule ^(.*)/landing/(.*)$ landing.php?page=$1&id=$2 [L]
RewriteRule ^(.*)/landing$ landing.php?page=$1 [L]

Вы, вероятно, должны включить L помечает оставшиеся перезаписи.

Вы также можете объединить эти 3 перезаписи в одну директиву, если хотите, но это будет зависеть от того, обрабатывает ли ваше приложение пустые параметры URL.

(Кто-то предложил Я использую флаг QSA, однако, по результатам исследования, я не думаю, что это имеет какое-либо отношение к тому, что я хочу достичь.)

Да, на самом деле это не имеет ничего общего с этой конкретной проблемой. Флаг QSA (Добавление строки запроса) позволит вам объединить любую строку запроса, которая присутствовала в запросе, со строкой запроса, которую вы пишете в подстановке RewriteRule .

3
ответ дан 3 December 2019 в 10:34

Теги

Похожие вопросы