mod_rewrite enviar todo lo que no emparejado a un RewriteMap
-
19-09-2019 - |
Pregunta
Tengo un archivo .htaccess que comienza con la materia normal:
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
a continuación, tiene un par de reescrituras por ejemplo:
RewriteRule ^protect/?$ /Legal/Your-Financial-Protection.aspx [NC, L, R=301]
luego termina con un RewriteMap:
RewriteMap map txt:rewritemaps/map.txt [NC]
RewriteRule ^(.+)$ ${map:$1} [R=301]
El RewriteMap contiene todas nuestras direcciones URL de legado - páginas de nuestro sitio actual y URLs cortas que serán redirigidos a páginas equivalentes en el nuevo sitio (hay cerca de 4k, por lo que es necesario utilizar un mapa de verdad):
Inspiration.aspx /Inspiration.aspx
Destinations/Africa/Countries/Gabon.aspx /Destinations/Africa/Gabon.aspx
indonesia /Destinations/Southeast-Asia/Indonesia.aspx
El problema es que, con el RewriteMap activado (es decir, no comentada), todos mis URL (incluso los que no coincide) redirigir a / -. Incluyendo hojas de estilo, JS, imágenes, etc
Lo que busco es URIs que coinciden con el patrón en el mapa para redirigir a la sustitución y todo lo demás para pasar a través (es decir, permanecen igual).
He tratado de establecer un valor predeterminado de $ 1 en el mapa:
RewriteRule ^(.+)$ ${map:$1|$1} [R=301]
pero esto sólo provoca un bucle de redireccionamiento. Creo que yo también podría omitir la reescritura para todos css, js, .jpg, etc, pero preferirían no tener que mantener una lista de extensiones de archivos usados.
Para su información, estoy usando ISAPIRewrite de HeliconTech (como estoy en IIS 6) aunque afirma que para manejar rewritemaps según Apache y nunca he tenido problemas en el pasado.
Cualquier ayuda sería enormemente apreciada!
Gracias, Adam
Solución
Sólo hay que poner solamente los pares en el mapa que realmente se diferencian. De lo contrario se redirigir al mismo valor y obtener una recursión infinita.
Y para redirigir sólo cuando se encuentra una coincidencia, intente lo siguiente:
RewriteCond ${map:$1} ^/.+
RewriteRule ^(.+)$ %0 [R=301]
Otros consejos
Esta línea es el problema:
RewriteMap map txt:rewritemaps/map.txt [NC]
No se puede definir un RewriteMap en un archivo .htaccess. (Ver documentos RewriteMap) Debe definir el mapa en el servidor o host virtual contexto, y luego se pueda hacer referencia en su archivo .htaccess. Si sube el nivel de registro lo suficientemente alto, verá una advertencia de que el mapa no está siendo cargado.
La solución de Gumbo es genial, excepto que no parece para manejar el URL de con espacios. http://www.webmasterworld.com/apache/3830228.htm ofrece información sobre las cómo manejar los espacios, la combinación de los dos, así:
RewriteCond ${moved:${escape:$1}} ^/.+
RewriteRule ^(.+)$ %0 [R=301]
No funciona. Maldición odio mod_rewrite
IPADDR - - [07/Jan/2010:01:44:58 --0500] [example.org/sid#842a5a8][rid#100e0a18/initial] (2) init rewrite engine with requested uri /press/Partners With City.pdf
IPADDR - - [07/Jan/2010:01:44:58 --0500] [example.org/sid#842a5a8][rid#100e0a18/initial] (3) applying pattern '^(.+)$' to uri '/press/Partners With City.pdf'
IPADDR - - [07/Jan/2010:01:44:58 --0500] [example.org/sid#842a5a8][rid#100e0a18/initial] (5) map lookup OK: map=escape key=/press/Partners With City.pdf -> val=/press/Partners%20With%20City.pdf
IPADDR - - [07/Jan/2010:01:44:58 --0500] [example.org/sid#842a5a8][rid#100e0a18/initial] (6) cache lookup FAILED, forcing new map lookup
IPADDR - - [07/Jan/2010:01:44:58 --0500] [example.org/sid#842a5a8][rid#100e0a18/initial] (5) map lookup FAILED: map=moved[txt] key=/press/Partners%20With%20City.pdf
IPADDR - - [07/Jan/2010:01:44:58 --0500] [example.org/sid#842a5a8][rid#100e0a18/initial] (4) RewriteCond: input='' pattern='^/.+' => not-matched
Adam, las reglas del Gumbo incluye la barra inicial en la clave, y la versión de su mapa publicado ellas no se encuentra.
RewriteLogLevel 9 es muy útil para el descubrimiento de cosas como esta.