From d3a182dd0238c964ff5191642d53fce3d2e64be9 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Fri, 21 Jan 2011 08:53:55 +0000 Subject: pass along "to_io" calls to the body This optimization is used by Rainbows! to pass IO objects to the response body. --- ext/clogger_ext/clogger.c | 19 +++++++++++++++++++ lib/clogger/pure.rb | 4 ++++ test/test_clogger_to_path.rb | 3 ++- 3 files changed, 25 insertions(+), 1 deletion(-) 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? -- cgit v1.2.3-24-ge0c7