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.

I've set up my virtual host on Apache 2.4.7 with a very basic configuration:

<VirtualHost *:80>
  ServerName foo.example.com
  DocumentRoot /var/www/html

  DirectoryIndex index.php
  FallbackResource /index.php
</VirtualHost>

Underneath the document root I have the following structure:

/index.php
/help/readme.txt

I get the following results when I make requests:

/bla     -> 200 OK
/help/   -> 404 Not Found
/help/a  -> 200 OK

It seems that the existence of the /help/ directory is causing Apache to return 404 because there's no index.php in there, but I expect all requests to invoke /index.php and thus yield a 200 OK response.

I don't remember this being a problem when using mod_rewrite, but I prefer using FallbackResource if possible. Is there a way to fix this?

Update

It works if I remove the DirectoryIndex directive, but that suffers from five second delay issues.

Update 3

I'm running the following test environment; the directory structure is as follows:

./htdocs
   index.html
   test/
      bla.txt
./conf
   httpd.conf
./logs

The contents of httpd.conf is:

ServerName apache-bug.local
Listen 8085

DirectoryIndex disabled
DirectorySlash Off

<VirtualHost *:8085>
DocumentRoot /home/user/apache-bug/htdocs

FallbackResource /index.html
</VirtualHost>

My config.nice contains:

"./configure" \
"--enable-debugger-mode" \
"--with-apr=/usr/local/apr/bin/apr-1-config" \
"--enable-dir=static" \
"--with-mpm=prefork" \
"--enable-unixd=static" \
"--enable-authn-core=static" \
"--enable-authz-core=static" \
"$@"

To run the server:

httpd -X -d /home/user/work/apache-bug/
share|improve this question
    
And what is in the response body for /bla? –  zerkms Jan 22 at 2:45
    
I'm not sure I'm understanding the problem then :-S –  zerkms Jan 22 at 3:49
    
Just to make sure - which version of Apache are you on? –  Jenny D Jan 24 at 10:50
    
@JennyD I'm running on 2.4.7. –  Jack Jan 24 at 10:51

2 Answers 2

Your configuration should be correct.

The problem, strangely enough, seems to be mod_deflate.

After having reproduced your configuration successfully here (not getting a 404), I also got the 5 second delay. However, I noticed that when the UA omits gzip from its Accept-Headers, the page is displayed/received instantaneously. You can test this for yourself with wget.

Interestingly, further debugging with strace shows that apache sends the contents of your FallbackResource to the socket of your client without noticeable difference in delay for both cases. This is also evident on the wire, where a reply paket is sent from the server to the client after the HTTP Request without any notable delay1.

It seems that when using mod_deflate in this case however, the UA doesn't know when the data sent by the server ends, and thus does not render anything before the TCP connection times out2 and is forcibly closed by the server. This is compliant to HTTP/1.0, where a closed connection signifies end-of-content.

For HTTP/1.1, the server has other means available to signal the end-of-contentbut none of which seem to happen here.

Wether the bug lurks in mod_dir or mod_deflate however, is beyond my available time right now. I got it to work flawlessy by disabling gzip compression; as a workaround until the issue is fixed for good, you can selectively disable gzip.

1) This tells us that the problem does not stem from unflushed buffers on the server.
2) By default, the timeout is 5 seconds with apache - that's where your 5 seconds are from.

share|improve this answer
    
Thanks. The 5s delay issue is secondary to my main problem, I've updated my question with how to reproduce the issue locally. –  Jack Jan 27 at 6:11
up vote 3 down vote accepted

I'm answering this myself as well, because I'm pretty sure that the issue is related to how mod_dir.c works internally and I think it's a bug.

If a resource can't be mapped to the local file system, the function fixup_dflt() will run, using the FallbackResource to determine which document should be loaded instead.

However, when a resource can be mapped to the local file system and it's a directory, it will attempt to resolve the document by running fixup_dir(); this function iterates over the list of DirectoryIndex values until it finds the first suitable document.

In my case, the configuration has an empty list of DirectoryIndex values, so fixup_dir() will fail and a 404 is returned.

The following patch works for me (PR):

static int dir_fixups(request_rec *r)
{
    if (r->finfo.filetype == APR_DIR) {
-        return fixup_dir(r);
+        if (fixup_dir(r) != OK) {
+           /* use fallback */
+           return fixup_dflt(r);
+        }
+
+        return OK;
    }
    else if ((r->finfo.filetype == APR_NOFILE) && (r->handler == NULL)) {
        /* No handler and nothing in the filesystem - use fallback */
        return fixup_dflt(r);
    }
    return DECLINED;
}

It basically tries fixup_dflt() after fixup_dir() failed.

share|improve this answer
    
I would say the error is in fixup_dir() ignoring the FallbackResource. –  Ricky Beam Jan 27 at 7:18
    
@RickyBeam Yes, but technically fixup_dir() shouldn't know about fixup_dflt(), so imho it's better to fix it "higher up" :) –  Jack Jan 27 at 7:51

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.