From fcbf63e62c627deae76c1b8cb8c0876c536ed811 Mon Sep 17 00:00:00 2001 From: Jari Vetoniemi Date: Mon, 16 Mar 2020 18:49:26 +0900 Subject: Fresh start --- jni/ruby/test/webrick/test_httpserver.rb | 412 +++++++++++++++++++++++++++++++ 1 file changed, 412 insertions(+) create mode 100644 jni/ruby/test/webrick/test_httpserver.rb (limited to 'jni/ruby/test/webrick/test_httpserver.rb') diff --git a/jni/ruby/test/webrick/test_httpserver.rb b/jni/ruby/test/webrick/test_httpserver.rb new file mode 100644 index 0000000..5cd4ba5 --- /dev/null +++ b/jni/ruby/test/webrick/test_httpserver.rb @@ -0,0 +1,412 @@ +require "test/unit" +require "net/http" +require "webrick" +require_relative "utils" + +class TestWEBrickHTTPServer < Test::Unit::TestCase + empty_log = Object.new + def empty_log.<<(str) + assert_equal('', str) + self + end + NoLog = WEBrick::Log.new(empty_log, WEBrick::BasicLog::WARN) + + def test_mount + httpd = WEBrick::HTTPServer.new( + :Logger => NoLog, + :DoNotListen=>true + ) + httpd.mount("/", :Root) + httpd.mount("/foo", :Foo) + httpd.mount("/foo/bar", :Bar, :bar1) + httpd.mount("/foo/bar/baz", :Baz, :baz1, :baz2) + + serv, opts, script_name, path_info = httpd.search_servlet("/") + assert_equal(:Root, serv) + assert_equal([], opts) + assert_equal("", script_name) + assert_equal("/", path_info) + + serv, opts, script_name, path_info = httpd.search_servlet("/sub") + assert_equal(:Root, serv) + assert_equal([], opts) + assert_equal("", script_name) + assert_equal("/sub", path_info) + + serv, opts, script_name, path_info = httpd.search_servlet("/sub/") + assert_equal(:Root, serv) + assert_equal([], opts) + assert_equal("", script_name) + assert_equal("/sub/", path_info) + + serv, opts, script_name, path_info = httpd.search_servlet("/foo") + assert_equal(:Foo, serv) + assert_equal([], opts) + assert_equal("/foo", script_name) + assert_equal("", path_info) + + serv, opts, script_name, path_info = httpd.search_servlet("/foo/") + assert_equal(:Foo, serv) + assert_equal([], opts) + assert_equal("/foo", script_name) + assert_equal("/", path_info) + + serv, opts, script_name, path_info = httpd.search_servlet("/foo/sub") + assert_equal(:Foo, serv) + assert_equal([], opts) + assert_equal("/foo", script_name) + assert_equal("/sub", path_info) + + serv, opts, script_name, path_info = httpd.search_servlet("/foo/bar") + assert_equal(:Bar, serv) + assert_equal([:bar1], opts) + assert_equal("/foo/bar", script_name) + assert_equal("", path_info) + + serv, opts, script_name, path_info = httpd.search_servlet("/foo/bar/baz") + assert_equal(:Baz, serv) + assert_equal([:baz1, :baz2], opts) + assert_equal("/foo/bar/baz", script_name) + assert_equal("", path_info) + end + + class Req + attr_reader :port, :host + def initialize(addr, port, host) + @addr, @port, @host = addr, port, host + end + def addr + [0,0,0,@addr] + end + end + + def httpd(addr, port, host, ali) + config ={ + :Logger => NoLog, + :DoNotListen => true, + :BindAddress => addr, + :Port => port, + :ServerName => host, + :ServerAlias => ali, + } + return WEBrick::HTTPServer.new(config) + end + + def assert_eql?(v1, v2) + assert_equal(v1.object_id, v2.object_id) + end + + def test_lookup_server + addr1 = "192.168.100.1" + addr2 = "192.168.100.2" + addrz = "192.168.100.254" + local = "127.0.0.1" + port1 = 80 + port2 = 8080 + port3 = 10080 + portz = 32767 + name1 = "www.example.com" + name2 = "www2.example.com" + name3 = "www3.example.com" + namea = "www.example.co.jp" + nameb = "www.example.jp" + namec = "www2.example.co.jp" + named = "www2.example.jp" + namez = "foobar.example.com" + alias1 = [namea, nameb] + alias2 = [namec, named] + + host1 = httpd(nil, port1, name1, nil) + hosts = [ + host2 = httpd(addr1, port1, name1, nil), + host3 = httpd(addr1, port1, name2, alias1), + host4 = httpd(addr1, port2, name1, nil), + host5 = httpd(addr1, port2, name2, alias1), + httpd(addr1, port2, name3, alias2), + host7 = httpd(addr2, nil, name1, nil), + host8 = httpd(addr2, nil, name2, alias1), + httpd(addr2, nil, name3, alias2), + host10 = httpd(local, nil, nil, nil), + host11 = httpd(nil, port3, nil, nil), + ].sort_by{ rand } + hosts.each{|h| host1.virtual_host(h) } + + # connect to addr1 + assert_eql?(host2, host1.lookup_server(Req.new(addr1, port1, name1))) + assert_eql?(host3, host1.lookup_server(Req.new(addr1, port1, name2))) + assert_eql?(host3, host1.lookup_server(Req.new(addr1, port1, namea))) + assert_eql?(host3, host1.lookup_server(Req.new(addr1, port1, nameb))) + assert_eql?(nil, host1.lookup_server(Req.new(addr1, port1, namez))) + assert_eql?(host4, host1.lookup_server(Req.new(addr1, port2, name1))) + assert_eql?(host5, host1.lookup_server(Req.new(addr1, port2, name2))) + assert_eql?(host5, host1.lookup_server(Req.new(addr1, port2, namea))) + assert_eql?(host5, host1.lookup_server(Req.new(addr1, port2, nameb))) + assert_eql?(nil, host1.lookup_server(Req.new(addr1, port2, namez))) + assert_eql?(host11, host1.lookup_server(Req.new(addr1, port3, name1))) + assert_eql?(host11, host1.lookup_server(Req.new(addr1, port3, name2))) + assert_eql?(host11, host1.lookup_server(Req.new(addr1, port3, namea))) + assert_eql?(host11, host1.lookup_server(Req.new(addr1, port3, nameb))) + assert_eql?(host11, host1.lookup_server(Req.new(addr1, port3, namez))) + assert_eql?(nil, host1.lookup_server(Req.new(addr1, portz, name1))) + assert_eql?(nil, host1.lookup_server(Req.new(addr1, portz, name2))) + assert_eql?(nil, host1.lookup_server(Req.new(addr1, portz, namea))) + assert_eql?(nil, host1.lookup_server(Req.new(addr1, portz, nameb))) + assert_eql?(nil, host1.lookup_server(Req.new(addr1, portz, namez))) + + # connect to addr2 + assert_eql?(host7, host1.lookup_server(Req.new(addr2, port1, name1))) + assert_eql?(host8, host1.lookup_server(Req.new(addr2, port1, name2))) + assert_eql?(host8, host1.lookup_server(Req.new(addr2, port1, namea))) + assert_eql?(host8, host1.lookup_server(Req.new(addr2, port1, nameb))) + assert_eql?(nil, host1.lookup_server(Req.new(addr2, port1, namez))) + assert_eql?(host7, host1.lookup_server(Req.new(addr2, port2, name1))) + assert_eql?(host8, host1.lookup_server(Req.new(addr2, port2, name2))) + assert_eql?(host8, host1.lookup_server(Req.new(addr2, port2, namea))) + assert_eql?(host8, host1.lookup_server(Req.new(addr2, port2, nameb))) + assert_eql?(nil, host1.lookup_server(Req.new(addr2, port2, namez))) + assert_eql?(host7, host1.lookup_server(Req.new(addr2, port3, name1))) + assert_eql?(host8, host1.lookup_server(Req.new(addr2, port3, name2))) + assert_eql?(host8, host1.lookup_server(Req.new(addr2, port3, namea))) + assert_eql?(host8, host1.lookup_server(Req.new(addr2, port3, nameb))) + assert_eql?(host11, host1.lookup_server(Req.new(addr2, port3, namez))) + assert_eql?(host7, host1.lookup_server(Req.new(addr2, portz, name1))) + assert_eql?(host8, host1.lookup_server(Req.new(addr2, portz, name2))) + assert_eql?(host8, host1.lookup_server(Req.new(addr2, portz, namea))) + assert_eql?(host8, host1.lookup_server(Req.new(addr2, portz, nameb))) + assert_eql?(nil, host1.lookup_server(Req.new(addr2, portz, namez))) + + # connect to addrz + assert_eql?(nil, host1.lookup_server(Req.new(addrz, port1, name1))) + assert_eql?(nil, host1.lookup_server(Req.new(addrz, port1, name2))) + assert_eql?(nil, host1.lookup_server(Req.new(addrz, port1, namea))) + assert_eql?(nil, host1.lookup_server(Req.new(addrz, port1, nameb))) + assert_eql?(nil, host1.lookup_server(Req.new(addrz, port1, namez))) + assert_eql?(nil, host1.lookup_server(Req.new(addrz, port2, name1))) + assert_eql?(nil, host1.lookup_server(Req.new(addrz, port2, name2))) + assert_eql?(nil, host1.lookup_server(Req.new(addrz, port2, namea))) + assert_eql?(nil, host1.lookup_server(Req.new(addrz, port2, nameb))) + assert_eql?(nil, host1.lookup_server(Req.new(addrz, port2, namez))) + assert_eql?(host11, host1.lookup_server(Req.new(addrz, port3, name1))) + assert_eql?(host11, host1.lookup_server(Req.new(addrz, port3, name2))) + assert_eql?(host11, host1.lookup_server(Req.new(addrz, port3, namea))) + assert_eql?(host11, host1.lookup_server(Req.new(addrz, port3, nameb))) + assert_eql?(host11, host1.lookup_server(Req.new(addrz, port3, namez))) + assert_eql?(nil, host1.lookup_server(Req.new(addrz, portz, name1))) + assert_eql?(nil, host1.lookup_server(Req.new(addrz, portz, name2))) + assert_eql?(nil, host1.lookup_server(Req.new(addrz, portz, namea))) + assert_eql?(nil, host1.lookup_server(Req.new(addrz, portz, nameb))) + assert_eql?(nil, host1.lookup_server(Req.new(addrz, portz, namez))) + + # connect to localhost + assert_eql?(host10, host1.lookup_server(Req.new(local, port1, name1))) + assert_eql?(host10, host1.lookup_server(Req.new(local, port1, name2))) + assert_eql?(host10, host1.lookup_server(Req.new(local, port1, namea))) + assert_eql?(host10, host1.lookup_server(Req.new(local, port1, nameb))) + assert_eql?(host10, host1.lookup_server(Req.new(local, port1, namez))) + assert_eql?(host10, host1.lookup_server(Req.new(local, port2, name1))) + assert_eql?(host10, host1.lookup_server(Req.new(local, port2, name2))) + assert_eql?(host10, host1.lookup_server(Req.new(local, port2, namea))) + assert_eql?(host10, host1.lookup_server(Req.new(local, port2, nameb))) + assert_eql?(host10, host1.lookup_server(Req.new(local, port2, namez))) + assert_eql?(host10, host1.lookup_server(Req.new(local, port3, name1))) + assert_eql?(host10, host1.lookup_server(Req.new(local, port3, name2))) + assert_eql?(host10, host1.lookup_server(Req.new(local, port3, namea))) + assert_eql?(host10, host1.lookup_server(Req.new(local, port3, nameb))) + assert_eql?(host10, host1.lookup_server(Req.new(local, port3, namez))) + assert_eql?(host10, host1.lookup_server(Req.new(local, portz, name1))) + assert_eql?(host10, host1.lookup_server(Req.new(local, portz, name2))) + assert_eql?(host10, host1.lookup_server(Req.new(local, portz, namea))) + assert_eql?(host10, host1.lookup_server(Req.new(local, portz, nameb))) + assert_eql?(host10, host1.lookup_server(Req.new(local, portz, namez))) + end + + def test_callbacks + accepted = started = stopped = 0 + requested0 = requested1 = 0 + config = { + :ServerName => "localhost", + :AcceptCallback => Proc.new{ accepted += 1 }, + :StartCallback => Proc.new{ started += 1 }, + :StopCallback => Proc.new{ stopped += 1 }, + :RequestCallback => Proc.new{|req, res| requested0 += 1 }, + } + log_tester = lambda {|log, access_log| + assert(log.find {|s| %r{ERROR `/' not found\.} =~ s }) + assert_equal([], log.reject {|s| %r{ERROR `/' not found\.} =~ s }) + } + TestWEBrick.start_httpserver(config, log_tester){|server, addr, port, log| + vhost_config = { + :ServerName => "myhostname", + :BindAddress => addr, + :Port => port, + :DoNotListen => true, + :Logger => NoLog, + :AccessLog => [], + :RequestCallback => Proc.new{|req, res| requested1 += 1 }, + } + server.virtual_host(WEBrick::HTTPServer.new(vhost_config)) + + Thread.pass while server.status != :Running + assert_equal(1, started, log.call) + assert_equal(0, stopped, log.call) + assert_equal(0, accepted, log.call) + + http = Net::HTTP.new(addr, port) + req = Net::HTTP::Get.new("/") + req["Host"] = "myhostname:#{port}" + http.request(req){|res| assert_equal("404", res.code, log.call)} + http.request(req){|res| assert_equal("404", res.code, log.call)} + http.request(req){|res| assert_equal("404", res.code, log.call)} + req["Host"] = "localhost:#{port}" + http.request(req){|res| assert_equal("404", res.code, log.call)} + http.request(req){|res| assert_equal("404", res.code, log.call)} + http.request(req){|res| assert_equal("404", res.code, log.call)} + assert_equal(6, accepted, log.call) + assert_equal(3, requested0, log.call) + assert_equal(3, requested1, log.call) + } + assert_equal(started, 1) + 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" + } + log_tester = lambda {|log, access_log| + assert_equal(1, log.length) + assert_match(/WARN Could not determine content-length of response body./, log[0]) + } + TestWEBrick.start_httpserver(config, log_tester){|server, addr, port, log| + server.mount_proc("/", lambda { |req, res| + r,w = IO.pipe + # Test for not setting chunked... + # res.chunked = true + res.body = r + w << "foo" + w.close + }) + Thread.pass while server.status != :Running + http = Net::HTTP.new(addr, port) + req = Net::HTTP::Get.new("/") + req['Connection'] = 'Keep-Alive' + begin + timeout(2) do + http.request(req){|res| assert_equal("foo", res.body) } + end + rescue Timeout::Error + flunk('corrupted reponse') + end + } + end + + def test_request_handler_callback_is_deprecated + requested = 0 + config = { + :ServerName => "localhost", + :RequestHandler => Proc.new{|req, res| requested += 1 }, + } + log_tester = lambda {|log, access_log| + assert_equal(2, log.length) + assert_match(/WARN :RequestHandler is deprecated, please use :RequestCallback/, log[0]) + assert_match(%r{ERROR `/' not found\.}, log[1]) + } + TestWEBrick.start_httpserver(config, log_tester){|server, addr, port, log| + Thread.pass while server.status != :Running + + http = Net::HTTP.new(addr, port) + req = Net::HTTP::Get.new("/") + req["Host"] = "localhost:#{port}" + http.request(req){|res| assert_equal("404", res.code, log.call)} + assert_match(%r{:RequestHandler is deprecated, please use :RequestCallback$}, log.call, log.call) + } + assert_equal(1, requested) + end + + def test_shutdown_with_busy_keepalive_connection + requested = 0 + config = { + :ServerName => "localhost", + } + TestWEBrick.start_httpserver(config){|server, addr, port, log| + server.mount_proc("/", lambda {|req, res| res.body = "heffalump" }) + Thread.pass while server.status != :Running + + Net::HTTP.start(addr, port) do |http| + req = Net::HTTP::Get.new("/") + http.request(req){|res| assert_equal('Keep-Alive', res['Connection'], log.call) } + server.shutdown + begin + 10.times {|n| http.request(req); requested += 1 } + rescue + # Errno::ECONNREFUSED or similar + end + end + } + assert_equal(0, requested, "Server responded to #{requested} requests after shutdown") + end +end -- cgit v1.2.3