rainbows 3.3.0 → 3.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -17,3 +17,5 @@ pkg/
17
17
  /GIT-VERSION-FILE
18
18
  /man
19
19
  /LATEST
20
+ tags
21
+ TAGS
@@ -1,7 +1,7 @@
1
1
  #!/bin/sh
2
2
 
3
3
  GVF=GIT-VERSION-FILE
4
- DEF_VER=v3.3.0.GIT
4
+ DEF_VER=v3.4.0.GIT
5
5
 
6
6
  LF='
7
7
  '
@@ -29,4 +29,6 @@ class Rainbows::Client < Kgio::Socket
29
29
  end
30
30
  end while true
31
31
  end
32
+
33
+ alias write kgio_write
32
34
  end
@@ -190,7 +190,9 @@ module Rainbows::Configurator
190
190
  # end
191
191
  #
192
192
  # Keep in mind that splice(2) itself is a relatively new system call
193
- # and has been buggy in many older Linux kernels.
193
+ # and has been buggy in many older Linux kernels. If you're proxying
194
+ # the output of sockets to the client, be sure to use "io_splice"
195
+ # 4.1.1 or later to avoid stalling responses.
194
196
  #
195
197
  # Default: IO on Ruby 1.9+, false otherwise
196
198
  def copy_stream(klass)
@@ -9,6 +9,7 @@ class Rainbows::Coolio::Heartbeat < Coolio::TimerWatcher
9
9
  KATO = Rainbows::Coolio::KATO
10
10
  CONN = Rainbows::Coolio::CONN
11
11
  Rainbows.config!(self, :keepalive_timeout)
12
+ Rainbows.at_quit { KATO.each_key { |client| client.timeout? }.clear }
12
13
 
13
14
  def on_timer
14
15
  if (ot = KEEPALIVE_TIMEOUT) >= 0
@@ -22,44 +22,27 @@ require 'sendfile'
22
22
  # === RubyGem Requirements
23
23
  #
24
24
  # * raindrops 0.6.0 or later
25
- # * sleepy_penguin 2.0.0 or later
25
+ # * sleepy_penguin 3.0.1 or later
26
26
  # * sendfile 1.1.0 or later
27
27
  #
28
28
  module Rainbows::Epoll
29
29
  # :stopdoc:
30
30
  include Rainbows::Base
31
- ReRun = []
32
31
  autoload :Server, 'rainbows/epoll/server'
33
32
  autoload :Client, 'rainbows/epoll/client'
34
33
  autoload :ResponsePipe, 'rainbows/epoll/response_pipe'
35
34
  autoload :ResponseChunkPipe, 'rainbows/epoll/response_chunk_pipe'
36
- class << self
37
- attr_writer :nr_clients
38
- end
39
-
40
- def self.loop
41
- begin
42
- EP.wait(nil, 1000) { |_, obj| obj.epoll_run }
43
- while obj = ReRun.shift
44
- obj.epoll_run
45
- end
46
- Rainbows::Epoll::Client.expire
47
- rescue Errno::EINTR
48
- rescue => e
49
- Rainbows::Error.listen_loop(e)
50
- end while Rainbows.tick || @nr_clients.call > 0
51
- end
52
35
 
53
36
  def init_worker_process(worker)
54
37
  super
55
- Rainbows::Epoll.const_set :EP, SleepyPenguin::Epoll.new
56
- Rainbows.at_quit { Rainbows::Epoll::EP.close }
38
+ Rainbows.const_set(:EP, SleepyPenguin::Epoll.new)
57
39
  Rainbows::Client.__send__ :include, Client
40
+ LISTENERS.each { |io| io.extend(Server) }
58
41
  end
59
42
 
60
43
  def worker_loop(worker) # :nodoc:
61
44
  init_worker_process(worker)
62
- Server.run
45
+ Client.loop
63
46
  end
64
47
  # :startdoc:
65
48
  end
@@ -10,8 +10,10 @@ module Rainbows::Epoll::Client
10
10
  OUT = SleepyPenguin::Epoll::OUT | SleepyPenguin::Epoll::ET
11
11
  KATO = {}
12
12
  KATO.compare_by_identity if KATO.respond_to?(:compare_by_identity)
13
+ Rainbows.at_quit { KATO.each_key { |k| k.timeout! }.clear }
13
14
  Rainbows.config!(self, :keepalive_timeout)
