Como posso evitar um erro neste arquivo .htaccess?

2

Eu tenho um blog. O blog é armazenado sob o prefixo /blog/ no meu site. Ele tem os URLs comuns de um blog, por isso os artigos têm URLs no formato /blog/:year/:month/:day/:title/ .

Antes de mais nada, quero redirecionar automaticamente os visitantes para o subdomínio www (caso eles deixem isso desativado) e internamente reescrever o URL raiz para /blog/ , para que a frente A página do blog aparece na primeira página do site. Eu consegui isso com o seguinte conjunto de regras de reescrita no meu arquivo .htaccess :

RewriteEngine On

# Rewrite monkey-robot.com to www.monkey-robot.com
RewriteCond %{HTTP_HOST} ^monkey-robot\.com$
RewriteRule ^(.*)$ http://www.monkey-robot.com/$1 [R=301,L]

RewriteRule ^$             /blog/               [L]
RewriteRule ^feeds/blog/?$ /feeds/blog/atom.xml [L]

Isso funciona bem. O problema é que a primeira página do blog agora aparece em duas URLs distintas: / e /blog/ . Então, eu gostaria de redirecionar a URL /blog/ para o URL raiz. Inicialmente, tentei fazer isso com o seguinte conjunto de regras de reescrita:

RewriteEngine On

# Rewrite monkey-robot.com to www.monkey-robot.com
RewriteCond %{HTTP_HOST} ^monkey-robot\.com$
RewriteRule ^(.*)$ http://www.monkey-robot.com/$1 [R=301,L]

RewriteRule ^$             /blog/               [L]
RewriteRule ^blog/?$       /                    [R,L]
RewriteRule ^feeds/blog/?$ /feeds/blog/atom.xml [L]

Mas isso me deu um redirecionamento infinito (talvez por causa da regra anterior?). Então tentei este conjunto:

RewriteEngine On

# Rewrite monkey-robot.com to www.monkey-robot.com
RewriteCond %{HTTP_HOST} ^monkey-robot\.com$
RewriteRule ^(.*)$ http://www.monkey-robot.com/$1 [R=301,L]

RewriteRule ^$             /blog/                       [L]
RewriteRule ^blog/?$       http://www.monkey-robot.com/ [R,L]
RewriteRule ^feeds/blog/?$ /feeds/blog/atom.xml         [L]

Mas recebi um 500 Internal Server Error com a seguinte mensagem de log:

Invalid command '[R,L]', perhaps misspelled or defined by a module not included in the server configuration

O que dá? Não acho que [R,L] seja um erro de sintaxe.

    
por mipadi 18.05.2010 / 20:14

2 respostas

2

Eu suspeito que você possa evitar o loop infinito em seu segundo conjunto de regras colocando as diretivas de reconfiguração na configuração principal do host virtual, não em um arquivo .htaccess . Em geral, isso é uma boa prática, já que a regravação é muito mais rápida quando você a coloca no host virtual, e você pode obter mais benefícios de velocidade se puder dizer ao Apache para ignorar .htaccess arquivos juntos.

A lógica por trás disso é explicada na documentação técnica do mod_rewrite . Aqui está a essência: como você sabe, as regras de reescrita podem alterar o nome do arquivo a que uma determinada solicitação corresponde, e até mesmo em qual diretório o arquivo resultante está. De fato, o seu

RewriteRule ^$ /blog/

é um exemplo perfeito, que altera a raiz do documento para o diretório blog . Mas o Apache precisa saber o diretório para descobrir quais arquivos .htaccess devem verificar a solicitação. Talvez você possa ver o problema aqui: no momento em que o Apache alcança seu arquivo .htaccess , ele determinou o nome do arquivo que deveria estar acessando, o que significa que é tarde demais para suas regras de reescrita aplicar.

O Apache internamente resolve esse problema criando uma nova subrequisa, que inicia o processamento desde o início, e injetando as regras do seu arquivo .htaccess no fluxo de processamento para que elas sejam aplicadas à solicitação. Como um efeito colateral disso, todas regras de reescrita aplicáveis são aplicadas novamente , e isso significa que o [L] é um tipo de mentira quando você o usa em .htaccess file. Então, mesmo que você coloque [L] em sua regra para tentar forçá-la a ser a última regra aplicada, ela realmente não é; todas as regras são aplicadas novamente quando o Apache processa sua sub-requisição interna.

Se você não tiver acesso à configuração principal do servidor, poderá fazer isso:

RewriteRule ^/blog/?$    /           [R,L,NS]

O sinalizador NS impede que a regra seja aplicada a sub-solicitações.

    
por 18.05.2010 / 23:54
0

Depois de ler os comentários, acho que a solução mais simples é reescrever a página raiz para o arquivo real ( index.html , suponho?).

RewriteRule ^blog/$ / [R,L]
RewriteRule ^$ /blog/index.html [L]

Desta forma, o looping pode ser evitado. Um problema continua - o /blog/index.html ainda é acessível externamente . Se isso não for uma opção, acho que sua melhor aposta é seguir o conselho do David e mover a configuração um nível acima.

Algumas alternativas que me vieram à mente:

  • Deixe /blog/index.html acessível e use link canônico (não é o melhor, mas é fácil)
  • Se o script do servidor ( PHP provavelmente) estiver acessível, redirecione /blog/index.php para / no nível do script
por 19.05.2010 / 13:42