Reescreva o Problema – L (ast) não sendo respeitado?

Então, estou trabalhando em um sistema de compactação CSS / JS para um site, que tem basicamente o seguinte htaccess

RewriteEngine On ... RewriteRule ^css/images/(.*)$ images/site/$1?%{QUERY_STRING} [L] RewriteRule ^css/([0-9a-fA-F]{32})$ assets.php?hash=$1 [L] RewriteCond %{HTTP_HOST} ^www.site.com [NC] RewriteRule ^(.*)$ http://site.com/$1 [L,R=301] RewriteRule ^([a-zA-Z0-9_.-]+)$ index.php?url=$1&%{QUERY_STRING} [L] php_flag register_globals off php_flag magic_quotes_gpc off php_flag register_long_arrays off # 404 Handler RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php?url=$1&%{QUERY_STRING} 

Agora, assets.php não está recebendo a chamada de hash, mas sim index.php – se eu remover a linha RewriteRule ^([a-zA-Z0-9_.-]+)$ index.php?url=$1&%{QUERY_STRING} [L]

funciona bem, mas eu não sei porque – o sinalizador [L] nos resources não deve rewrite RewriteRule ^css/([0-9a-fA-F]{32})$ assets.php?hash=$1 [L] impede que novas reescritas sejam executadas? Estou confuso com o que está acontecendo aqui.

Qualquer luz que você pudesse lançar sobre isso seria muito apreciada.

A bandeira L diz “não execute mais nenhuma regra no conjunto de regras”, o que curiosamente não significa que nenhuma outra regra será executada pelo mod_rewrite .

Quando você especifica diretivas mod_rewrite em um contexto por diretório, como com .htaccess ou a seção Directory de uma configuração de servidor ou servidor virtual, a reconfiguração vem atrasada no estágio de processamento do Apache. Para fazer sua mágica aqui, o mod_rewrite precisa executar um redirecionamento interno toda vez que seu URL for reescrito.

Como a sua reescrita poderia direcioná-lo para um diretório diferente, o mod_rewrite atribui a si próprio como o manipulador para esse redirecionamento, de modo que ele possa passar por quaisquer regras que ele possa encontrar no novo local para o qual você enviou a solicitação. Muitas vezes, como você está lidando apenas com um único arquivo .htaccess em sua raiz, as regras na “nova” localização são as que causaram a reescrita em primeiro lugar.

Então, no seu caso, acontece o seguinte:

  • Pedido feito para /css/A01EF
  • mod_rewrite inicia o conjunto de regras
  • ^css/([0-9a-fA-F]{32})$ -> assets.php?hash=A01EF
  • L flag pára de rewrite e força o redirecionamento interno para assets.php?hash=A01EF
  • mod_rewrite inicia o conjunto de regras novamente
  • ^([a-zA-Z0-9_.-]+)$ -> index.php?url=assets.php&hash=A01EF (você pode usar o QSA aqui, a propósito)
  • L flag pára de rewrite e força o redirecionamento interno para index.php?url=assets.php&hash=A01EF

É provável que esse loop continue, mas o mod_rewrite reconhece que você está redirecionando para a mesma página e ignora sua reescrita depois desse ponto.

Todo este processo acontece por que as duas condições …

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

… são tão comuns em conjuntos de regras do .htaccess mod_rewrite , uma vez que fornecem uma maneira fácil de determinar se a URL já foi reescrita para o recurso real pretendido. Você poderia usá-los, ou você pode excluir o index.php rewrite quando o pedido foi reescrito para assets.php :

 RewriteCond %{REQUEST_URI} !^/assets.php RewriteRule ^([a-zA-Z0-9_.-]+)$ index.php?url=$1&%{QUERY_STRING} [L]