14
- EP = Rainbows::Epoll::EP
15
+ EP = Rainbows::EP
16
+ ReRun = []
15
17
  @@last_expire = Time.now
16
18
 
17
19
  def self.expire
@@ -23,6 +25,19 @@ module Rainbows::Epoll::Client
23
25
  @@last_expire = now
24
26
  end
25
27
 
28
+ def self.loop
29
+ begin
30
+ EP.wait(nil, 1000) { |_, obj| obj.epoll_run }
31
+ while obj = ReRun.shift
32
+ obj.epoll_run
33
+ end
34
+ expire
35
+ rescue Errno::EINTR
36
+ rescue => e
37
+ Rainbows::Error.listen_loop(e)
38
+ end while Rainbows.tick || Server.nr > 0
39
+ end
40
+
26
41
  # only call this once
27
42
  def epoll_once
28
43
  @wr_queue = [] # may contain String, ResponsePipe, and StreamFile objects
@@ -100,7 +115,7 @@ module Rainbows::Epoll::Client
100
115
  end
101
116
 
102
117
  def want_more
103
- Rainbows::Epoll::ReRun << self
118
+ ReRun << self
104
119
  end
105
120
 
106
121
  def on_deferred_write_complete
@@ -5,7 +5,7 @@ class Rainbows::Epoll::ResponsePipe
5
5
  attr_reader :io
6
6
  alias to_io io
7
7
  RBUF = Rainbows::EvCore::RBUF
8
- EP = Rainbows::Epoll::EP
8
+ EP = Rainbows::EP
9
9
 
10
10
  def initialize(io, client, body)
11
11
  @io, @client, @body = io, client, body
@@ -2,16 +2,14 @@
2
2
  # :enddoc:
3
3
  module Rainbows::Epoll::Server
4
4
  @@nr = 0
5
- Rainbows::Epoll.nr_clients = lambda { @@nr }
6
5
  IN = SleepyPenguin::Epoll::IN | SleepyPenguin::Epoll::ET
7
6
  MAX = Rainbows.server.worker_connections
8
7
  THRESH = MAX - 1
9
8
  LISTENERS = Rainbows::HttpServer::LISTENERS
10
- EP = Rainbows::Epoll::EP
9
+ EP = Rainbows::EP
11
10
 
12
- def self.run
13
- LISTENERS.each { |sock| EP.add(sock.extend(self), IN) }
14
- Rainbows::Epoll.loop
11
+ def self.nr
12
+ @@nr
15
13
  end
16
14
 
17
15
  # rearms all listeners when there's a free slot
@@ -19,6 +17,10 @@ module Rainbows::Epoll::Server
19
17
  THRESH == (@@nr -= 1) and LISTENERS.each { |sock| EP.set(sock, IN) }
20
18
  end
21
19
 
20
+ def self.extended(sock)
21
+ EP.set(sock, IN)
22
+ end
23
+
22
24
  def epoll_run
23
25
  return EP.delete(self) if @@nr >= MAX
24
26
  while io = kgio_tryaccept
@@ -32,9 +32,7 @@ EM::VERSION >= '0.12.10' or abort 'eventmachine 0.12.10 is required'
32
32
  # all request processing is complete.
33
33
  #
34
34
  # Merb (and other frameworks/apps) supporting +deferred?+ execution as
35
- # documented at http://brainspl.at/articles/2008/04/18/deferred-requests-with-merb-ebb-and-thin
36
- # will also get the ability to conditionally defer request processing
37
- # to a separate thread.
35
+ # documented at Rainbows::EventMachine::TryDefer
38
36
  #
39
37
  # This model does not implement as streaming "rack.input" which allows
40
38
  # the Rack application to process data as it arrives. This means
@@ -74,11 +72,11 @@ module Rainbows::EventMachine
74
72
  conns = EM.instance_variable_get(:@conns) or
75
73
  raise RuntimeError, "EM @conns instance variable not accessible!"
76
74
  Rainbows::EventMachine::Server.const_set(:CUR, conns)
75
+ Rainbows.at_quit do
76
+ EM.next_tick { conns.each_value { |c| client_class === c and c.quit } }
77
+ end
77
78
  EM.add_periodic_timer(1) do
