Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

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)?

share|improve this question
add comment

2 Answers

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 word private, e.g.

grep private /etc/httpd/httpd.conf  # RedHat, CentOS
grep -r private /etc/apache2        # Debian, Ubuntu, etc.

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.

share|improve this answer
    
Thanks, I already did that, and the string "private" occurs only as part of a path name for ErrorLog, CustomLog, TypesConfig directives. If I remove the Order directive, by the way, the error changes from 403 to 404 for server/private/2201. Very strange. –  janeden Nov 21 '11 at 10:20
add comment
up vote 0 down vote accepted

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.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.