From 84afd795b818062208e2148e8d08c8cdf75300ac Mon Sep 17 00:00:00 2001 From: naruse Date: Wed, 28 Mar 2018 12:50:56 +0000 Subject: merge revision(s) 62953-62959: win32/file.c: relative path with drive letter * win32/file.c (IS_ABSOLUTE_PATH_P): home directory should not be a relative path regardless a drive letter. PathIsRelativeW returns FALSE on such path. [ruby-core:86356] [Bug #14638] ------------------------------------------------------------------------ r62953 | normal | 2018-03-28 17:05:46 +0900 (Wed, 28 Mar 2018) | 15 lines webrick: favor .write over << method This will make the next change to use IO.copy_stream easier-to-read. When we can drop Ruby 2.4 support in a few years, this will allow us to use writev(2) with multiple arguments for headers and chunked responses. * lib/webrick/cgi.rb (write): new wrapper method lib/webrick/httpresponse.rb: (send_header): use socket.write (send_body_io): ditto (send_body_string): ditto (send_body_proc): ditto (_write_data): ditto (ChunkedWrapper#write): ditto (_send_file): ditto ------------------------------------------------------------------------ r62954 | normal | 2018-03-28 17:05:52 +0900 (Wed, 28 Mar 2018) | 14 lines webrick/httpresponse: IO.copy_stream for regular files Remove the redundant _send_file method since its functionality is unnecessary with IO.copy_stream. IO.copy_stream also allows the use of sendfile under some OSes to speed up copies to non-TLS sockets. Testing with "curl >/dev/null" and "ruby -run -e httpd" to read a 1G file over Linux loopback reveals a reduction from around ~0.770 to ~0.490 seconds on the client side. * lib/webrick/httpresponse.rb (send_body_io): use IO.copy_stream (_send_file): remove [Feature #14237] ------------------------------------------------------------------------ r62955 | normal | 2018-03-28 17:05:57 +0900 (Wed, 28 Mar 2018) | 10 lines webrick: use IO.copy_stream for single range response This is also compatible with range responses generated by Rack::File (tested with rack 2.0.3). * lib/webrick/httpresponse.rb (send_body_io): use Content-Range * lib/webrick/httpservlet/filehandler.rb (make_partial_content): use File object for the single range case * test/webrick/test_filehandler.rb (get_res_body): use send_body to test result ------------------------------------------------------------------------ r62956 | normal | 2018-03-28 17:06:02 +0900 (Wed, 28 Mar 2018) | 7 lines test/webrick/test_filehandler.rb: stricter multipart range test We need to ensure we generate compatibile output in the face of future changes * test/webrick/test_filehandler.rb (test_make_partial_content): check response body ------------------------------------------------------------------------ r62957 | normal | 2018-03-28 17:06:08 +0900 (Wed, 28 Mar 2018) | 8 lines webrick: quiet warning for multi-part ranges Content-Length is ignored by WEBrick::HTTPResponse even if we calculate it, so instead we chunk responses to HTTP/1.1 clients and terminate HTTP/1.0 connections. * lib/webrick/httpservlet/filehandler.rb (make_partial_content): quiet warning ------------------------------------------------------------------------ r62958 | normal | 2018-03-28 17:06:13 +0900 (Wed, 28 Mar 2018) | 7 lines webrick/httpresponse: make ChunkedWrapper copy_stream-compatible The .write method needs to return the number of bytes written to avoid confusing IO.copy_stream. * lib/webrick/httpresponse.rb (ChunkedWrapper#write): return bytes written (ChunkedWrapper#<<): return self ------------------------------------------------------------------------ r62959 | normal | 2018-03-28 17:06:18 +0900 (Wed, 28 Mar 2018) | 9 lines webrick: use IO.copy_stream for multipart response Use the new Proc response body feature to generate a multipart range response dynamically. We use a flat array to minimize object overhead as much as possible; as many ranges may fit into an HTTP request header. * lib/webrick/httpservlet/filehandler.rb (multipart_body): new method (make_partial_content): use multipart_body git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_5@63006 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- test/webrick/test_filehandler.rb | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) (limited to 'test') diff --git a/test/webrick/test_filehandler.rb b/test/webrick/test_filehandler.rb index 3fba1ec5e2..99bc1420b8 100644 --- a/test/webrick/test_filehandler.rb +++ b/test/webrick/test_filehandler.rb @@ -20,16 +20,10 @@ class WEBrick::TestFileHandler < Test::Unit::TestCase end def get_res_body(res) - body = res.body - if defined? body.read - begin - body.read - ensure - body.close - end - else - body - end + sio = StringIO.new + sio.binmode + res.send_body(sio) + sio.string end def make_range_request(range_spec) @@ -81,6 +75,23 @@ class WEBrick::TestFileHandler < Test::Unit::TestCase res = make_range_response(filename, "bytes=0-0, -2") assert_match(%r{^multipart/byteranges}, res["content-type"]) + body = get_res_body(res) + boundary = /; boundary=(.+)/.match(res['content-type'])[1] + off = filesize - 2 + last = filesize - 1 + + exp = "--#{boundary}\r\n" \ + "Content-Type: text/plain\r\n" \ + "Content-Range: bytes 0-0/#{filesize}\r\n" \ + "\r\n" \ + "#{IO.read(__FILE__, 1)}\r\n" \ + "--#{boundary}\r\n" \ + "Content-Type: text/plain\r\n" \ + "Content-Range: bytes #{off}-#{last}/#{filesize}\r\n" \ + "\r\n" \ + "#{IO.read(__FILE__, 2, off)}\r\n" \ + "--#{boundary}--\r\n" + assert_equal exp, body end def test_filehandler -- cgit v1.2.3