Combinando mais de 1 Apache rewriterule: redirecionamento de domínio de host virtual e redirecionamento de arquivo de entrada

1

Fiquei preso ao usar as condições RewriteCond e RewriteRule do Apache. Eu geralmente não os uso muito e principalmente a documentação me fornece informações suficientes para produzir uma solução por mim mesmo. Desta vez, porém, fiquei preso em como combinar mais de uma situação de reescrita.

No Apache 2.4.17, eu tenho um host virtual com serverAliases serveral apontando para o mesmo ServerName e diretório. Cada ServerAlias configurado deve redirecionar para o domínio ServerName. Então, quando eu visito sub1.domain.com, sub2.domain.com ou sub3.domain.com, tudo deve ser redirecionado para HTTP 301 para www.domain.com.

Também quero redirecionar toda a URL para o mesmo arquivo de entrada do PHP. Por exemplo: www.domain.com/news/1 deve ser internamente redirecionado para o arquivo index.php no documentroot do virtalhost sem alterar o URL no navegador do usuário.

As situações acima funcionam sozinhas, mas quando tento combinar as situações no arquivo .htaccess, as coisas dão errado.

Exemplo de redirecionamento do meu domínio:

AcceptPathInfo On
Options +MultiViews

Options +FollowSymLinks  
RewriteEngine On  

# Following solution inspired by https://makandracards.com/makandra/922-apache-redirect-all-requests-from-one-host-to-another
RewriteCond %{HTTP_HOST} !^www.domain.com$
RewriteRule ^(.*)$ "https://www.domain.com/$1" [NC,QSA,R=301]

Isso funciona muito bem.

E esse é o código que eu normalmente uso para redirecionar todo o URL internamente para index.php no documentroot para poder gerar conteúdo dinâmico com base no URL:

AcceptPathInfo On
Options +MultiViews

Options +FollowSymLinks  
RewriteEngine On  

RewriteCond %{SCRIPT_FILENAME} !-d  
RewriteCond %{SCRIPT_FILENAME} !-f  

RewriteRule ^.*$ ./index.php

Isso também funciona muito bem. A solicitação não é encaminhada nos navegadores dos usuários para index.php, mas apenas para dentro.

Quando tento combinar os dois redirecionamentos:

AcceptPathInfo On
Options +MultiViews

Options +FollowSymLinks  
RewriteEngine On  

# Following solution inspired by https://makandracards.com/makandra/922-apache-redirect-all-requests-from-one-host-to-another
RewriteCond %{HTTP_HOST} !^www.domain.com$
RewriteRule ^(.*)$ "https://www.domain.com/$1" [NC,QSA,R=301]

RewriteCond %{SCRIPT_FILENAME} !-d  
RewriteCond %{SCRIPT_FILENAME} !-f  

RewriteRule ^.*$ ./index.php

Então as coisas dão errado. Todas as solicitações nos outros domínios (por exemplo, sub1.domínio.com, sub2.domínio.com/test, etc.) resultam em um erro do Apache:

Moved Permanently

The document has moved here.

Additionally, a 301 Moved Permanently error was encountered while trying to use an ErrorDocument to handle the request.

Enquanto www.domain.com/test serve corretamente o conteúdo de index.php na raiz do documento.

Quando tento alterar a ordem das condições e regras:

AcceptPathInfo On
Options +MultiViews

Options +FollowSymLinks  
RewriteEngine On  

RewriteCond %{SCRIPT_FILENAME} !-d  
RewriteCond %{SCRIPT_FILENAME} !-f  

RewriteRule ^.*$ ./index.php

# Following solution inspired by https://makandracards.com/makandra/922-apache-redirect-all-requests-from-one-host-to-another
RewriteCond %{HTTP_HOST} !^www.domain.com$
RewriteRule ^(.*)$ "https://www.domain.com/$1" [NC,QSA,R=301]

Em seguida, sub1.domain.com foi redirecionado corretamente no navegador do usuário para www.domain.com, mas quando eu adicionei um URI a ele como sub1.domain.com/test, ele foi redirecionado para www.domain.com/ index.php em vez de www.domain.com/test e somente buscando internamente o conteúdo de index.php no documentroot.

Solicitar www.domain.com/test diretamente neste caso funciona bem: o conteúdo do index.php no documentroot está sendo exibido em vez de redirecionar o usuário para index.php.

Eu acredito que tem que fazer algo com algumas bandeiras, mas não sei de que maneira aplicá-las. Quem pode me explicar em quais coisas tenho que prestar atenção?

    
por Jeroen Maathuis 22.10.2016 / 17:38

1 resposta

0

Acho que já resolvi o problema por minha própria conta, adicionando o sinal [L] a ambas as linhas RewriteRule .

Este é o meu arquivo htaccess agora:

AcceptPathInfo On
Options +MultiViews

Options +FollowSymLinks  
RewriteEngine On 

# Following solution inspired by https://makandracards.com/makandra/922-apache-redirect-all-requests-from-one-host-to-another
RewriteCond %{HTTP_HOST} !^www.domain.com$
RewriteRule ^(.*)$ "https://www.domain.com/$1" [NC,QSA,R=301,L]

RewriteCond %{SCRIPT_FILENAME} !-d  
RewriteCond %{SCRIPT_FILENAME} !-f  

RewriteRule ^.*$ ./index.php [L]

Tanto quanto eu entendo, o Apache irá primeiro olhar para

RewriteCond %{HTTP_HOST} !^www.domain.com$

e depois executar

RewriteRule ^(.*)$ "https://www.domain.com/$1" [NC,QSA,R=301,L]

Como RewriteRule tem o sinalizador [L] definido, o Apache não verificará outras regras.

Quando o URL completo não atinge o primeiro RewriteCond , o Apache pula essa combinação RewriteCond / RewriteRule e vai para a parte com

RewriteCond %{SCRIPT_FILENAME} !-d  
RewriteCond %{SCRIPT_FILENAME} !-f  

RewriteRule ^.*$ ./index.php [L]

Que apenas redirecionamentos internos. E agora ele não está sendo combinado com o primeiro RewriteRule porque o RewriteRule está sendo ignorado por causa de [L] flag.

Estou certo? Alguém pode confirmar ou negar esta explicação? Ou talvez esclarecer isso?

    
por 23.10.2016 / 01:16