Guía básica del mod_rewrite

Hablando de mod_rewrite siempre saltan las dudas, normalmente lo más problemático suelen ser las expresiones regulares así que he decidido reunir en una entrada toda la información que he recolectado sobre el tema.

Empiezo por dos cheatsheets que deberían ser un musthave para cualquier sysadmin, aquí las dejo para descarga y/o visualización: Nota: Post en actualización constante, se irán tanto agregando nuevos ejemplos como features que se vayan usando.

Sintaxis de expresiones regulares

La regexp syntax tiene 4 ó 5 reglas básicas que son sencillas de entender, vamos a ello:
  • ^.- Comienzo de cadena.
  • $.- Fin de cadena.
  • ..- Cualquier caracter simple.
  • (a|b).- Opcional entre a y b.
  • (...).- Sección de grupo.
  • [abc].- Item en rango (a, b ó c).
  • [^abc].- Negación de item en rango (ni a, ni b, ni c).
  • a?.- Cero ó 1 "a".
  • a*.- Cero o más "a".
  • a+.- Una o más "a".
  • a{3}.- Exactamente 3 "a".
  • a{3,}.- 3 ó más "a".
  • a{3,6}.- De 3 a 6 "a".
  • !(patron).- Aplicar regla cuando la URL no coincida con el patrón.
  • \\.- Escapa un caracter especial.

Patrones de condición

  • < condición.- Menor que condición.
  • > condición.- Mayor que condición.
  • = condición.- Igual a condición.
  • -d.- Es directorio.
  • -f.- Es archivo regular.
  • -s.- Es archivo con tamaño mayor de cero.
  • -l.- Es enlace simbólico.
  • -F.- Comprueba si el archivo existe y es accesible vía URL.
  • -U.-Comprueba si la URL existe y es accesible.

RewriteRule flags

  • [NC].- No Case, hace el patrón case insensitive, da igual mayúsculas que minúsculas.
  • [R=code].- Redirecciona a una nueva URL con un código opcional [300-400] para indicar error, redirección...
  • [F].- Forbidden, envía un 403.
  • [L].- Last Rule, trata a la regla como si fuera la última, para el proceso de rewrite en esta linea.
  • [C].- Chain, concatena una regla con la siguiente, si la regla coincide sigue con las concatenadas, si no coincide las salta.
  • [T=mime-type].- Fuerza un mime-type específico "application/x-httpd-cgi" o lo que sea.
  • [NE].- Not Escape output, para no escapar los caracteres raros por urlcode(), por ejemplo si queremos que un espacio siga siendo espacio y no %20%.
  • [S=x].- Skip, se salta las siguientes x reglas.
  • [E=var:value].- Enviroment, crea una variable de entorno var con el valor value.

Variables de servidor

  • %{NAME_OF_VAR}.- Para referirnos a una variable cualquiera, creada por ejemplo con la opción [E=var:val] vista antes.
  • %{HTTP_USER_AGENT}
  • %{HTTP_REFERER}
  • %{HTTP_COOKIE}
  • %{HTTP_FORWARDED}
  • %{HTTP_HOST}
  • %{HTTP_PROXY_CONNECTION}
  • %{HTTP_ACCEPT}
  • %{REMOTE_ADDR}
  • %{REMOTE_HOST}
  • %{REMOTE_USER}
  • %{REMOTE_IDENT}
  • %{REQUEST_METHOD}
  • %{SCRIPT_FILENAME}
  • %{PATH_INFO}
  • %{QUERY_STRING}
  • %{AUTH_TYPE}
  • %{DOCUMENT_ROOT}
  • %{SERVER_ADMIN}
  • %{SERVER_NAME}
  • %{SERVER_ADDR}
  • %{SERVER_PORT}
  • %{SERVER_PROTOCOL}
  • %{SERVER_SOFTWARE}
  • %{TIME_YEAR}
  • %{TIME_MON}
  • %{TIME_DAY}
  • %{TIME_MIN}
  • %{TIME_SEC}
  • %{TIME_WDAY}
  • %{TIME}
  • %{API_VERSION}
  • %{THE_REQUEST}
  • %{REQUEST_URI}
  • %{REQUEST_FILENAME}
  • %{IS_SUBREQ}

Directivas

  • RewriteEngine
  • RewriteOptions
  • RewriteLog
  • RewriteLogLevel
  • RewriteLock
  • RewriteMap
  • RewriteBase
  • RewriteCond
  • RewriteRule

Ejemplos

Se irán agregando más ejemplos según vayan apareciendo casos curiosos:
  • Redirigir un dominio a otro (301):
RewriteCond   %{HTTP_HOST}   ^www.domain.com$   [NC]
RewriteRule   ^(.*)$   http://www.domain2.com/$1   [R=301,L]
  • Varios ejemplos:
RewriteRule   ^page.html$   new_page.html   [R,NC,L]
RewriteRule   ^([A-Za-z0-9-]+)/?$   categories.php?name=$1 [L]
RewriteRule   ^articles/([A-Za-z0-9-]+)/([0-9]+)/?$ article.php?name=$1&page;=$2 [L]
  • Parando el spam de weight y drugs, por ejemplo:
RewriteCond  %{HTTP_REFERRER}  (weight)  [NC,OR]
RewriteCond  %{HTTP_REFERRER}  (drugs)  [NC]
RewriteRule  .*  -  [F]
  • Redirigir un dominio a otro directorio:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www.domain.com$
RewriteCond %{REQUEST_URI} !^/HTML2/
RewriteRule ^(.*)$ /HTML2/$1

Recursos

About the author

Óscar
has doubledaddy super powers, father of Hugo and Nico, husband of Marta, *nix user, Djangonaut and open source passionate.