diff options
-rw-r--r-- | lib/plum/client/response.rb | 36 | ||||
-rw-r--r-- | test/plum/client/test_client.rb | 17 | ||||
-rw-r--r-- | test/plum/client/test_response.rb | 16 |
3 files changed, 21 insertions, 48 deletions
diff --git a/lib/plum/client/response.rb b/lib/plum/client/response.rb index ee23971..8270e95 100644 --- a/lib/plum/client/response.rb +++ b/lib/plum/client/response.rb @@ -10,7 +10,7 @@ module Plum @body = Queue.new @finished = false @failed = false - @body_read = false + @body = [] end # Return the HTTP status code. @@ -38,26 +38,26 @@ module Plum @failed end - # Yields a chunk of the response body until EOF. + # Set callback tha called when received a chunk of response body. # @yield [chunk] A chunk of the response body. - def each_chunk(&block) - raise "Body already read" if @body_read - @body_read = true - while !(finished? && @body.empty?) && chunk = @body.pop - if Exception === chunk - raise chunk - else - yield chunk - end + def on_chunk(&block) + raise "Body already read" if @on_chunk + @on_chunk = block + unless @body.empty? + @body.each(&block) + @body.clear end end # Returns the complete response body. Use #each_body instead if the body can be very large. # @return [String] the whole response body def body - body = String.new - each_chunk { |chunk| body << chunk } - body + raise "Body already read" if @on_chunk + if finished? + @body.join + else + raise "Response body is not complete" + end end # @api private @@ -68,19 +68,21 @@ module Plum # @api private def _chunk(chunk) - @body << chunk + if @on_chunk + @on_chunk.call(chunk) + else + @body << chunk + end end # @api private def _finish @finished = true - @body << nil # @body.close is not implemented in Ruby 2.2 end # @api private def _fail(ex) @failed = true - @body << ex end end end diff --git a/test/plum/client/test_client.rb b/test/plum/client/test_client.rb index 66479a1..f8b64b0 100644 --- a/test/plum/client/test_client.rb +++ b/test/plum/client/test_client.rb @@ -68,23 +68,6 @@ class ClientTest < Minitest::Test server_thread.join end - def test_raise_error_async_seq_wait_headers - server_thread = start_tls_server - client = Client.start("127.0.0.1", LISTEN_PORT, https: true, verify_mode: OpenSSL::SSL::VERIFY_NONE) - res = client.get_async("/error_in_data") - client.wait_headers(res) - data = String.new - tt = Thread.new { client.wait } - assert_raises(LocalConnectionError) { - res.each_chunk { |c| data << c } - } - tt.join - client.close - assert_equal("a", data) - ensure - server_thread.join - end - def test_raise_error_async_block client = nil server_thread = start_tls_server diff --git a/test/plum/client/test_response.rb b/test/plum/client/test_response.rb index dbb6ba2..eb98e3d 100644 --- a/test/plum/client/test_response.rb +++ b/test/plum/client/test_response.rb @@ -11,21 +11,9 @@ class ResponseTest < Minitest::Test def test_fail resp = Response.new - ret = "" - run = false - t = Thread.new { - assert_raises { - run = true - resp.each_chunk { |chunk| ret << chunk } } } resp._chunk("a") resp._fail(RuntimeError.new) - timeout(3) { - t.join } - assert(run) assert(true, resp.failed?) - rescue Timeout::Error - t.kill - flunk "timeout" end def test_status @@ -53,13 +41,13 @@ class ResponseTest < Minitest::Test assert_equal("ab", resp.body) end - def test_each_chunk + def test_on_chunk resp = Response.new res = [] resp._chunk("a") resp._chunk("b") resp._finish - resp.each_chunk { |chunk| res << chunk } + resp.on_chunk { |chunk| res << chunk } assert_equal(["a", "b"], res) end end |