From e413325737f23c5ec27a02246f95077bc1fb038d Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Mon, 9 Mar 2015 04:35:18 +0000 Subject: acceptor: close inherited-but-unneeded sockets When inheriting sockets from the parent via YAHNS_FD, we must close sockets ASAP if they are unconfigured in the child. This bug exists in yahns (and not unicorn) because of the trickier shutdown routine we do for blocking accept system calls to work reliably with the threading support in mainline Ruby 2.x. This bug would not exist in a purely C server using blocking accept, either. --- test/test_server.rb | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'test') diff --git a/test/test_server.rb b/test/test_server.rb index 69babb3..b7cb3e6 100644 --- a/test/test_server.rb +++ b/test/test_server.rb @@ -804,4 +804,43 @@ class TestServer < Testcase ensure quit_wait(pid) end + + def test_inherit_too_many + err = @err + s2 = TCPServer.new(ENV["TEST_HOST"] || "127.0.0.1", 0) + cfg = Yahns::Config.new + host, port = @srv.addr[3], @srv.addr[1] + cfg.instance_eval do + ru = lambda { |_| [ 200, {'Content-Length'=>'2'}, ['HI'] ] } + GTL.synchronize { app(:rack, ru) { listen "#{host}:#{port}" } } + logger(Logger.new(err.path)) + end + mkserver(cfg, @srv) do + s2.autoclose = false + ENV["YAHNS_FD"] = "#{@srv.fileno},#{s2.fileno}" + end + run_client(host, port) { |res| assert_equal "HI", res.body } + th = Thread.new do + c = s2.accept + c.readpartial(1234) + c.write "HTTP/1.0 666 OK\r\n\r\nGO AWAY" + c.close + :OK + end + Thread.pass + s2host, s2port = s2.addr[3], s2.addr[1] + Net::HTTP.start(s2host, s2port) do |http| + res = http.request(Net::HTTP::Get.new("/")) + assert_equal 666, res.code.to_i + assert_equal "GO AWAY", res.body + end + assert_equal :OK, th.value + tmpc = TCPSocket.new(s2host, s2port) + a2 = s2.accept + assert_nil IO.select([a2], nil, nil, 0.05) + tmpc.close + assert_nil a2.read(1) + a2.close + s2.close + end end -- cgit v1.2.3-24-ge0c7