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.0
It 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