Mod_Rewrite comportamiento inesperado L flag

mi estructura de aplicación web es:

/var/www/myapp/ - www/ - index.php - css.php - .htaccess 

el host virtual está configurado como:

  ServerName www.example.org DocumentRoot /var/www/myapp/www DirectoryIndex index.php index.html  Options Indexes FollowSymLinks MultiViews AllowOverride All Order allow,deny allow from all   

En /var/www/myapp/www/.htaccess hay:

  RewriteEngine on RewriteBase / RewriteRule css css.php [L,NC] RewriteRule .* index.php  

Ahora, si llamo a www.example.org me redireccionan correctamente a index.php, pero si llamo a www.example.org/css, sigo siendo redirigido siempre a index.php.

Si dejo caer la línea “RewriteRule. * Index.php” y luego llamo a www.example.org/css, me redirigen correctamente a css.php.

¿Qué pasa? Muchas gracias a todos

======== EDITAR =========

 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b7080058/initial] (3) [perdir /var/www/sviluppo/mattia_dev/example/www/] add path info postfix: /var/www/sviluppo/mattia_dev/example/www/DEV_2 -> /var/www/sviluppo/mattia_dev/example/www/DEV_2/css/example1/test.css 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b7080058/initial] (3) [perdir /var/www/sviluppo/mattia_dev/example/www/] strip per-dir prefix: /var/www/sviluppo/mattia_dev/example/www/DEV_2/css/example1/test.css -> DEV_2/css/example1/test.css 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b7080058/initial] (3) [perdir /var/www/sviluppo/mattia_dev/example/www/] applying pattern '^(DEV|TEST|PROD)\_[0-9]+\/(css|js|image|static)\/(.+)$' to uri 'DEV_2/css/example1/test.css' 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b7080058/initial] (2) [perdir /var/www/sviluppo/mattia_dev/example/www/] rewrite 'DEV_2/css/example1/test.css' -> 'css/example1/test.css' 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b7080058/initial] (3) [perdir /var/www/sviluppo/mattia_dev/example/www/] add per-dir prefix: css/example1/test.css -> /var/www/sviluppo/mattia_dev/example/www/css/example1/test.css 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b7080058/initial] (2) [perdir /var/www/sviluppo/mattia_dev/example/www/] trying to replace prefix /var/www/sviluppo/mattia_dev/example/www/ with / 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b7080058/initial] (5) strip matching prefix: /var/www/sviluppo/mattia_dev/example/www/css/example1/test.css -> css/example1/test.css 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b7080058/initial] (4) add subst prefix: css/example1/test.css -> /css/example1/test.css 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b7080058/initial] (1) [perdir /var/www/sviluppo/mattia_dev/example/www/] internal redirect with /css/example1/test.css [INTERNAL REDIRECT] 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b63188e8/initial/redir#1] (3) [perdir /var/www/sviluppo/mattia_dev/example/www/] strip per-dir prefix: /var/www/sviluppo/mattia_dev/example/www/css/example1/test.css -> css/example1/test.css 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b63188e8/initial/redir#1] (3) [perdir /var/www/sviluppo/mattia_dev/example/www/] applying pattern '^(DEV|TEST|PROD)\_[0-9]+\/(css|js|image|static)\/(.+)$' to uri 'css/example1/test.css' 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b63188e8/initial/redir#1] (3) [perdir /var/www/sviluppo/mattia_dev/example/www/] strip per-dir prefix: /var/www/sviluppo/mattia_dev/example/www/css/example1/test.css -> css/example1/test.css 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b63188e8/initial/redir#1] (3) [perdir /var/www/sviluppo/mattia_dev/example/www/] applying pattern '.*' to uri 'css/example1/test.css' 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b63188e8/initial/redir#1] (2) [perdir /var/www/sviluppo/mattia_dev/example/www/] rewrite 'css/example1/test.css' -> 'index.php' 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b63188e8/initial/redir#1] (3) [perdir /var/www/sviluppo/mattia_dev/example/www/] add per-dir prefix: index.php -> /var/www/sviluppo/mattia_dev/example/www/index.php 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b63188e8/initial/redir#1] (2) [perdir /var/www/sviluppo/mattia_dev/example/www/] trying to replace prefix /var/www/sviluppo/mattia_dev/example/www/ with / 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b63188e8/initial/redir#1] (5) strip matching prefix: /var/www/sviluppo/mattia_dev/example/www/index.php -> index.php 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b63188e8/initial/redir#1] (4) add subst prefix: index.php -> /index.php 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b63188e8/initial/redir#1] (1) [perdir /var/www/sviluppo/mattia_dev/example/www/] internal redirect with /index.php [INTERNAL REDIRECT] 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b6310db8/initial/redir#2] (3) [perdir /var/www/sviluppo/mattia_dev/example/www/] strip per-dir prefix: /var/www/sviluppo/mattia_dev/example/www/index.php -> index.php 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b6310db8/initial/redir#2] (3) [perdir /var/www/sviluppo/mattia_dev/example/www/] applying pattern '^(DEV|TEST|PROD)\_[0-9]+\/(css|js|image|static)\/(.+)$' to uri 'index.php' 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b6310db8/initial/redir#2] (3) [perdir /var/www/sviluppo/mattia_dev/example/www/] strip per-dir prefix: /var/www/sviluppo/mattia_dev/example/www/index.php -> index.php 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b6310db8/initial/redir#2] (3) [perdir /var/www/sviluppo/mattia_dev/example/www/] applying pattern '.*' to uri 'index.php' 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b6310db8/initial/redir#2] (2) [perdir /var/www/sviluppo/mattia_dev/example/www/] rewrite 'index.php' -> 'index.php' 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b6310db8/initial/redir#2] (3) [perdir /var/www/sviluppo/mattia_dev/example/www/] add per-dir prefix: index.php -> /var/www/sviluppo/mattia_dev/example/www/index.php 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b6310db8/initial/redir#2] (1) [perdir /var/www/sviluppo/mattia_dev/example/www/] initial URL equal rewritten URL: /var/www/sviluppo/mattia_dev/example/www/index.php [IGNORING REWRITE] 

