unicorn Ruby/Rack server user+dev discussion/patches/pulls/bugs/help
 help / color / mirror / code / Atom feed
Search results ordered by [date|relevance]  view[summary|nested|Atom feed]
thread overview below | download mbox.gz: |
* [PATCH] close client socket after closing response body
@ 2011-01-06  7:20 14% Eric Wong
  0 siblings, 0 replies; 1+ results
From: Eric Wong @ 2011-01-06  7:20 UTC (permalink / raw)
  To: mongrel-unicorn

I am wondering if there are any apps affected by this bug (and
perhaps keeping people from switching Unicorn).

It's a fairly esoteric case, so I probably won't make another release
until tomorrow (sleepy now, will probably screw something else up
or realize something else is broken :)

Anyways it's pushed out to master and 1.1.x-stable in case people
want^Wneed it *right* *now*:

>From b72a86f66c722d56a6d77ed1d2779ace6ad103ed Mon Sep 17 00:00:00 2001
From: Eric Wong <normalperson@yhbt.net>
Date: Wed, 5 Jan 2011 22:39:03 -0800
Subject: [PATCH] close client socket after closing response body

Response bodies may capture the block passed to each
and save it for body.close, so don't close the socket
before we have a chance to call body.close
---
 lib/unicorn/http_response.rb |    1 -
 lib/unicorn/http_server.rb   |    1 +
 t/t0018-write-on-close.sh    |   23 +++++++++++++++++++++++
 t/write-on-close.ru          |   11 +++++++++++

 (Unnecessary unit test case omitted for email)
 test/unit/test_response.rb   |   18 +++++++++---------

 5 files changed, 44 insertions(+), 10 deletions(-)
 create mode 100755 t/t0018-write-on-close.sh
 create mode 100644 t/write-on-close.ru

diff --git a/lib/unicorn/http_response.rb b/lib/unicorn/http_response.rb
index 3a03cd6..62b3ee9 100644
--- a/lib/unicorn/http_response.rb
+++ b/lib/unicorn/http_response.rb
@@ -38,7 +38,6 @@ module Unicorn::HttpResponse
     end
 
     body.each { |chunk| socket.write(chunk) }
-    socket.close # flushes and uncorks the socket immediately
     ensure
       body.respond_to?(:close) and body.close
   end
diff --git a/lib/unicorn/http_server.rb b/lib/unicorn/http_server.rb
index e2a4db7..3a6e51e 100644
--- a/lib/unicorn/http_server.rb
+++ b/lib/unicorn/http_server.rb
@@ -538,6 +538,7 @@ class Unicorn::HttpServer
     end
     @request.headers? or headers = nil
     http_response_write(client, status, headers, body)
+    client.close # flush and uncork socket immediately, no keepalive
   rescue => e
     handle_error(client, e)
   end
diff --git a/t/t0018-write-on-close.sh b/t/t0018-write-on-close.sh
new file mode 100755
index 0000000..3afefea
--- /dev/null
+++ b/t/t0018-write-on-close.sh
@@ -0,0 +1,23 @@
+#!/bin/sh
+. ./test-lib.sh
+t_plan 4 "write-on-close tests for funky response-bodies"
+
+t_begin "setup and start" && {
+	unicorn_setup
+	unicorn -D -c $unicorn_config write-on-close.ru
+	unicorn_wait_start
+}
+
+t_begin "write-on-close response body succeeds" && {
+	test xGoodbye = x"$(curl -sSf http://$listen/)"
+}
+
+t_begin "killing succeeds" && {
+	kill $unicorn_pid
+}
+
+t_begin "check stderr" && {
+	check_stderr
+}
+
+t_done
diff --git a/t/write-on-close.ru b/t/write-on-close.ru
new file mode 100644
index 0000000..54a2f2e
--- /dev/null
+++ b/t/write-on-close.ru
@@ -0,0 +1,11 @@
+class WriteOnClose
+  def each(&block)
+    @callback = block
+  end
+
+  def close
+    @callback.call "7\r\nGoodbye\r\n0\r\n\r\n"
+  end
+end
+use Rack::ContentType, "text/plain"
+run(lambda { |_| [ 200, [%w(Transfer-Encoding chunked)], WriteOnClose.new ] })
-- 
Eric Wong
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying


^ permalink raw reply related	[relevance 14%]

Results 1-1 of 1 | reverse | options above
-- pct% links below jump to the message on this page, permalinks otherwise --
2011-01-06  7:20 14% [PATCH] close client socket after closing response body Eric Wong

Code repositories for project(s) associated with this public inbox

	https://yhbt.net/unicorn.git/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).