Я сказал бы, что взгляд на Smoothwall - но я смещаюсь, я работаю там. Устройства аппаратных средств/качества VM/your (диски wd re3/re4, intel NICs), хотя - поэтому выбирают.
Эти правила перезаписи находятся в файле .htaccess
? В этом случае флаг [L]
не делает то, что вы думаете - он останавливает обработку текущего набора правил, но затем запрос снова обрабатывается Apache, используя .htaccess
файлы, соответствующие перезаписанному URI, поэтому ваши правила могут быть выполнены снова. Этого не происходит для правил, которые находятся в файле конфигурации Apache (а не внутри раздела
) - в этом случае флаг [L]
обрабатывается должным образом.
В вашем примере https://example.com/preview/anything
внутренне переписано в https://example.com/index.php/preview/anything
третье правило; однако, чтобы обработать этот запрос, Apache должен снова прочитать файл .htaccess
- и на этот раз URI соответствует вашему второму правилу, которое возвращает перенаправление 302
.
Apache 2.4.x поддерживает [END]
флаг, который останавливает такие циклы перезаписи, в отличие от [L]
; решения для более ранних версий Apache более сложны.
Если вы хотите убедиться, что Apache выполняет только один проход по вашим правилам перезаписи, вы можете добавить следующее правило перед всеми остальными:
RewriteCond %{ENV:REDIRECT_STATUS} !=""
RewriteRule ^ - [L]
На первом проходе REDIRECT_STATUS
будет пустым; на втором проходе оно будет иметь непустое значение (обычно 200
), и правило будет соответствовать и действительно остановит дальнейшие перезаписи.
В случае, если такое правило не подходит (например, в некоторых случаях, когда вам нужно обрабатывать перезаписанные URI на втором проходе),
This sounds like the last rule is introducing an absolute http
-based redirect when it's being done, perhaps due to some bug or feature in Apache or mod_rewrite.
How about you break it down into two rules with an extra condition?
Try this:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{HTTPS} =off
RewriteRule ^(.*)$ http://example.com/index.php/$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{HTTPS} =on
RewriteRule ^(.*)$ https://example.com/index.php/$1 [L]
Is the http
scheme (instead of https
) that bothers you? If so, you should look at the RewriteBase
directive.
From the mod_rewrite docs:
The
RewriteBase
directive specifies the URL prefix to be used for per-directory (htaccess)RewriteRule
directives that substitute a relative path.This directive is required when you use a relative path in a substitution in per-directory (htaccess) context (...)
Я не думаю, что вам нужен '(. *) $' В конце операторов RewriteCond, потому что вы нигде не используете захваченные данные. Вы можете упростить эти 2 так:
RewriteCond %{REQUEST_URI} ^/system [NC]
и RewriteCond% {REQUEST_URI}! ^ / (System | preview) / [NC]
Я бы также порекомендовал включить RewriteLog и установить RewriteLogLevel, чтобы точно видеть, что apache делает для каждого запроса. С apache 2.2 или ниже это будет:
RewriteLog /var/log/apache2/rewrite.log
RewriteLogLevel 7
Вы должны шаг за шагом точно увидеть, что соответствует и какие действия предпринял apache.