properly half-close both sides of the HTTP connection
authorLunar <lunar@anargeek.net>
Wed, 29 Feb 2012 21:19:03 +0000 (22:19 +0100)
committerLunar <lunar@anargeek.net>
Thu, 14 Mar 2013 09:12:08 +0000 (10:12 +0100)
Half-closing the write part first and draining our input makes sure the client
will properly receive an error message instead of TCP RST (a.k.a. "Connection
reset by peer") when we interrupt it in the middle of a POST request.

config.ru

index 760cdf0..dc962cb 100644 (file)
--- a/config.ru
+++ b/config.ru
@@ -23,4 +23,30 @@ Bundler.require
 $:.unshift File.join(File.dirname(__FILE__), 'lib')
 require 'coquelicot'
 
 $:.unshift File.join(File.dirname(__FILE__), 'lib')
 require 'coquelicot'
 
+if defined? Rainbows::Client
+  # This implements the behaviour outlined in Section 8 of
+  # <http://ftp.ics.uci.edu/pub/ietf/http/draft-ietf-http-connection-00.txt>.
+  #
+  # Half-closing the write part first and draining our input makes sure the
+  # client will properly receive an error message instead of TCP RST (a.k.a.
+  # "Connection reset by peer") when we interrupt it in the middle of a POST
+  # request.
+  #
+  # Thanks Eric Wong for these few lines. See
+  # <http://rubyforge.org/pipermail/rainbows-talk/2012-February/000328.html> for
+  # the discussion that lead him to propose what follows.
+  class Rainbows::Client
+    def close
+      close_write
+      buf = ""
+      loop do
+        kgio_wait_readable(2)
+        break unless kgio_tryread(512, buf)
+      end
+    ensure
+      super
+    end
+  end
+end
+
 run Coquelicot::Application
 run Coquelicot::Application