summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornaruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-04-07 21:50:34 +0000
committernaruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-04-07 21:50:34 +0000
commit56206ab8cd0e822e861ae963fc02e2343652d8e2 (patch)
treeabf1c211dddd47e6b61488497a0424ae0ce354d9
parent42109a02f02b5e55a45df4f6bf3103c88be340cd (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--ChangeLog7
-rw-r--r--lib/webrick/httpresponse.rb19
-rw-r--r--test/webrick/test_httpserver.rb64
3 files changed, 83 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index a746048bd6..e7b0fdf8ee 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Sun Apr 8 06:46:48 2012 NARUSE, Yui <naruse@ruby-lang.org>
+
+ * 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@gmail.com>
* 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"