OK he descubierto una manera de hacerlo.
Lo que hice fue utilizar mod_rewrite
que es un módulo de Apache (incluido por defecto en todas las instalaciones) para reescribir sobre la marcha las URL solicitadas. Aquí está el código:
# Custom error pages
ErrorDocument 404 /hidden/404/index.html
ErrorDocument 403 /hidden/403/index.html
# Pretend that /hidden doesn't exist
# (unless this is an internal redirect,
# such as rendering a 404 or 403)
RewriteCond %{ENV:REDIRECT_STATUS} =""
RewriteRule ^/hidden/.* - [L,R=404]
Así que vamos a recorrer estas líneas. El ErrorDocument
no han cambiado - sólo dicen qué página debe ser servida cuando se produce un error dado.
La verdadera carne está en el RewriteCond
y RewriteRule
directivas. Lo que la RewriteRule
es la siguiente: si se solicita una url cuya ruta coincide con la expresión regular ^/hidden/.*
(esencialmente, cualquier ruta que sea a cualquier cosa en /hidden/ o su subárbol), deje la url sin cambios (eso es lo que hace el comando -
significa), pero no interprete más RewriteRule
(eso es lo que hacen las directivas L
significa), y devolver un código de error 404 (que es lo que el R=404
significa).
Esto, combinado con la ErrorDocument 404 /hidden/404/index.html
puede parecer suficiente. El problema, sin embargo, es que cuando Apache va a servir /hidden/404/index.html
vuelve a repasar estas reglas. Esto significa que el RewriteRule
que a su vez dice renderizar el 404, y todo el asunto se repite infinitamente.
Así, utilizamos el RewriteCond
para asegurarse de que esto no ocurra. RewriteCond
son condicionales: la directiva RewriteRule
sólo se ejecutará si se cumple la condición. La condición en este caso es "la variable de entorno REDIRECT_STATUS
es igual a la cadena vacía". Ahora, REDIRECT_STATUS
es una variable de entorno que se establece mediante ErrorDocument
y contiene el código de estado que se está redirigiendo (por lo tanto, si el archivo ErrorDocument 404 ...
se establecería el valor "404"). Sin embargo, si no se ErrorDocument
se había ejecutado, entonces REDIRECT_STATUS
no se habría establecido, por lo que preguntar por su valor simplemente devolvería la cadena vacía. Por lo tanto, RewriteCond %{ENV:REDIRECT_STATUS} =""
esencialmente dice, "no te molestes en evaluar el RewriteRule
a menos que no estemos sirviendo una página de error".
nota: si ha mirado el RewriteRule
se habrá dado cuenta de que R
debe realizar una redirección explícita. La razón por la que funciona bien en este caso es que existe una característica no documentada de la directiva R
que es que sólo redirige en códigos de clase 300. Por lo tanto, R=404
no hace una redirección explícita, sólo una interna.