RewriteRule para raiz sem o sinalizador R não está funcionando

2

Estou tentando fazer um sistema de cache com arquivos. E eu estava pensando em usar mod rewrite para servir o arquivo em cache, se existir, ou o arquivo php (que irá criar o cache estático html) se não.

Aqui está a primeira amostra que eu criei

         <IfModule mod_rewrite.c>
            RewriteEngine On

            RewriteRule ^$ /cache/home.html [L,NC]
            RewriteCond %{REQUEST_URI} /cache/
            RewriteCond %{REQUEST_FILENAME} !-f
            RewriteRule ^cache/home.html /index.php [L]

            RewriteRule ^page/([0-9]*) /cache/page_$1.html [L,NC]
            RewriteCond %{REQUEST_URI} /cache/
            RewriteCond %{REQUEST_FILENAME} !-f
            RewriteRule ^cache/page_([0-9]*).html /page.php?&id=$1 [L]
        </IfModule>

Isso funciona corretamente para as páginas internas. Se eu ligar para o link ou link ele serve corretamente o arquivo em cache ou a página do php, dependendo se o arquivo existe ou não.

O problema é que ele não funciona para o link

do site principal

Se eu adicionar um sinalizador de redirecionamento para a casa, ele realmente funcionará corretamente

RewriteRule ^$ /cache/home.html [L,NC,R]

Mas, obviamente, nesse caso, se eu ligar para o site principal e receber um link , não é o que eu estava procurando.

Aqui estão algumas linhas de log em que o problema pode estar:

[Wed Aug 05 11:59:11.751277 2015] [rewrite:trace1] [pid 30670] mod_rewrite.c(468): [client 10.1.1.1:53595] 10.1.1.1 - - [m.site.com/sid#7f7850ecb038][rid#7f7850e480a0/initial] [perdir /home/www/site.com/public/mobile/] internal redirect with /cache/home.html [INTERNAL REDIRECT]
[Wed Aug 05 11:59:11.751339 2015] [rewrite:trace3] [pid 30670] mod_rewrite.c(468): [client 10.1.1.1:53595] 10.1.1.1 - - [m.site.com/sid#7f7850ecb038][rid#7f7850e420a0/subreq] [perdir /home/www/site.com/public/mobile/] strip per-dir prefix: /home/www/site.com/public/mobile/index.html -> index.html

Enquanto estiver com a bandeira R

[Wed Aug 05 12:04:34.333591 2015] [rewrite:trace1] [pid 31746] mod_rewrite.c(468): [client 10.1.1.1:53613] 10.1.1.1 - - [m.site.com/sid#7f7850ec1038][rid#7f7850e440a0/initial] [perdir /home/www/site.com/public/mobile/] redirect to http://m.cmstest.site.com/cache/home.html [REDIRECT/302]
[Wed Aug 05 12:04:34.343609 2015] [rewrite:trace3] [pid 31746] mod_rewrite.c(468): [client 10.1.1.1:53613] 10.1.1.1 - - [m.site.com/sid#7f7850ec1038][rid#7f7850e420a0/initial] [perdir /home/www/site.com/public/mobile/] strip per-dir prefix: /home/www/site.com/public/mobile/cache/home.html -> cache/home.html

Parece que o primeiro, sem o sinalizador R, depois de fazer o correto REDIRECT INTERNO para cache / home.html, vai procurar por index.html (que na verdade não existe)

    
por Kesty 31.07.2015 / 16:34

2 respostas

0

O problema parece estar nos sub-questionamentos, como nesta resposta: link

Como visto no log, após o primeiro redirecionamento interno correto, a segunda chamada é para uma subsequest que tenta encontrar um index.html no diretório raiz.

Eu tentei adicionar a opção -MultiViews como na resposta que eu vinculei, mas que ainda não funcionou. O Apache ainda estava procurando na sub-requisição na raiz do site.

Então acabei com uma pequena solução "hack" que verificará se a solicitação é uma subsequação e, nesse caso, se estiver procurando por um arquivo index.* na raiz, ele redirecionará para /cache/home.html

        RewriteCond %{IS_SUBREQ} t
        RewriteCond %{REQUEST_URI} ^(/index.\w+|/)?$
        RewriteRule ^ /cache/home.html [L]

Isso funciona bem, no sentido de que acaba fazendo exatamente o que eu estava tentando fazer.

Vou deixar a questão aberta por mais algum tempo, porque isso ainda parece uma solução de "hack". Não sei se existe um melhor que funcione bloqueando diretamente esses sub-questionamentos.

    
por 05.08.2015 / 14:57
1

Sua primeira regra diz:

RewriteRule ^$ /cache/home.html [L,NC]

O sinalizador L diz ao mod_rewrite para parar o processamento nesse ponto, que é o problema que você está perguntando. A solução alternativa 'R' significa que a nova regra será regravada conforme o esperado, na segunda solicitação, mas o L a impedirá na primeira. Além disso, o sinalizador NC é redundante aqui, pois não pode haver caracteres de caminho a serem afetados pela diferenciação entre maiúsculas e minúsculas.

Embora não faça parte da sua pergunta, reconsidere o seguinte.

RewriteRule ^cache/home.html /index.php [L]

Você provavelmente deseja corresponder com ^cache/page.html$ , para que não aceite cache/home.htmlxyz , o impacto prático provavelmente será mínimo. Também há a regra:

RewriteRule ^page/([0-9]*) /cache/page_$1.html [L,NC]

As bandeiras são provavelmente inadequadas como antes. O NC flag realmente faz alguma coisa aqui, mas eu diria que é indesejável. Considere também que a sequência numérica em seu regex pode ser de comprimento zero, o que eu suspeito que não seja desejável, então talvez você queira ([0-9]+) ? Você provavelmente também quer terminar com um '$', como no presente você vai corresponder, por exemplo /page/foobar e você também não quer corresponder /page/123foobar . Então você teria:

RewriteRule ^page/([0-9]+)$ /cache/page_$1.html

EDITAR:

Veja os comentários abaixo sobre por que a correspondência ^$ pode não funcionar para você. Além disso, se a correção não funcionar, adicione mod_rewrite:trace3 ao seu < Uma diretriz href="http://httpd.apache.org/docs/2.4/mod/core.html#loglevel"> LogLevel e descobrir exatamente onde ela está dando errado. A saída é detalhada, mas você aprenderá muito e, se ainda estiver intrigado, terá mais detalhes para nos trazer de volta.

    
por 05.08.2015 / 09:27