about summary refs log tree commit homepage
path: root/lib/unicorn/http_server.rb
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2015-06-09 20:17:18 +0000
committerEric Wong <e@80x24.org>2015-06-10 09:18:59 +0000
commit02a072734906ac4c1ea77990207b84895ab4a7cb (patch)
tree04abb7b53211c779637ab5a2f0e2930dbbd2ac6d /lib/unicorn/http_server.rb
parent40b9812029848933037466b2e7b19a47cfbd8363 (diff)
downloadunicorn-02a072734906ac4c1ea77990207b84895ab4a7cb.tar.gz
Middlewares such as Rack::Lock (used by Rails) break badly unless
the response body is closed on hijack, so we will close it to follow
the lead of other popular Rack servers.

While it's unclear if there's anybody using rack.hijack with unicorn,
we'll try to emulate the behavior of other servers as much as
possible.

ref: https://github.com/ngauthier/tubesock/issues/10
Diffstat (limited to 'lib/unicorn/http_server.rb')
-rw-r--r--lib/unicorn/http_server.rb20
1 files changed, 13 insertions, 7 deletions
diff --git a/lib/unicorn/http_server.rb b/lib/unicorn/http_server.rb
index 2657c29..9129ed8 100644
--- a/lib/unicorn/http_server.rb
+++ b/lib/unicorn/http_server.rb
@@ -559,16 +559,22 @@ class Unicorn::HttpServer
   # in 3 easy steps: read request, call app, write app response
   def process_client(client)
     status, headers, body = @app.call(env = @request.read(client))
-    return if @request.hijacked?
 
-    if 100 == status.to_i
-      e100_response_write(client, env)
-      status, headers, body = @app.call(env)
+    begin
       return if @request.hijacked?
+
+      if 100 == status.to_i
+        e100_response_write(client, env)
+        status, headers, body = @app.call(env)
+        return if @request.hijacked?
+      end
+      @request.headers? or headers = nil
+      http_response_write(client, status, headers, body,
+                          @request.response_start_sent)
+    ensure
+      body.respond_to?(:close) and body.close
     end
-    @request.headers? or headers = nil
-    http_response_write(client, status, headers, body,
-                        @request.response_start_sent)
+
     unless client.closed? # rack.hijack may've close this for us
       client.shutdown # in case of fork() in Rack app
       client.close # flush and uncork socket immediately, no keepalive