78
- unless Rainbows.tick
79
- conns.each_value { |c| client_class === c and c.quit }
80
- EM.stop if conns.empty? && EM.reactor_running?
81
- end
79
+ EM.stop if ! Rainbows.tick && conns.empty? && EM.reactor_running?
82
80
  end
83
81
  LISTENERS.map! do |s|
84
82
  EM.watch(s, Rainbows::EventMachine::Server) do |c|
@@ -1,27 +1,32 @@
1
1
  # -*- encoding: binary -*-
2
- # :enddoc:
3
2
 
4
3
  # Middleware that will run the app dispatch in a separate thread.
5
4
  # This middleware is automatically loaded by Rainbows! when using
6
5
  # EventMachine and if the app responds to the +deferred?+ method.
7
- class Rainbows::EventMachine::TryDefer < Struct.new(:app)
6
+ #
7
+ # Use EM.threadpool_size in your \Rainbows! config file to control
8
+ # the number of threads used by EventMachine.
9
+ #
10
+ # See http://brainspl.at/articles/2008/04/18/deferred-requests-with-merb-ebb-and-thin
11
+ # for more information.
12
+ class Rainbows::EventMachine::TryDefer
8
13
  # shortcuts
9
- ASYNC_CALLBACK = Rainbows::EvCore::ASYNC_CALLBACK
14
+ ASYNC_CALLBACK = Rainbows::EvCore::ASYNC_CALLBACK # :nodoc:
10
15
 
11
- def initialize(app)
16
+ def initialize(app) # :nodoc:
12
17
  # the entire app becomes multithreaded, even the root (non-deferred)
13
18
  # thread since any thread can share processes with others
14
19
  Rainbows::Const::RACK_DEFAULTS['rack.multithread'] = true
15
- super
20
+ @app = app
16
21
  end
17
22
 
18
- def call(env)
19
- if app.deferred?(env)
20
- EM.defer(proc { catch(:async) { app.call(env) } }, env[ASYNC_CALLBACK])
23
+ def call(env) # :nodoc:
24
+ if @app.deferred?(env)
25
+ EM.defer(proc { catch(:async) { @app.call(env) } }, env[ASYNC_CALLBACK])
21
26
  # all of the async/deferred stuff breaks Rack::Lint :<
22
27
  nil
23
28
  else
24
- app.call(env)
29
+ @app.call(env)
25
30
  end
26
31
  end
27
32
  end
@@ -10,7 +10,7 @@ require 'rainbows/epoll'
10
10
  # === RubyGem Requirements
11
11
  #
12
12
  # * raindrops 0.6.0 or later
13
- # * sleepy_penguin 2.0.0 or later
13
+ # * sleepy_penguin 3.0.1 or later
14
14
  # * sendfile 1.1.0 or later
15
15
  module Rainbows::XEpoll
16
16
  # :stopdoc:
@@ -19,14 +19,13 @@ module Rainbows::XEpoll
19
19
 
20
20
  def init_worker_process(worker)
21
21
  super
22
- Rainbows::Epoll.const_set :EP, SleepyPenguin::Epoll.new
23
- Rainbows.at_quit { Rainbows::Epoll::EP.close }
22
+ Rainbows.const_set(:EP, SleepyPenguin::Epoll.new)
24
23
  Rainbows::Client.__send__ :include, Client
25
24
  end
26
25
 
27
26
  def worker_loop(worker) # :nodoc:
28
27
  init_worker_process(worker)
29
- Client.run
28
+ Client.loop
30
29
  end
31
30
  # :startdoc:
32
31
  end
@@ -3,9 +3,7 @@
3
3
 
4
4
  module Rainbows::XEpoll::Client
5
5
  N = Raindrops.new(1)
6
- Rainbows::Epoll.nr_clients = lambda { N[0] }
7
6
  include Rainbows::Epoll::Client
8
- EP = Rainbows::Epoll::EP
9
7
  ACCEPTORS = Rainbows::HttpServer::LISTENERS.dup
10
8
  extend Rainbows::WorkerYield
11
9
 
@@ -26,8 +24,17 @@ module Rainbows::XEpoll::Client
26
24
  end
27
25
  end
28
26
 
29
- def self.run
30
- Rainbows::Epoll.loop
27
+ def self.loop
28
+ begin
29
+ EP.wait(nil, 1000) { |_, obj| obj.epoll_run }
30
+ while obj = ReRun.shift
31
+ obj.epoll_run
32
+ end
33
+ Rainbows::Epoll::Client.expire
34
+ rescue Errno::EINTR
35
+ rescue => e
36
+ Rainbows::Error.listen_loop(e)
37
+ end while Rainbows.tick || N[0] > 0
31
38
  Rainbows::JoinThreads.acceptors(ACCEPTORS)
