Como evitar que o Apache reinicie o processamento de reescrita dentro de um “contexto de diretório”

Como evitar que o Apache reinicie o processamento de reescrita dentro de um “contexto de diretório”

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>

informação relacionada