4

I'm running a standard installation of Apache 2.4.6 (Amazon) with PHP 5.4.21 using the following configuration for my virtual host:

DirectoryIndex index.php
# ...
FallbackResource /index.php

My index.php is the epitome of simple:

<?php echo "Hello world";

Accessing http://<server-name>/ mysteriously shows the full page only after five seconds! Any other page has the expected response time (which is fast).

Those five seconds, as I came to find out, are related to the default waiting time of the Keep-Alive feature; in this case, the last few bytes of the chunked response are not sent until Apache severs the connection after that waiting time. Btw, that also completely ruins any gains that a persistent connection would otherwise give you.

Is this a known bug of Apache or am I missing something extremely obvious here?

Jack
  • 636
  • 4
  • 15

1 Answers1

7

2017/04/18: This has been fixed in Apache 2.4.25: https://bz.apache.org/bugzilla/show_bug.cgi?id=58292

The explanation from the bug summary:

If FallBackResource is executed on a subrequest, the server never sends an last-chunk causing the appearance of a hang in some clients.

This happens because the EOS bucket is stripped by the subrequest filter, which is not removed properly if multiple subrequest filters end up in one list

This behaviour is only apparent when compression is applied, because that relies on knowing when the stream ends; and the 5s is the default socket timeout that's used.

Old answer

From this bug report I realised that this problem could be related to the DirectoryIndex directive.

The standard Apache installation comes with the following section in the configuration:

<IfModule dir_module>
DirectoryIndex index.html
</IfModule>

Any directives following this statement, such as the one in your virtual host, will not overwrite this setting; rather, it gets added to a stack of pages that will be attempted when the index is requested. This behaviour can be confirmed when you perform strace httpd -X and check the stat() calls right after the request has been read, e.g.:

stat("/path/to/vhost/index.html", 0x7fff9dc41b90) = -1 ENOENT
stat("/path/to/vhost/index.php", {st_mode=S_IFREG|0664, st_size=130, ...}) = 0

Although I can't tell exactly why, any previous DirectoryIndex directive must be cleared before specifying DirectoryIndex index.php, i.e. index.php MUST be the first page that's attempted to handle the request.

This can be done using the following configuration:

DirectoryIndex disabled
DirectoryIndex index.php
Jack
  • 636
  • 4
  • 15
  • Please see https://serverfault.com/a/569617/208335 for a better explanation of the cause. – AnrDaemon Dec 31 '21 at 04:56
  • Yeah, this is also explained in the bug report that I added to my answer here ... I was just too lazy to update the rest of my answer I guess :) – Jack Jan 04 '22 at 05:26