IE は KeepAlive をうまく処理できない?

http://otaba.jp/page.php?p=fh_diary&target_c_member_id=1&target_c_diary_id=19563

本件について調査しましたところ、その原因の一つは、IE系ブラウザに、KeepAlive(*1)を正しく処理できないという不具合があり、サーバー/ネットワークの負荷をさせるために行ったバージョンアップと設定変更によって、この問題が発生するようになってしまったのではないかと考えています。

この問題に対応するための対策としまして、IE系のブラウザからのアクセスであると判明した場合はKeepAliveを無効にするという処置を行うように致しました。
具体的には、ブラウザがUser-Agent(*2)に"MSIE"という文字を含めてきた場合は強制的にKeep-Aliveを無効にするようにしました。
しかしながら、IE系ブラウザの一種であるSleipnirは、"Sleipnir"のみで"MSIE"という文字を送らないバージョンが存在するようですのでそれにも後から対応させてあります。

ただしプロクシをご利用の方は、一部のプロクシがUser-Agentを勝手に書き換えてしまうものがありますので、IE系ブラウザをプロクシを介してご利用の方はご注意ください。

しかしながらIE系ブラウザはまれに、2つ目以降のファイルを転送するタイミングを見逃してしまい、サーバーが接続を強制的に切断するまで黙り込んでしまう不具合があるようです。

ふーん。いまだにそういう問題があるってホントかしらん。
デフォでも除外設定があるんだねぇ。でも4だけ?

BrowserMatch "MSIE 4?.0b2;" nokeepalive downgrade-1.0 force-response-1.0

http://pcweb.mycom.co.jp/column/winxp/098/
デフォルトが2分なのね。長すぎて鯖側の負荷がしんどいってこともあるのかな。
http://mm.apache.jp/pipermail/apache-users/2002-October/001998.html
最初は動いているけど、突然動かなくなって、再起動するまで改善しないのか。
なんでだろうね。
ちょっと日本語でぐぐったくらいでは、出てこないな。
 
元ネタのコメントにURLが埋まっていた。
http://support.microsoft.com/default.aspx?scid=kb;ja;831167
http://ns1.php.gr.jp/pipermail/php-users/2004-April/021749.html

Apache などのデフォルトでは Keep Alive の時間が 15秒に設定されています。
ところが wininet では独自に TCPセッションを持続する仕組みが在り、これのタイムアウト値が 60秒に設定されています。
また、wininet はサーバーよりの Keep Alive が解除されたと言う FIN シグナルを無視してしまいます。
ここで、クライアントは繋がっているはず、サーバーは切断されたはずとTCPセッションの矛盾が発生してしまいます。
この状況はサーバーが Keep Alive を解除して FIN を投げた時から発生致します。
netstat で状態を見ると、クライアント側では CLOSE_WAIT、サーバー側ではFIN_WAIT2(かな?)になっていると思います。

この状況下で、クライアント側(IE)からリクエストを行うと、wininet は先ほどまで使用していた TCPセッションが生きていると思っていますから、その TCPセッションに対してリクエストのデータをセットして、サーバーにデータを送出します。
ですがサーバー側では、その TCPセッションは既に無効になっていますので、そのリクエストは受け付けられません。(当然サーバーのログにも残りません)
この時、wininet はどうするかと言うと、送出に失敗した TCPセッションは消去して、新規に TCPセッションを再作成してしまい、そのまま処理を継続しようとします。
しかも先ほど消去された TCPセッションにセットしたデータは引き継がれず、結果として Content-Length : 0 のリクエストが再送される形になります。サーバーのログにはこちらが残ります。

なるほどね。問題が違うレイヤーで重なっているのね。「SSL 3.0 の実装が不完全」ってのもやだな。
Apache側のKeepAliveを65くらいにしておけば、とりあえず問題ないのかな。
こんなのは、鯖屋の常識なんでしょうか。