In the end I traced the problem to when we enabled SSL in our Apache 2.0 installation. As it turns out, we fell victim to multiple bone-headed behaviors. The first is that Microsoft Internet Explorer has problems with SSL. The second is an attempt by the Apache team to save users from this problem. In /etc/apache2/mods-available/ssl.conf, this code lurks:
SetEnvIf User-Agent ".*MSIE.*" \ nokeepalive ssl-unclean-shutdown \ downgrade-1.0 force-response-1.0It basically says, for any MSIE, including MSIE 7.0, drop back to old HTTP 1.0 behavior with no keepalive. And, violate the SSL protocol so that IE doesn't have a fit. No problem, right?
There's something terribly wrong here. The snippet above is in a global context. It disables keep-alive for any MSIE, doing HTTP or HTTPS. This is an efficiency killer.
The fix turns out to be straightforward and I wish the Apache team would have found a way to do it out of the box. What I did was just to move the snippet to my port 443 virtual host:
Update 1/8/2013: I split out the conditions for versions before and after MSIE 7. This is based on the latest configuration from Apache.
NameVirtualHost *:443 <VirtualHost *:443> ... SSLEngine on SSLCertificateFile /etc/apache2/ssl/foo.com-cert.pem SSLCertificateKeyFile /etc/apache2/ssl/foo.com-key.pem SSLCACertificateFile /etc/apache2/ssl/cacert.pem SetEnvIf User-Agent ".*MSIE [2-6].*" \ nokeepalive ssl-unclean-shutdown \ downgrade-1.0 force-response-1.0 SetEnvIf User-Agent ".*MSIE [17-9].*" \ ssl-unclean-shutdown </VirtualHost>Dan Pritts at University of Michigan points out that newer versions of MSIE aren't broken and aren't common. He suggests just removing the original problem code. Personally, I feel safer with it, in the proper place.
ServerTokens Prod Timeout 30 KeepAliveTimeout 1