about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2009-09-09 10:02:49 -0700
committerEric Wong <normalperson@yhbt.net>2009-09-09 10:09:57 -0700
commit7eb0c4e29e567f02affc202b51eb277cbae43688 (patch)
tree59b2aa2efe2cc427cddc5638d1ccc152454419e8
parent72dfd64ed0ab31ced0f27e8a8a941c555221bb96 (diff)
downloadclogger-7eb0c4e29e567f02affc202b51eb277cbae43688.tar.gz
Since the wrapped Clogger object always responds to
close, we cannot blindly delegate the close method to
the body without ensuring it can be closed.  So ensure
that it can be closed before attempting to close it,
all return values and errors are trapped and returned.

Reported-by: IƱaki Baz Castillo
-rw-r--r--ext/clogger_ext/clogger.c4
-rw-r--r--lib/clogger/pure.rb2
-rw-r--r--test/test_clogger.rb20
3 files changed, 24 insertions, 2 deletions
diff --git a/ext/clogger_ext/clogger.c b/ext/clogger_ext/clogger.c
index 63322f9..7813c8c 100644
--- a/ext/clogger_ext/clogger.c
+++ b/ext/clogger_ext/clogger.c
@@ -656,7 +656,9 @@ static VALUE clogger_close(VALUE self)
 {
         struct clogger *c = clogger_get(self);
 
-        return rb_funcall(c->body, close_id, 0);
+        if (rb_respond_to(c->body, close_id))
+                return rb_funcall(c->body, close_id, 0);
+        return Qnil;
 }
 
 /* :nodoc: */
diff --git a/lib/clogger/pure.rb b/lib/clogger/pure.rb
index 2800802..da2c1de 100644
--- a/lib/clogger/pure.rb
+++ b/lib/clogger/pure.rb
@@ -47,7 +47,7 @@ class Clogger
   end
 
   def close
-    @body.close
+    @body.close if @body.respond_to?(:close)
   end
 
   def reentrant?
diff --git a/test/test_clogger.rb b/test/test_clogger.rb
index e65311f..23d6e58 100644
--- a/test/test_clogger.rb
+++ b/test/test_clogger.rb
@@ -469,4 +469,24 @@ class TestClogger < Test::Unit::TestCase
     assert_equal "<GET /hello?goodbye=true HTTP/1.0>", s
   end
 
+  def test_clogger_body_not_closeable
+    s = ''
+    app = lambda { |env| [302, [ %w(a) ], []] }
+    cl = Clogger.new(app, :logger => s)
+    status, headers, body = cl.call(@req)
+    assert_nil body.close
+  end
+
+  def test_clogger_body_close_return_value
+    s = ''
+    body = []
+    def body.close
+      :foo
+    end
+    app = lambda { |env| [302, [ %w(a) ], body ] }
+    cl = Clogger.new(app, :logger => s)
+    status, headers, body = cl.call(@req)
+    assert_equal :foo, body.close
+  end
+
 end