[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]