From bb88b1aab8ce5aad01e11f1dbd574ab46ac44648 Mon Sep 17 00:00:00 2001 From: normal Date: Mon, 30 Oct 2017 23:56:44 +0000 Subject: webrick: support Proc objects as body responses * lib/webrick/httpresponse.rb (send_body): call send_body_proc (send_body_proc): new method (class ChunkedWrapper): new class * test/webrick/test_httpresponse.rb (test_send_body_proc): new test (test_send_body_proc_chunked): ditto [Feature #855] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60584 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- lib/webrick/httpresponse.rb | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'lib') diff --git a/lib/webrick/httpresponse.rb b/lib/webrick/httpresponse.rb index eae14d6597..2da1625fba 100644 --- a/lib/webrick/httpresponse.rb +++ b/lib/webrick/httpresponse.rb @@ -303,6 +303,8 @@ module WEBrick def send_body(socket) # :nodoc: if @body.respond_to? :readpartial then send_body_io(socket) + elsif @body.respond_to?(:call) then + send_body_proc(socket) else send_body_string(socket) end @@ -440,6 +442,39 @@ module WEBrick end end + def send_body_proc(socket) + if @request_method == "HEAD" + # do nothing + elsif chunked? + @body.call(ChunkedWrapper.new(socket, self)) + _write_data(socket, "0#{CRLF}#{CRLF}") + else + size = @header['content-length'].to_i + @body.call(socket) + @sent_size = size + end + end + + class ChunkedWrapper + def initialize(socket, resp) + @socket = socket + @resp = resp + end + + def write(buf) + return if buf.empty? + socket = @socket + @resp.instance_eval { + size = buf.bytesize + data = "#{size.to_s(16)}#{CRLF}#{buf}#{CRLF}" + _write_data(socket, data) + data.clear + @sent_size += size + } + end + alias :<< :write + end + def _send_file(output, input, offset, size) while offset > 0 sz = @buffer_size < size ? @buffer_size : size -- cgit v1.2.3