Bug 53929

Summary: RewriteRule of "^$" broke between 2.2.21 and 2.4.2
Product: Apache httpd-2 Reporter: Vic <victor.shih>
Component: mod_rewriteAssignee: Apache HTTPD Bugs Mailing List <bugs>
Status: RESOLVED FIXED    
Severity: normal CC: bcodding, contact, john, normadize, tm
Priority: P2 Keywords: FixedInTrunk
Version: 2.4.2   
Target Milestone: ---   
Hardware: All   
OS: All   
Attachments: proposed patch

Description Vic 2012-09-24 09:03:43 UTC
The following .htaccess configuration worked fine in 2.2.21:

  RewriteCond %{DOCUMENT_ROOT}/index-cached.html -f
  RewriteRule ^$ /index-cached.html [L]

  RewriteCond %{DOCUMENT_ROOT}/$1-cached.html -f
  RewriteRule ^([^/]+?)/$ /$1-cached.html [L]

  RewriteRule ^index\.php$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteRule . /index.php [L]

where browsing to "http://test.local" returns the contents of index-cached.html correctly.

However, in 2.4.2, processing falls through to index.php, even though the logs seem to indicate that the first condition was matched:

  [rid#13ad0b0/initial] [perdir C:/test/] strip per-dir prefix: C:/test/ ->
  [rid#13ad0b0/initial] [perdir C:/test/] applying pattern '^$' to uri ''
  [rid#13ad0b0/initial] [perdir C:/test/] RewriteCond: input='C:/test/index-cached.html' pattern='-f' => matched
  [rid#13ad0b0/initial] [perdir C:/test/] rewrite '' -> '/index-cached.html'
  [rid#13ad0b0/initial] [perdir C:/test/] trying to replace prefix C:/test/ with /
  [rid#13ad0b0/initial] [perdir C:/test/] internal redirect with /index-cached.html [INTERNAL REDIRECT]
  [rid#13b30c8/subreq] [perdir C:/test/] strip per-dir prefix: C:/test/index.php -> index.php
  [rid#13b30c8/subreq] [perdir C:/test/] applying pattern '^$' to uri 'index.php'
  [rid#13b30c8/subreq] [perdir C:/test/] strip per-dir prefix: C:/test/index.php -> index.php
  [rid#13b30c8/subreq] [perdir C:/test/] applying pattern '^([^/]+?)/$' to uri 'index.php'
  [rid#13b30c8/subreq] [perdir C:/test/] strip per-dir prefix: C:/test/index.php -> index.php
  [rid#13b30c8/subreq] [perdir C:/test/] applying pattern '^index\\.php$' to uri 'index.php'
  [rid#13b30c8/subreq] [perdir C:/test/] pass through C:/test/index.php

Notice that after the "initial" request finishes, a "subreq" is generated, whereas "initial/redir#1" was expected.

Both of my 2.2.21 and 2.4.2 environments have mod_dir enabled, which may or may not have bearing on this issue.

Note also that the second rule works in both versions; that is, browsing to "http://test.local/a/" correctly returns the contents of a-cached.html.
Comment 1 Joyce Babu 2013-07-30 16:29:08 UTC
I am also experiencing this issue. The issue is caused by the DirectoryIndex directive. mod_dir is not respecting the result of the rewrite execution. If DirectoryIndex is set to disabled, it starts working correctly. Similarly, using SetHandler also resolved the problem.

Unfortunately, since both the directives are inherited by files/sub directories, it is not a proper solution.

I was able to work around it by setting an environment variable using the mod_rewrite, and Disabling DirectoryIndex for those requests.

    RewriteEngine on 
    RewriteRule ^$ /test/home.php [NC,QSA,END,E=IS_DIR_INDEX:1] 

    <If "env('IS_DIR_INDEX') == 1"> 
    SetHandler default_handler 
    </If> 

There is a related issue which is present in 2.2 too. DirectoryIndex directive does not pass requests for directories to FallbackResource, if the index file is not found.
Comment 2 jkaluza 2013-09-12 12:48:30 UTC
Not so useful as I thought, but maybe it could help someone. Using git-bisect I've found out this is caused by following commit:

http://svn.apache.org/viewvc?view=revision&revision=233369
Comment 3 jkaluza 2013-09-13 05:45:47 UTC
Created attachment 30827 [details]
proposed patch

This patch fixes this issue for me without breaking ABI. Normally r->uri and r->filename ends with "/" in the case of directory request. If mod_rewrite rewrites URL later in hook_fixup, it changes r->filename. In this patch, I check if the r->filename still ends with "/" and if not, return DECLINED in mod_dir fixup hook.

I think there is still problem if you rewrite r->filename from directory to directory, but it should fix case when you rewrite from directory to file. I don't see immediate solution for directory to directory rewrite.
Comment 4 John Flatness 2013-12-02 17:48:13 UTC
The same issue seems to still be present as of 2.4.6.

I see the same behavior described here: for the "initial" request, my rule is applied as I expect, the substitution happens and there's an [INTERNAL REDIRECT] with my correct, desired URL. Then, the next log lines are all "subreq" and are operating on the DirectoryIndex file. Basically, DirectoryIndex seems to take precedence over RewriteRules.

These same rules work correctly in 2.2, and disabling DirectoryIndex allows the rewrite to take place as expected.

This also seems to be the same problem as described in Bug 53794. There is a different proposed patch there.
Comment 5 Mark Jenkins 2013-12-20 12:32:36 UTC
I have the same problem here. Any chance to see a fix soon? This bug has been around for more than a year now and it's pretty annoying.
Comment 6 Eric Covener 2014-01-13 01:54:18 UTC
Hi Jan, can you check out the approach these two commits before I propose them for backport?

http://svn.apache.org/r1557640
http://svn.apache.org/r1557641
Comment 7 John Flatness 2014-04-08 19:05:42 UTC
I see that there's a related commit(s) for this on the trunk.

Is there any chance of seeing this fixed in the 2.4 series?
Comment 8 Eric Covener 2014-04-08 19:09:06 UTC
(In reply to John Flatness from comment #7)
> I see that there's a related commit(s) for this on the trunk.
> 
> Is there any chance of seeing this fixed in the 2.4 series?

Can you test with the patches in the previous comment?(In reply to John Flatness from comment #7)
> I see that there's a related commit(s) for this on the trunk.
> 
> Is there any chance of seeing this fixed in the 2.4 series?

Can you try with 2.4.9? Supposd to be fixed there.
Comment 9 Eric Covener 2014-04-08 19:09:35 UTC
> Can you test with the patches in the previous comment?(In reply to John
> Flatness from comment #7)

ignore this part in last comment, forgot it was actually backported and available in 2.4.9.
Comment 10 John Flatness 2014-04-09 05:18:04 UTC
Aha, thanks for that update. 2.4.9 does appear to fix the problem I was having.

The behavior now seems to be consistent with 2.2, and a rewrite rule that conflicts with a DirectoryIndex gets applied.
Comment 11 Eric Covener 2014-04-09 05:56:17 UTC
Thanks for testing
Comment 12 Eric Covener 2014-04-20 18:14:05 UTC
*** Bug 56434 has been marked as a duplicate of this bug. ***