
Eu tenho o seguinte em meu host virtual para conexões SSL (meu host virtual não SSL parece o mesmo, mas sem a primeira regra definida para redirecionamento).
DocumentRoot /var/www/example.com/public/
<Directory "/var/www/example.com/public/">
#only mod_rewrite configuration is shown here
RewriteEngine on
RewriteBase /
RewriteCond $1 !=signup
RewriteCond $1 !=login
RewriteCond $1 !=welcome
RewriteCond $1 !=thankyou
RewriteRule ^(.*)$ http://example.com/$1 [L,R,QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule ^(.+)$ index.php?q=$1 [L,QSA]
</Directory>
Minha intenção é que qualquer solicitação de página que não corresponda (signup|login|welcome|thankyou) seja redirecionada para o host virtual não SSL sem processamento adicional, caso contrário, não redirecione, mas processe a solicitação dentro do host virtual SSL.
O primeiro conjunto RewriteRule cuida do redirecionamento, enquanto o segundo conjunto RewriteRule cuida do processamento normal da página.
Sem o primeiro conjunto de regras, todas as solicitações são carregadas corretamente no host virtual SSL.
Com o primeiro conjunto de regras, os redirecionamentos funcionam perfeitamente quando não correspondem aos recursos listados. por exemplo. um pedido de
https://example.com/about
redireciona para
http://example.com/about
Mas ao solicitar as páginas de inscrição, login, boas-vindas e agradecimento, o problema ocorre. Essas solicitações também são redirecionadas para o site não SSL, mas de forma quebrada. Um pedido de
https://example.com/signup
redireciona para
http://example.com/index.php?q=signup
Parece que o primeiro conjunto de regras não corresponde (como seria esperado) e, depois que o segundo conjunto de regras é processado, o primeiro conjunto de regras é aplicado novamente (o que não é esperado).
Não consigo combinar esse comportamento inesperado com nenhuma funcionalidade documentada.
Alguma ideia?
Editar
Encontrei algumas referências obscuras na documentação para o Apache executar novamente as regras quando ocorre uma correspondência de regras dentro de um "contexto de diretório", no entanto, a referência era em relação ao .htaccess. Minha reescrita está ocorrendo dentro de uma tag <Directory> dentro da minha tag <VirtualHost>. Atualmente estou testando mover a reescrita para fora do contexto <Directory> - isso certamente parece mudar o comportamento, mas ainda não fiz funcionar conforme necessário.
Editar2
O problema certamente é causado pelo apache reiniciar o processamento de reescrita quando o processamento de regras existe dentro de um contexto de diretório. Mudei o processamento de regras para fora da tag <Directory>. No entanto, agora as linhas RewriteCond não funcionam... por exemplo.
RewriteCond %{REQUEST_FILENAME} -f
porque o apache ainda não resolveu o recurso solicitado para um mapeamento de arquivo usando o DocumentRoot. Que bagunça.
Portanto, acrescento manualmente o valor especificado em DocumentRoot ao RewriteCond. No entanto, isso parece um hack ruim. por exemplo.
RewriteCond /var/www/example.com/public%{REQUEST_FILENAME} -f
Então, agora estou procurando uma maneira de evitar que o Apache reinicie o processo de reescrita quando estiver dentro de um contexto de diretório ou, segundo melhor, uma maneira melhor de especificar os RewriteConds necessários no nível <VirtualHost>.
Responder1
Sugiro adicionar o seguinte à sua configuração, que fornecerá um registro detalhado do que o mod_rewrite está fazendo e por quê. Isso pode ajudar a esclarecer por que você tem tal comportamento:
RewriteLog /tmp/rewrite.log RewriteLogLevel 9
Quando terminar de analisar isso, certifique-se de remover essas linhas, pois elas afetam o desempenho.
Responder2
Eu decidi pela solução a seguir, colocando as reescritas fora de qualquer seção <Directory ...>. Isso me permite redirecionar qualquer solicitação que não deveria ser SSL para o site não SSL, ao mesmo tempo que permite que qualquer conteúdo estático seja veiculado por SSL (imagens, css, js etc.).
<VirtualHost ...>
...
RewriteEngine on
RewriteCond $1 !=signup
RewriteCond $1 !=login
RewriteCond $1 !=welcome
RewriteCond $1 !=thankyou
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d
RewriteRule ^/(.*)$ http://example.com/$1 [R=303,QSA,L]
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteCond %{REQUEST_URI} !=/robots.txt
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d
RewriteRule ^/(.+)$ /index.php?q=$1 [QSA,L]
...
</VirtualHost>