The directory private
lives under my DocumentRoot, and despite its name, it should be accessible just like any other dir. But if I add the following RewriteRule
to httpd.conf:
RewriteRule ^/([^\.]+)$ /$1.html [L]
Apache returns 403 for http://server/private/2201. The error log states
client denied by server configuration: /private/2201.html
If I then rename private
to foo
, or if I request 2201.html directly, the file is served:
127.0.0.1 - - [21/Nov/2011:10:24:45 +0100] "GET /private/2201 HTTP/1.1" 403 214
127.0.0.1 - - [21/Nov/2011:10:24:58 +0100] "GET /foo/2201 HTTP/1.1" 200 3068
127.0.0.1 - - [21/Nov/2011:10:27:39 +0100] "GET /private/2201.html HTTP/1.1" 200 3068
This is confusing. Is there any special rule for directories named private
? If so – why does the direct request for 2201.html work (although the denied request seems to handle the same resource, at least according to the error log entry)?
There's nothing built into Apache or mod_rewrite that makes the name
private
special, AFAIK. But, your configuration might have come with a default rule that treats that name differently. Try grepping your configuration for the wordprivate
, e.g.If you find a RewriteRule that matches, that's your culprit.
Your log entries make clear that it's the name
private
in particular that's causing the problem, and that it must be a RewriteRule that's causing the request to be denied.This is an embarrassing case of RTM. Apache's documentation regarding RewriteRule explicitly states that substitution strings "will be treated as a URL-path unless a directory named www exists at the root or your file-system, in which case it will be treated as a file-system path", at least when defining a RewriteRule outside a directory context.
Since my filesystem contains
/private
, but not/foo
, and the URL/private/2212.html
is not affected by the RewriteRule, the pattern above should be expected.The solution was to add the flag [PT] (passthrough) to my RewriteRule.