Parece que se produce un primer redireccionamiento, pero el mod_rewrite no deja de provocar un redireccionamiento interno. Luego, la URL modificada se pasa a mod_rewrite en otro momento y se produce una segunda redirección, pero ahora coincide con la segunda regla.

No puedo entenderlo porque coloqué la bandera [L] solo para asegurarme de que mod_rewrite se detenga.

Gracias otra vez

Te estás perdiendo un hecho importante sobre la bandera L :

Por lo tanto, es importante que, si utiliza directivas RewriteRule en uno de estos contextos [ .htaccess , ], tome medidas explícitas para evitar el bucle de reglas y no cuente únicamente con el indicador [L] para finalizar la ejecución de un serie de reglas

Desde: L | last (Flag) ; atrevido por mi

Eso significa que solo al usar la L no tiene el efecto deseado para evitar el redireccionamiento interno. El INTERNAL REDIRECT sucede aquí porque debe suceder, lo ha especificado con su configuración .htaccess . La bandera L no es la bandera correcta para evitar el INTERNAL REDIRECT .

Veamos más de cerca tu pregunta y lo que realmente sucede:

No puedo entenderlo porque coloqué la bandera [L] solo para asegurarme de que mod_rewrite se detenga.

Es solo que tienes una comprensión incorrecta de la bandera L Solo se detendrá para la reescritura actual, es decir, las directivas RewriteRule debajo de ella no se procesarán en la ronda actual (el ciclo interno).

Si el URI cambió, L volverá a inyectarse en la próxima ronda (el bucle externo) como muestra el siguiente diagtwig de flujo de detalles técnicos :

http://httpd.apache.org/docs/current/rewrite/tech.html

Para resaltar dónde entra la bandera L y dónde ocurre el INTERNAL REDIRECT , este es el mismo gráfico con algunas anotaciones para su específica (primera) reescritura de URI:

enter image description here

Muestra que la bandera L solo sale del bucle interno, pero si el URI se reescribió (modificó), como en su caso, el bucle externo se ocupará de que el URI modificado se pase de nuevo a todas las reglas de reescritura.

En su lugar, es posible que desee formular una condición como se muestra en el siguiente ejemplo de esa parte del manual:

 RewriteBase / RewriteCond %{REQUEST_URI} !=/index.php RewriteRule ^(.*) /index.php?req=$1 [L,PT] 

( PT tiene su propia entrada manual , es más o menos no parte de la solución, solo se nota porque cité el ejemplo tal como está)

Lo que realmente quiere usar es la bandera END :

 RewriteRule css css.php [END,NC] 

Sin embargo, póngase en contacto con el administrador de su sistema si tiene la versión apache necesaria (disponible en 2.3.9 y posteriores). De lo contrario, debe operar con RewriteCond .

La respuesta de hakre ilustra bien lo que está sucediendo. Además de usar la bandera END , tienes algunas opciones más:

  • Use %{ENV:REDIRECT_STATUS} para evitar nuevas reescrituras. Esto cambiará después de una redirección interna. Consulte esta página para obtener más información sobre lo que está sucediendo realmente:

     RewriteCond %{ENV:REDIRECT_STATUS} ^$ RewriteRule css css.php [L,NC] 
  • Use %{THE_REQUEST} para hacer coincidir la solicitud que se realizó con el servidor. Como esto no cambia cuando redirige internamente, esto puede usarse para evitar nuevas redirecciones

     RewriteCond %{THE_REQUEST} ^(GET|POST)\ /css\ HTTP RewriteRule ^ css.php [L,NC] 
  • Use una variable ficticia en la cadena de consulta. Esto permitiría evitar la redirección al definir esta variable en un enlace, pero la usaremos aquí para evitar múltiples pases:

     RewriteCond %{QUERY_STRING} !noredir=1 RewriteRule css css.php?noredir=1 [L,QSA,NC] 

Tenga en cuenta que para cada uno de estos ejemplos necesita usar esta construcción para cada regla individual.