Keep-Alive の実装が適当すぎるせいか、ソケットを再利用したときにサーバー側から切断されていてもそれを検出できない。
GET なら再接続して送り直せばいい。しかし POST でメッセージボディが大きすぎるとき、メモリ使いすぎて困る。
なのでクライアントからボディを受信してはオリジンサーバーへ送信って事を繰り返しているんだけど、既にサーバー側から切断されていることがある。しかも切断されているのに Socket.Send() はできちゃうのでリクエストボディ送り終えて、さぁレスポンスくれってときに切断されてて、送ったデータが無駄になってしまう。
んでなんとかならんもんかねっておもってたら Expect: 100-continue ってのがあるじゃないかと。
ソケットを再利用する場合は、
- 前のレスポンスが HTTP/1.1 であった事を確認 (HTTP/1.0 ならそもそも再利用してない)
- リクエストヘッダに Expect: 100-continue を付加して、オリジンサーバーに送る。
- オリジンサーバーから HTTP/1.1 100 continue をうけとる。-> ボディを送る
- 対応してなかったら HTTP/1.1 417 Expectation Failed が返ってくるとおもう。-> 返ってきたということは接続中 -> もっかい送り直す?
- 切断されてたら受信できないけど Socket.Receive() == 0 が返ってくるはず。-> つなぎ直す
ということでメッセージボディを送る前に何とかなりそうではあるかな。まだ定かじゃないけど。