Essas regras de reconfiguração estão em um arquivo .htaccess
? Nesse caso, o sinalizador [L]
não faz o que você acha que faz - interrompe o processamento do conjunto de regras atual, mas, em seguida, o pedido é processado pelo Apache novamente, usando .htaccess
arquivos apropriados para o URI reconfigurado, portanto, suas regras podem ser executadas novamente. Isso não acontece com regras que estão no arquivo de configuração do Apache (e não dentro de uma seção <Directory>
) - nesse caso, o [L]
flag é tratado como esperado.
Por exemplo, https://example.com/preview/anything
é reescrito internamente em https://example.com/index.php/preview/anything
pela terceira regra; no entanto, para processar essa solicitação, o Apache deve ler o arquivo .htaccess
novamente e, dessa vez, o URI corresponde à sua segunda regra, que retorna um 302
de redirecionamento.
O Apache 2.4.x suporta o [END]
flag que interrompe esses loops de reescrita, ao contrário de [L]
; soluções para versões anteriores do Apache são mais complexas.
Se você quiser ter certeza de que o Apache faz apenas uma única passagem sobre suas regras de reescrita, você pode adicionar a seguinte regra antes de todas as outras:
RewriteCond %{ENV:REDIRECT_STATUS} !=""
RewriteRule ^ - [L]
Na primeira passagem, REDIRECT_STATUS
estará vazio; na segunda passagem, ele terá um valor não vazio (geralmente 200
), e a regra corresponderá e realmente parará de novas reescritas.
Caso tal regra não seja apropriada (por exemplo, em alguns casos, você precisa manipular URIs reconfiguradas na segunda passagem), é possível definir uma variável de ambiente em regras que devem ser realmente finais:
RewriteRule ^(.*)$ /index.php/$1 [L,E=FINISH:1]
e adicione a seguinte regra antes de todas as outras:
RewriteCond %{ENV:REDIRECT_FINISH} !=""
RewriteRule ^ - [L]
Observe que, durante a segunda passagem, o Apache precede REDIRECT_
aos nomes de variáveis de ambiente que foram definidos durante a primeira passagem; portanto, você precisa definir FINISH
, mas teste REDIRECT_FINISH
.
Como alternativa, você pode tentar modificar suas condições de correspondência para que as URIs de segunda passagem modificadas na primeira passagem não sejam correspondidas (por exemplo, insira (index\.php/)?
no regexp na segunda regra).