32
39
  end
33
40
 
@@ -61,7 +61,7 @@ require "raindrops"
61
61
  # === RubyGem Requirements
62
62
  #
63
63
  # * raindrops 0.6.0 or later
64
- # * sleepy_penguin 2.0.0 or later
64
+ # * sleepy_penguin 3.0.1 or later
65
65
  module Rainbows::XEpollThreadPool
66
66
  extend Rainbows::PoolSize
67
67
 
@@ -37,11 +37,15 @@ module Rainbows::XEpollThreadPool::Client
37
37
 
38
38
  ep = SleepyPenguin::Epoll
39
39
  EP = ep.new
40
- Rainbows.at_quit { EP.close }
41
40
  IN = ep::IN | ep::ET | ep::ONESHOT
42
41
  KATO = {}
43
42
  KATO.compare_by_identity if KATO.respond_to?(:compare_by_identity)
44
43
  LOCK = Mutex.new
44
+ Rainbows.at_quit do
45
+ clients = nil
46
+ LOCK.synchronize { clients = KATO.keys; KATO.clear }
47
+ clients.each { |io| io.closed? or io.close }
48
+ end
45
49
  @@last_expire = Time.now
46
50
 
47
51
  def kato_set
@@ -123,7 +127,7 @@ module Rainbows::XEpollThreadPool::Client
123
127
  def pipeline_ready(hp)
124
128
  # be fair to other clients, let others run first
125
129
  hp.parse and return queue!
126
- kato_set
130
+ epoll_run("")
127
131
  false
128
132
  end
129
133
  end
@@ -39,7 +39,7 @@ require "raindrops"
39
39
  # === RubyGem Requirements
40
40
  #
41
41
  # * raindrops 0.6.0 or later
42
- # * sleepy_penguin 2.0.0 or later
42
+ # * sleepy_penguin 3.0.1 or later
43
43
  module Rainbows::XEpollThreadSpawn
44
44
  # :stopdoc:
45
45
  include Rainbows::Base
@@ -26,11 +26,15 @@ module Rainbows::XEpollThreadSpawn::Client
26
26
 
27
27
  ep = SleepyPenguin::Epoll
28
28
  EP = ep.new
29
- Rainbows.at_quit { EP.close }
30
29
  IN = ep::IN | ep::ET | ep::ONESHOT
31
30
  KATO = {}
32
31
  KATO.compare_by_identity if KATO.respond_to?(:compare_by_identity)
33
32
  LOCK = Mutex.new
33
+ Rainbows.at_quit do
34
+ clients = nil
35
+ LOCK.synchronize { clients = KATO.keys; KATO.clear }
36
+ clients.each { |io| io.closed? or io.close }
37
+ end
34
38
  @@last_expire = Time.now
35
39
 
36
40
  def kato_set
data/pkg.mk CHANGED
@@ -69,7 +69,7 @@ doc:: .document .wrongdoc.yml $(pkg_extra)
69
69
  $(RM) -r doc
70
70
  $(WRONGDOC) all
71
71
  install -m644 COPYING doc/COPYING
72
- install -m644 $(shell grep '^[A-Z]' .document) doc/
72
+ install -m644 $(shell LC_ALL=C grep '^[A-Z]' .document) doc/
73
73
 
74
74
  ifneq ($(VERSION),)
75
75
  pkggem := pkg/$(rfpackage)-$(VERSION).gem
@@ -168,7 +168,7 @@ doc_gz:
168
168
  for i in $(docs); do \
169
169
  gzip --rsyncable -9 < $$i > $$i.gz; touch -r $$i $$i.gz; done
170
170
  check-warnings:
171
- @(for i in $$(git ls-files '*.rb'|grep -v '^setup\.rb$$'); \
171
+ @(for i in $$(git ls-files '*.rb'| grep -v '^setup\.rb$$'); \
172
172
  do $(RUBY) -d -W2 -c $$i; done) | grep -v '^Syntax OK$$' || :
173
173
 
174
174
  .PHONY: all .FORCE-GIT-VERSION-FILE doc test $(test_units) manifest
@@ -9,6 +9,9 @@ map "/rss" do
9
9
  [ 200, {}, [ ($1.to_i * 1024).to_s ] ]
10
10
  }
