
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>