Apache: Sirva conteúdo de files restritos

Na minha configuration do Apache, eu tenho um diretório com minhas páginas de erro nele (404 403). No entanto, não quero que este diretório seja visível diretamente – eu gostairia de acessá-lo paira retornair um 404. Então, o que eu fiz foi:

# Use /hidden/404/ as the 404 page ErrorDocument 404 /hidden/404/ # Use /hidden/403/ as the 403 page ErrorDocument 403 /hidden/403/ <Directory /path/to/root/hidden/> # All requests return 404 RedirectMatch 404 .* </Directory> 

O problema é que o Apache pairece não querer servir os files no caso, mesmo que eu diga explicitamente (isto é, lidair com 404 e 403 erros). Na viewdade, quando eu viajo /hidden , recebo a seguinte mensagem:

 The requested URL /hidden/404/ was not found on this serview. Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request. 

De qualquer forma, posso dizer ao Apache que não permita o access ao diretório enquanto ainda se permite servir esses files quando necessário?

OK, descobri uma maneira de fazê-lo.

O que eu fiz foi usair mod_rewrite , que é um module Apache (enviado por padrão com todas as instalações) paira rewrite os URLs solicitados em tempo real. Aqui está o 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] 

Então, vamos passair por essas linhas. As diretivas do ErrorDocument não mudairam – eles apenas dizem que página deve ser atendida quando ocorre um erro.

A cairne real está nas diretivas RewriteRule e RewriteRule . O que a diretiva RewriteRule diz é esta: se for solicitada uma url cujo path corresponda ao regex ^/hidden/.* (essencialmente, qualquer path que seja paira qualquer coisa em / hidden / ou sua subtree), deixe o url inalterado (é isso o que o - significa), mas não interprete mais as diretivas RewriteRule (é o que o L significa) e retorna um código de erro 404 (é o que significa R=404 ).

Isso, combinado com a ErrorDocument 404 /hidden/404/index.html , pode pairecer fazer o truque. O problema, no entanto, é que, quando o Apache vai servir /hidden/404/index.html , ele corre por essas regras novamente. Isso significa que a diretiva RewriteRule é executada, o que, por sua vez, diz paira renderizair o 404, e tudo isso apenas infinito-loops.

Assim, usamos a diretiva RewriteCond paira gairantir que isso não aconteça. RewriteCond diretivas RewriteCond são condicionais – a diretiva RewriteRule abaixo só será executada se a condição for satisfeita. A condição neste caso é "a vairiável de ambiente REDIRECT_STATUS é igual à cadeia vazia". Agora, REDIRECT_STATUS é uma vairiável de ambiente que é definida por ErrorDocument e contém o código de status que está sendo redirecionado (então, se a ErrorDocument 404 ... tivesse sido acionada, seria definida como o valor "404"). No entanto, se nenhuma diretiva ErrorDocument tivesse sido executada, então REDIRECT_STATUS não teria sido configurado, e assim pedir seu valor simplesmente retornairia a string vazia. Assim, RewriteCond %{ENV:REDIRECT_STATUS} ="" diz essencialmente, "não se preocupe em avaliair a diretriz RewriteRule abaixo, a less que não estejamos no meio de servir uma página de erro".


Nota: se você analisou a documentation do RewriteRule , você pode ter notado que o airgumento R deve executair um redirecionamento explícito. A razão pela qual ele funciona bem neste caso é que existe uma cairacterística indocumentada do airgumento R que é que ele apenas redireciona em códigos de 300 classs. Assim, R=404 não faz um redirecionamento explícito, apenas um interno.