11
11
  end
12
+ map "/pid" do
13
+ run lambda { |env| [ 200, {}, [ "#{Process.pid}\n" ] ] }
14
+ end
12
15
  map "/" do
13
16
  run Rack::File.new(Dir.pwd)
14
17
  end
@@ -0,0 +1,59 @@
1
+ #!/bin/sh
2
+ . ./test-lib.sh
3
+ case $model in
4
+ Coolio|CoolioThreadSpawn|CoolioThreadPool|EventMachine) ;;
5
+ Epoll|XEpoll|XEpollThreadPool|XEpollThreadSpawn) ;;
6
+ *)
7
+ t_info "$0 not supported for $model"
8
+ exit 0
9
+ ;;
10
+ esac
11
+
12
+ t_plan 7 "keepalive clients disconnected on SIGQUIT for $model"
13
+
14
+ t_begin "setup and start" && {
15
+ rainbows_setup $model 50 30
16
+ rainbows -E none -D env.ru -c $unicorn_config
17
+ rainbows_wait_start
18
+ }
19
+
20
+ t_begin "start a keepalive request" && {
21
+ (
22
+ cat < $fifo > $tmp &
23
+ printf 'GET / HTTP/1.1\r\nHost: example.com\r\n\r\n'
24
+ wait
25
+ ) | socat - TCP4:$listen > $fifo &
26
+ }
27
+
28
+ t_begin "wait for response" && {
29
+ while ! tail -1 < $tmp | grep '}$' >/dev/null
30
+ do
31
+ sleep 1
32
+ done
33
+ }
34
+
35
+ t_begin "stop Rainbows! gracefully" && {
36
+ t0=$(date +%s)
37
+ kill -QUIT $rainbows_pid
38
+ }
39
+
40
+ t_begin "keepalive client disconnected quickly" && {
41
+ wait
42
+ diff=$(( $(date +%s) - $t0 ))
43
+ test $diff -le 2 || die "client diff=$diff > 2"
44
+ }
45
+
46
+ t_begin "wait for termination" && {
47
+ while kill -0 $rainbows_pid
48
+ do
49
+ sleep 1
50
+ done
51
+ diff=$(( $(date +%s) - $t0 ))
52
+ test $diff -le 4 || die "server diff=$diff > 4"
53
+ }
54
+
55
+ t_begin "check stderr" && {
56
+ check_stderr
57
+ }
58
+
59
+ t_done
@@ -0,0 +1,120 @@
1
+ #!/bin/sh
2
+ . ./test-lib.sh
3
+ STRACE=$(which strace 2>/dev/null || :)
4
+ if ! test -x "$STRACE"
5
+ then
6
+ t_info "strace not found, skipping $T"
7
+ exit 0
8
+ fi
9
+ if test x"$(uname -s)" != xLinux
10
+ then
11
+ t_info "Linux is the only supported OS for $T"
12
+ exit 0
13
+ fi
14
+
15
+ # these buffer internally in external libraries, so we can't detect when
16
+ # to use TCP_CORK
17
+ skip_models EventMachine NeverBlock
18
+ skip_models Coolio CoolioThreadPool CoolioThreadSpawn
19
+ skip_models Revactor Rev RevThreadPool RevThreadSpawn
20
+
21
+ # not sure why, but we don't have time to care about Ruby 1.8 too much
22
+ case $RUBY_VERSION in
23
+ 1.8.*) skip_models WriterThreadSpawn WriterThreadPool ;;
24
+ esac
25
+
26
+ t_plan 13 "Kgio autopush tests"
27
+
28
+ start_strace () {
29
+ # dbgcat strace_out
30
+ > $strace_out
31
+ sleep 1
32
+ strace -p $worker_pid -e '!futex' -f -o $strace_out &
33
+ strace_pid=$!
34
+ while ! test -s $strace_out; do sleep 1; done
35
+ }
36
+
37
+ check_TCP_CORK () {
38
+ nr=0
39
+ while test 2 -gt $(grep TCP_CORK $strace_out | wc -l)
40
+ do
41
+ nr=$(( $nr + 1 ))
42
+ if test $nr -gt 30
43
+ then
44
+ dbgcat strace_out
45
+ die "waited too long ($nr seconds) for TCP_CORK"
46
+ fi
47
+ sleep 1
48
+ done
49
+
50
+ test 2 -eq $(grep TCP_CORK $strace_out | wc -l)
51
+ fgrep 'SOL_TCP, TCP_CORK, [0], 4) = 0' $strace_out
52
+ fgrep 'SOL_TCP, TCP_CORK, [1], 4) = 0' $strace_out
53
+ }
54
+
55
+ t_begin "setup and start" && {
56
+ rainbows_setup $model 1 1
57
+ rtmpfiles strace_out
58
+ ed -s $unicorn_config <<EOF
59
+ ,s/^listen.*/listen "$listen", :tcp_nodelay => true, :tcp_nopush => true/
60
+ w
61
+ EOF
62
+ rainbows -D large-file-response.ru -c $unicorn_config -E none
63
+ rainbows_wait_start
64
+ }
65
+
66
+ t_begin "read worker pid" && {
67
+ worker_pid=$(curl -sSf http://$listen/pid)
68
+ kill -0 $worker_pid
69
+ }
70
+
71
+ t_begin "start strace on worker" && start_strace
72
+
73
+ t_begin "reading RSS uncorks" && {
74
+ curl -sSf http://$listen/rss >/dev/null
75
+ }
76
+
77
+ t_begin "restart strace on worker" && {
78
+ kill $strace_pid
79
+ wait
80
+ start_strace
81
+ }
82
+
83
+ t_begin "reading static file uncorks" && {
84
+ curl -sSf http://$listen/random_blob >/dev/null
85
+ check_TCP_CORK
86
+ }
87
+
88
+ t_begin "stop strace on worker" && {
89
+ kill $strace_pid
90
+ wait
91
+ }
92
+
93
+ t_begin "enable sendfile" && {
94
+ echo >> $unicorn_config 'require "sendfile"'
95
+ kill -HUP $rainbows_pid
96
+ test xSTART = x"$(cat $fifo)"
97
+ }
98
+
99
+ t_begin "reread worker pid" && {
100
+ worker_pid=$(curl -sSf http://$listen/pid)
101
+ kill -0 $worker_pid
102
+ }
103
+
104
+ t_begin "restart strace on the worker" && start_strace
105
+
106
+ t_begin "HTTP/1.x GET on static file with sendfile uncorks" && {
107
+ curl -sSf http://$listen/random_blob >/dev/null
108
+ check_TCP_CORK
109
+ }
110
+
111
+ t_begin "killing succeeds" && {
112
+ kill $strace_pid
113
+ wait
114
+ # dbgcat strace_out
115
+ kill $rainbows_pid
116
+ }
117
+
118
+ t_begin "check stderr" && check_stderr
119
+
120
+ t_done
@@ -38,10 +38,10 @@ Isolate.now!(opts) do
38
38
  end
39
39
 
40
40
  if RUBY_PLATFORM =~ /linux/
41
- gem 'sleepy_penguin', '2.0.0'
41
+ gem 'sleepy_penguin', '3.0.1'
42
42
 
43
43
  # is 2.6.32 new enough?
44
- gem 'io_splice', '4.1.0' if `uname -r`.strip > '2.6.32'
44
+ gem 'io_splice', '4.1.1' if `uname -r`.strip > '2.6.32'
45
45
  end
46
46
  end
47
47
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rainbows
3
3
  version: !ruby/object:Gem::Version
4
- hash: 11
4
+ hash: 23
5
5
  prerelease:
6
6
  segments:
7
7
  - 3
8
- - 3
8
+ - 4
9
9
  - 0
10
- version: 3.3.0
10
+ version: 3.4.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Rainbows! hackers
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-05-16 00:00:00 Z
18
+ date: 2011-05-21 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: rack
@@ -458,6 +458,8 @@ files:
458
458
  - t/t0040-keepalive_requests-setting.sh
459
459
  - t/t0041-optional-pool-size.sh
460
460
  - t/t0042-client_header_buffer_size.sh
461
+ - t/t0043-quit-keepalive-disconnect.sh
462
+ - t/t0044-autopush.sh
461
463
  - t/t0050-response-body-close-has-env.sh
462
464
  - t/t0100-rack-input-hammer-chunked.sh
463
465
  - t/t0100-rack-input-hammer-content-length.sh