Cómo evitar que Apache reinicie el procesamiento de reescritura dentro de un "contexto de directorio"

Cómo evitar que Apache reinicie el procesamiento de reescritura dentro de un "contexto de directorio"

Tengo lo siguiente en mi host virtual para conexiones SSL (mi host virtual no SSL tiene el mismo aspecto, pero sin la primera regla establecida para la redirección).

DocumentRoot /var/www/example.com/public/
<Directory "/var/www/example.com/public/">
  #only mod_rewrite configuration is shown here

  RewriteEngine on
  RewriteBase /

  RewriteCond $1 !=signup
  RewriteCond $1 !=login
  RewriteCond $1 !=welcome
  RewriteCond $1 !=thankyou
  RewriteRule ^(.*)$ http://example.com/$1 [L,R,QSA]

  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_URI} !=/favicon.ico
  RewriteRule ^(.+)$ index.php?q=$1 [L,QSA]
</Directory>

Mi intención es que cualquier solicitud de página que no coincida (registro|iniciar sesión|bienvenido|gracias) sea redirigida al host virtual no SSL sin procesamiento adicional; de lo contrario, no redirija, sino procese la solicitud dentro del host virtual SSL.

El primer conjunto de RewriteRule se encarga del redireccionamiento, mientras que el segundo conjunto de RewriteRule se encarga del procesamiento normal de la página.

Sin el primer conjunto de reglas, todas las solicitudes se cargan correctamente en el host virtual SSL.

Con el primer conjunto de reglas, las redirecciones funcionan bien si no coinciden con los recursos enumerados. p.ej. una solicitud de

https://example.com/about

redirige a

http://example.com/about

Pero al solicitar las páginas de registro, inicio de sesión, bienvenida y agradecimiento, surge el problema. Esas solicitudes también se redirigen al sitio que no es SSL, pero de forma rota. una solicitud de

https://example.com/signup

redirige a

http://example.com/index.php?q=signup

Parecería que el primer conjunto de reglas no coincide (como era de esperar), luego, después de que se procesa el segundo conjunto de reglas, el primer conjunto de reglas se aplica nuevamente (no se esperaba).

No puedo relacionar este comportamiento inesperado con ninguna funcionalidad documentada.

¿Algunas ideas?

Editar

Encontré algunas referencias oscuras en la documentación sobre cómo Apache vuelve a ejecutar las reglas cuando ocurre una coincidencia de reglas dentro de un "contexto de directorio", sin embargo, la referencia se refería a .htaccess. Mi reescritura se produce dentro de una etiqueta <Directory> dentro de mi etiqueta <VirtualHost>. Actualmente estoy probando mover la reescritura fuera del contexto <Directorio>; esto ciertamente parece cambiar el comportamiento, pero todavía no lo he hecho funcionar como necesito.

Editar2

El problema ciertamente se debe a que Apache reinicia el procesamiento de reescritura cuando el procesamiento de reglas existe dentro de un contexto de directorio. Moví el procesamiento de reglas fuera de la etiqueta <Directorio>. Sin embargo, ahora las líneas RewriteCond no funcionan... por ejemplo.

RewriteCond %{REQUEST_FILENAME} -f

porque Apache aún no ha resuelto el recurso solicitado en una asignación de archivos utilizando DocumentRoot. Que desastre.

Entonces, luego antepongo manualmente el valor que especifico en DocumentRoot a RewriteCond. Sin embargo, esto parece un truco pobre. p.ej.

RewriteCond /var/www/example.com/public%{REQUEST_FILENAME} -f

Entonces, ahora estoy buscando una manera de evitar que Apache reinicie el proceso de reescritura cuando esté dentro del contexto de un directorio, o en segundo lugar, una mejor manera de especificar las RewriteConds necesarias en el nivel <VirtualHost>.

Respuesta1

Sugiero agregar lo siguiente a su configuración, que le brindará un registro detallado de lo que está haciendo mod_rewrite y por qué. Eso puede ayudar a aclarar por qué tiene ese comportamiento:

RewriteLog /tmp/rewrite.log
RewriteLogLevel 9

Una vez que haya terminado de analizar esto, asegúrese de eliminar estas líneas, ya que afectan el rendimiento.

Respuesta2

Me decidí por la siguiente solución: colocar las reescrituras fuera de cualquier sección <Directorio...>. Esto me permite redirigir cualquier solicitud que no debería ser SSL al sitio que no es SSL y, al mismo tiempo, permite que cualquier contenido estático se entregue a través de SSL (imágenes, css, js, etc.).

<VirtualHost ...>
  ...
  RewriteEngine on

  RewriteCond $1 !=signup
  RewriteCond $1 !=login
  RewriteCond $1 !=welcome
  RewriteCond $1 !=thankyou
  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d
  RewriteRule ^/(.*)$ http://example.com/$1 [R=303,QSA,L]

  RewriteCond %{REQUEST_URI} !=/favicon.ico
  RewriteCond %{REQUEST_URI} !=/robots.txt
  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d
  RewriteRule ^/(.+)$ /index.php?q=$1 [QSA,L]
  ...
</VirtualHost>

información relacionada