From b583fe84c3e2174f143d2412b0b93eeb18e5aeb8 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Fri, 26 Oct 2012 09:24:46 +0000 Subject: add Kcar::Parser#body_bytes_left= setter method This allows us to properly get body_eof? to return true in Kcar::Response for unchunked responses. --- ext/kcar/kcar.rl | 19 +++++++++++++++++++ lib/kcar/response.rb | 1 + test/test_response.rb | 5 +++++ 3 files changed, 25 insertions(+) diff --git a/ext/kcar/kcar.rl b/ext/kcar/kcar.rl index e424331..e812279 100644 --- a/ext/kcar/kcar.rl +++ b/ext/kcar/kcar.rl @@ -493,6 +493,24 @@ static VALUE body_bytes_left(VALUE self) return Qnil; } +/** + * call-seq: + * parser.body_bytes_left = Integer + * + * Sets the number of bytes left to download for HTTP responses + * with "Content-Length". This raises RuntimeError for chunked + * responses. + */ +static VALUE body_bytes_left_set(VALUE self, VALUE bytes) +{ + struct http_parser *hp = data_get(self); + + if (HP_FL_TEST(hp, CHUNKED)) + rb_raise(rb_eRuntimeError, "body_bytes_left= is not for chunked bodies"); + hp->len.content = NUM2OFFT(bytes); + return bytes; +} + /** * Document-method: chunked * call-seq: @@ -667,6 +685,7 @@ void Init_kcar_ext(void) rb_define_method(cParser, "trailers", headers, 2); rb_define_method(cParser, "filter_body", filter_body, 2); rb_define_method(cParser, "body_bytes_left", body_bytes_left, 0); + rb_define_method(cParser, "body_bytes_left=", body_bytes_left_set, 1); rb_define_method(cParser, "body_eof?", body_eof, 0); rb_define_method(cParser, "keepalive?", keepalive, 0); rb_define_method(cParser, "chunked?", chunked, 0); diff --git a/lib/kcar/response.rb b/lib/kcar/response.rb index f34971d..2ba19f2 100644 --- a/lib/kcar/response.rb +++ b/lib/kcar/response.rb @@ -147,6 +147,7 @@ class Kcar::Response dst.respond_to?(:clear) ? dst.clear : @buf = "" end end + @parser.body_bytes_left = 0 end def each_unchunk diff --git a/test/test_response.rb b/test/test_response.rb index 3feb5e9..3c611d2 100644 --- a/test/test_response.rb +++ b/test/test_response.rb @@ -28,6 +28,7 @@ class TestSession < Test::Unit::TestCase assert_nothing_raised { body.each { |chunk| tmp << chunk.dup } } assert_equal [], tmp assert @response.parser.keepalive? + assert @response.parser.body_eof? body.close status, headers, body = @response.rack @@ -135,6 +136,8 @@ class TestSession < Test::Unit::TestCase tmp = [] assert body.parser.keepalive? assert_nothing_raised { body.each { |chunk| tmp << chunk.dup } } + assert body.parser.body_eof? + assert body.parser.keepalive? assert_equal [ "HI" ], tmp _, status = Process.waitpid2(pid) assert status.success? @@ -171,6 +174,8 @@ class TestSession < Test::Unit::TestCase tmp = [] assert body.parser.keepalive? assert_nothing_raised { body.each { |chunk| tmp << chunk.dup } } + assert body.parser.keepalive? + assert body.parser.body_eof? assert_equal [ "abcde" ], tmp _, status = Process.waitpid2(pid) assert status.success? -- cgit v1.2.3-24-ge0c7