Bug 57298

Summary: RewriteBase inside FilesMatch behaves oddly
Product: Apache httpd-2 Reporter: Jan Wolter <jan>
Component: mod_rewriteAssignee: Apache HTTPD Bugs Mailing List <bugs>
Status: NEW ---    
Severity: minor    
Priority: P2    
Version: 2.4.10   
Target Milestone: ---   
Hardware: PC   
OS: Linux   

Description Jan Wolter 2014-12-02 21:46:58 UTC
I have the following somewhat redundant .htaccess file in the directory /home/jan/public_html/rewrite_test

<FilesMatch "a\.html">
RewriteEngine On
RewriteBase /~jan/rewrite_test/
RewriteRule (.*)a\.html $1.html

Without the <FilesMatch> directive, this works perfectly. If we access http://localhost/~jan/rewrite_test/1a.html, it serves up the 1.html file instead.

With the <FilesMatch> directive, it fails. In the log file we see all going well until this happens:

[Tue Dec 02 15:55:21.365666 2014] [rewrite:trace2] [pid 2020] mod_rewrite.c(475): [client ::1:58291] ::1 - - [localhost/sid#7f14dc162448][rid#7f14dbfbf0a0/initial] [perdir a\\.html/] trying to replace prefix a\\.html/ with /~jan/rewrite_test/

Without the <FilesMatch> it tries to replace the prefix "/home/jan/public_html/rewrite_test/", and that works fine. But the <FilesMatch> directive has confused it to the extent that it no longer seems to remember the directory prefix it is supposed to be replacing, and is using the argument from <FilesMatch>, "a\\.html\" instead. (Possibly it is mistaking the <FilesMatch> block for a <Directory> block.)

I'm not completely convinced it ever really makes a lot of sense to put Rewrite Rules inside a <FilesMatch> block, but it seems like it ought to work, and mostly it does except that RewriteBase breaks.
Comment 1 Eric Covener 2014-12-03 00:05:13 UTC
I had just looked at a related issue/limitation on trunk which as a result now requires RewriteBase to be explicitly specified less often, and as a bonus seems to fix this case even w/ a RewriteBase.

Can you try a patch against 2.4.x?  http://svn.apache.org/r1642484

In various places, mod_rewrite strips/readds/re-strips the current perdir prefix.  In this case, even the original comparison in the rewriterule is wrong -- it's operating on the entire filename on-disk rather than whats normally just the "remainder".