diff options
author | naruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-04-07 21:50:34 +0000 |
---|---|---|
committer | naruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-04-07 21:50:34 +0000 |
commit | 56206ab8cd0e822e861ae963fc02e2343652d8e2 (patch) | |
tree | abf1c211dddd47e6b61488497a0424ae0ce354d9 | |
parent | 42109a02f02b5e55a45df4f6bf3103c88be340cd (diff) |
* lib/webrick/httpresponse.rb (WEBrick::HTTPResponse#send_body_io):
use readpartial to get data even if the response is streaming data and
each data is smaller than @buffer_size.
patched by yu nobuoka. [ruby-dev:45471] [Bug #6230]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@35253 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | lib/webrick/httpresponse.rb | 19 | ||||
-rw-r--r-- | test/webrick/test_httpserver.rb | 64 |
3 files changed, 83 insertions, 7 deletions
@@ -1,3 +1,10 @@ +Sun Apr 8 06:46:48 2012 NARUSE, Yui <[email protected]> + + * lib/webrick/httpresponse.rb (WEBrick::HTTPResponse#send_body_io): + use readpartial to get data even if the response is streaming data and + each data is smaller than @buffer_size. + patched by yu nobuoka. [ruby-dev:45471] [Bug #6230] + Sat Apr 7 22:35:36 2012 Hiroshi Shirosaki <[email protected]> * include/ruby/win32.h (rb_w32_aspawn_flags): add the declaration of diff --git a/lib/webrick/httpresponse.rb b/lib/webrick/httpresponse.rb index baa49dea92..5adbc82173 100644 --- a/lib/webrick/httpresponse.rb +++ b/lib/webrick/httpresponse.rb @@ -330,13 +330,18 @@ module WEBrick if @request_method == "HEAD" # do nothing elsif chunked? - while buf = @body.read(@buffer_size) - next if buf.empty? - data = "" - data << format("%x", buf.bytesize) << CRLF - data << buf << CRLF - _write_data(socket, data) - @sent_size += buf.bytesize + begin + buf = '' + data = '' + while true + @body.readpartial( @buffer_size, buf ) # there is no need to clear buf? + data << format("%x", buf.bytesize) << CRLF + data << buf << CRLF + _write_data(socket, data) + data.clear + @sent_size += buf.bytesize + end + rescue EOFError # do nothing end _write_data(socket, "0#{CRLF}#{CRLF}") else diff --git a/test/webrick/test_httpserver.rb b/test/webrick/test_httpserver.rb index 526d72c381..bbfef53611 100644 --- a/test/webrick/test_httpserver.rb +++ b/test/webrick/test_httpserver.rb @@ -258,6 +258,70 @@ class TestWEBrickHTTPServer < Test::Unit::TestCase assert_equal(stopped, 1) end + # This class is needed by test_response_io_with_chunked_set method + class EventManagerForChunkedResponseTest + def initialize + @listeners = [] + end + def add_listener( &block ) + @listeners << block + end + def raise_str_event( str ) + @listeners.each{ |e| e.call( :str, str ) } + end + def raise_close_event() + @listeners.each{ |e| e.call( :cls ) } + end + end + def test_response_io_with_chunked_set + evt_man = EventManagerForChunkedResponseTest.new + t = Thread.new do + begin + config = { + :ServerName => "localhost" + } + TestWEBrick.start_httpserver(config) do |server, addr, port, log| + body_strs = [ 'aaaaaa', 'bb', 'cccc' ] + server.mount_proc( "/", ->( req, res ){ + # Test for setting chunked... + res.chunked = true + r,w = IO.pipe + evt_man.add_listener do |type,str| + type == :cls ? ( w.close ) : ( w << str ) + end + res.body = r + } ) + Thread.pass while server.status != :Running + http = Net::HTTP.new(addr, port) + req = Net::HTTP::Get.new("/") + http.request(req) do |res| + i = 0 + evt_man.raise_str_event( body_strs[i] ) + res.read_body do |s| + assert_equal( body_strs[i], s ) + i += 1 + if i < body_strs.length + evt_man.raise_str_event( body_strs[i] ) + else + evt_man.raise_close_event() + end + end + assert_equal( body_strs.length, i ) + end + end + rescue => err + flunk( 'exception raised in thread: ' + err.to_s ) + end + end + if t.join( 3 ).nil? + evt_man.raise_close_event() + flunk( 'timeout' ) + if t.join( 1 ).nil? + Thread.kill t + end + end + end + def test_response_io_without_chunked_set config = { :ServerName => "localhost" |