about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2011-01-21 08:53:55 +0000
committerEric Wong <normalperson@yhbt.net>2011-01-21 08:57:01 +0000
commitd3a182dd0238c964ff5191642d53fce3d2e64be9 (patch)
tree7849641fd6ecdf22f15a82ee1c7653214999ea44
parent0abc76611fe3438dd5b152257f9ba9028c536ed3 (diff)
This optimization is used by Rainbows! to pass IO objects
to the response body.
-rw-r--r--ext/clogger_ext/clogger.c19
-rw-r--r--lib/clogger/pure.rb4
-rw-r--r--test/test_clogger_to_path.rb3
3 files changed, 25 insertions, 1 deletions
diff --git a/ext/clogger_ext/clogger.c b/ext/clogger_ext/clogger.c
index 253339f..94301fc 100644
--- a/ext/clogger_ext/clogger.c
+++ b/ext/clogger_ext/clogger.c
@@ -908,6 +908,24 @@ static VALUE to_path(VALUE self)
         return path;
 }
 
+/*
+ * call-seq:
+ *   clogger.to_io
+ *
+ * used to proxy +:to_io+ method calls to the wrapped response body.
+ */
+static VALUE to_io(VALUE self)
+{
+        struct clogger *c = clogger_get(self);
+        struct stat sb;
+        VALUE io = rb_convert_type(c->body, T_FILE, "IO", "to_io");
+
+        if (fstat(my_fileno(io), &sb) == 0)
+                c->body_bytes_sent = sb.st_size;
+
+        return io;
+}
+
 void Init_clogger_ext(void)
 {
         VALUE tmp;
@@ -938,6 +956,7 @@ void Init_clogger_ext(void)
         rb_define_method(cClogger, "wrap_body?", clogger_wrap_body, 0);
         rb_define_method(cClogger, "reentrant?", clogger_reentrant, 0);
         rb_define_method(cClogger, "to_path", to_path, 0);
+        rb_define_method(cClogger, "to_io", to_io, 0);
         rb_define_method(cClogger, "respond_to?", respond_to, 1);
         CONST_GLOBAL_STR(REMOTE_ADDR);
         CONST_GLOBAL_STR(HTTP_X_FORWARDED_FOR);
diff --git a/lib/clogger/pure.rb b/lib/clogger/pure.rb
index 6613686..3f54819 100644
--- a/lib/clogger/pure.rb
+++ b/lib/clogger/pure.rb
@@ -89,6 +89,10 @@ class Clogger
     rv
   end
 
+  def to_io
+    @body.to_io
+  end
+
 private
 
   def byte_xs(s)
diff --git a/test/test_clogger_to_path.rb b/test/test_clogger_to_path.rb
index 00767dc..4cc9027 100644
--- a/test/test_clogger_to_path.rb
+++ b/test/test_clogger_to_path.rb
@@ -120,7 +120,8 @@ class TestCloggerToPath < Test::Unit::TestCase
     assert_instance_of(Clogger, body)
     check_body(body)
 
-    body.to_path
+    assert_equal tmp.path, body.to_path
+    assert_nothing_raised { body.to_io }
     assert_kind_of IO, tmp.instance_variable_get(:@to_io_called)
     assert logger.string.empty?
     assert ! tmp.closed?