ruby-changes:23204
From: naruse <ko1@a...>
Date: Sun, 8 Apr 2012 06:51:05 +0900 (JST)
Subject: [ruby-changes:23204] naruse:r35253 (trunk): * lib/webrick/httpresponse.rb (WEBrick::HTTPResponse#send_body_io):
naruse 2012-04-08 06:50:34 +0900 (Sun, 08 Apr 2012) New Revision: 35253 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=35253 Log: * 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] Modified files: trunk/ChangeLog trunk/lib/webrick/httpresponse.rb trunk/test/webrick/test_httpserver.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 35252) +++ ChangeLog (revision 35253) @@ -1,3 +1,10 @@ +Sun Apr 8 06:46:48 2012 NARUSE, Yui <naruse@r...> + + * 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 <h.shirosaki@g...> * include/ruby/win32.h (rb_w32_aspawn_flags): add the declaration of Index: lib/webrick/httpresponse.rb =================================================================== --- lib/webrick/httpresponse.rb (revision 35252) +++ lib/webrick/httpresponse.rb (revision 35253) @@ -330,13 +330,18 @@ 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 Index: test/webrick/test_httpserver.rb =================================================================== --- test/webrick/test_httpserver.rb (revision 35252) +++ test/webrick/test_httpserver.rb (revision 35253) @@ -258,6 +258,70 @@ 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" -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/