zbatery 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.manifest +4 -0
- data/ChangeLog +32 -1
- data/GIT-VERSION-FILE +1 -1
- data/GIT-VERSION-GEN +1 -1
- data/GNUmakefile +40 -8
- data/NEWS +5 -0
- data/Rakefile +30 -3
- data/lib/zbatery.rb +36 -32
- data/t/.gitignore +3 -1
- data/t/GNUmakefile +37 -23
- data/t/my-tap-lib.sh +3 -2
- data/t/sha1-random-size.ru +19 -0
- data/t/t0005-large-file-response.sh +16 -11
- data/t/t0020-large-sendfile-response.sh +141 -0
- data/t/t0103-rack-input-limit.sh +61 -0
- data/t/test-lib.sh +37 -12
- data/t/test_isolate.rb +43 -0
- data/zbatery.gemspec +4 -3
- metadata +53 -11
data/.manifest
CHANGED
@@ -27,8 +27,12 @@ t/bin/unused_listen
|
|
27
27
|
t/bin/utee
|
28
28
|
t/large-file-response.ru
|
29
29
|
t/my-tap-lib.sh
|
30
|
+
t/sha1-random-size.ru
|
30
31
|
t/sleep.ru
|
31
32
|
t/t0003-reopen-logs.sh
|
32
33
|
t/t0005-large-file-response.sh
|
34
|
+
t/t0020-large-sendfile-response.sh
|
35
|
+
t/t0103-rack-input-limit.sh
|
33
36
|
t/test-lib.sh
|
37
|
+
t/test_isolate.rb
|
34
38
|
zbatery.gemspec
|
data/ChangeLog
CHANGED
@@ -1,5 +1,36 @@
|
|
1
|
-
ChangeLog from git://git.bogomips.org/zbatery.git (v0.1.1..v0.
|
1
|
+
ChangeLog from git://git.bogomips.org/zbatery.git (v0.1.1..v0.3.0)
|
2
2
|
|
3
|
+
commit d4f095ed8ed0da4f190280eb957c14b3f5e9a2e9
|
4
|
+
Author: Eric Wong <normalperson@yhbt.net>
|
5
|
+
Date: Sat Jul 10 09:56:27 2010 +0000
|
6
|
+
|
7
|
+
Zbatery v0.3.0 - for newer Rainbows!
|
8
|
+
|
9
|
+
Rainbows! v0.95.0 is more awesome than v0.94.0, so we've updated
|
10
|
+
ourselves to use it and be more awesome as well!
|
11
|
+
|
12
|
+
commit 00f570d6c3363794ee4489fae17b05555b78b2cf
|
13
|
+
Author: Eric Wong <normalperson@yhbt.net>
|
14
|
+
Date: Sat Jul 10 09:55:20 2010 +0000
|
15
|
+
|
16
|
+
gemspec: small doc updates
|
17
|
+
|
18
|
+
commit 59d3b3f6318a85e4d68592e1f7b992dd54832aa0
|
19
|
+
Author: Eric Wong <normalperson@yhbt.net>
|
20
|
+
Date: Sat Jul 10 09:53:52 2010 +0000
|
21
|
+
|
22
|
+
add additional tests for newish Rainbows! features
|
23
|
+
|
24
|
+
commit bd6b2263869c271113577b88d526c7c2a6f1455d
|
25
|
+
Author: Eric Wong <normalperson@yhbt.net>
|
26
|
+
Date: Sat Jul 10 02:41:46 2010 -0700
|
27
|
+
|
28
|
+
updates for Rainbows! 0.95.0
|
29
|
+
|
30
|
+
Rainbows! 0.95.0 made some incompatible changes, so update
|
31
|
+
everything. Unfortunately we have to avoid subclassing here.
|
32
|
+
Tests use isolate now.
|
33
|
+
|
3
34
|
commit 5764336aa3785af8a08be7ec7b40846ec139eb6c
|
4
35
|
Author: Eric Wong <normalperson@yhbt.net>
|
5
36
|
Date: Mon Apr 19 14:14:46 2010 -0700
|
data/GIT-VERSION-FILE
CHANGED
@@ -1 +1 @@
|
|
1
|
-
GIT_VERSION = 0.
|
1
|
+
GIT_VERSION = 0.3.0
|
data/GIT-VERSION-GEN
CHANGED
data/GNUmakefile
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
# use GNU Make to run tests in parallel, and without depending on RubyGems
|
2
2
|
all::
|
3
|
+
MRI = ruby
|
3
4
|
RUBY = ruby
|
4
5
|
RAKE = rake
|
6
|
+
RSYNC = rsync
|
5
7
|
GIT_URL = git://git.bogomips.org/zbatery.git
|
6
8
|
|
7
9
|
GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE
|
@@ -14,9 +16,11 @@ endif
|
|
14
16
|
ifeq ($(RUBY_VERSION),)
|
15
17
|
RUBY_VERSION := $(shell $(RUBY) -e 'puts RUBY_VERSION')
|
16
18
|
endif
|
19
|
+
RUBY_ENGINE := $(shell $(RUBY) -e 'puts((RUBY_ENGINE rescue "ruby"))')
|
17
20
|
|
18
21
|
base_bins := zbatery
|
19
22
|
bins := $(addprefix bin/, $(base_bins))
|
23
|
+
man1_rdoc := $(addsuffix _1, $(base_bins))
|
20
24
|
man1_bins := $(addsuffix .1, $(base_bins))
|
21
25
|
man1_paths := $(addprefix man/man1/, $(man1_bins))
|
22
26
|
|
@@ -76,26 +80,52 @@ cgit_atom := http://git.bogomips.org/cgit/zbatery.git/atom/?h=master
|
|
76
80
|
atom = <link rel="alternate" title="Atom feed" href="$(1)" \
|
77
81
|
type="application/atom+xml"/>
|
78
82
|
|
79
|
-
# using rdoc 2.
|
83
|
+
# using rdoc 2.5.x+
|
80
84
|
doc: .document NEWS ChangeLog
|
81
|
-
for i in $(
|
82
|
-
|
85
|
+
for i in $(man1_rdoc); do echo > $$i; done
|
86
|
+
find bin lib -type f -name '*.rbc' -exec rm -f '{}' ';'
|
87
|
+
rdoc -t "$(shell sed -ne '1s/^= //p' README)"
|
83
88
|
install -m644 COPYING doc/COPYING
|
84
89
|
install -m644 $(shell grep '^[A-Z]' .document) doc/
|
85
90
|
$(MAKE) -C Documentation install-html install-man
|
86
91
|
install -m644 $(man1_paths) doc/
|
87
92
|
cd doc && for i in $(base_bins); do \
|
93
|
+
$(RM) 1.html $${i}.1.html; \
|
88
94
|
sed -e '/"documentation">/r man1/'$$i'.1.html' \
|
89
|
-
< $${i}_1.html > tmp && mv tmp $${i}_1.html;
|
90
|
-
|
95
|
+
< $${i}_1.html > tmp && mv tmp $${i}_1.html; \
|
96
|
+
ln $${i}_1.html $${i}.1.html; \
|
97
|
+
done
|
98
|
+
$(MRI) -i -p -e \
|
91
99
|
'$$_.gsub!("</title>",%q{\&$(call atom,$(cgit_atom))})' \
|
92
100
|
doc/ChangeLog.html
|
93
|
-
$(
|
101
|
+
$(MRI) -i -p -e \
|
94
102
|
'$$_.gsub!("</title>",%q{\&$(call atom,$(news_atom))})' \
|
95
103
|
doc/NEWS.html doc/README.html
|
96
104
|
$(RAKE) -s news_atom > doc/NEWS.atom.xml
|
97
105
|
cd doc && ln README.html tmp && mv tmp index.html
|
98
|
-
$(RM) $(
|
106
|
+
$(RM) $(man1_rdoc)
|
107
|
+
|
108
|
+
# publishes docs to http://zbatery.bogomip.org/
|
109
|
+
publish_doc:
|
110
|
+
-git set-file-times
|
111
|
+
$(RM) -r doc ChangeLog NEWS
|
112
|
+
$(MAKE) doc LOG_VERSION=$(shell git tag -l | tail -1)
|
113
|
+
awk 'BEGIN{RS="=== ";ORS=""}NR==2{sub(/\n$$/,"");print RS""$$0 }' \
|
114
|
+
< NEWS > doc/LATEST
|
115
|
+
find doc/images doc/js -type f | \
|
116
|
+
TZ=UTC xargs touch -d '1970-01-01 00:00:01' doc/rdoc.css
|
117
|
+
$(MAKE) doc_gz
|
118
|
+
chmod 644 $$(find doc -type f)
|
119
|
+
$(RSYNC) -av doc/ zbatery.bogomip.org:/srv/zbatery/
|
120
|
+
git ls-files | xargs touch
|
121
|
+
|
122
|
+
# Create gzip variants of the same timestamp as the original so nginx
|
123
|
+
# "gzip_static on" can serve the gzipped versions directly.
|
124
|
+
doc_gz: docs = $(shell find doc -type f ! -regex '^.*\.\(gif\|jpg\|png\|gz\)$$')
|
125
|
+
doc_gz:
|
126
|
+
touch doc/NEWS.atom.xml -d "$$(awk 'NR==1{print $$4,$$5,$$6}' NEWS)"
|
127
|
+
for i in $(docs); do \
|
128
|
+
gzip --rsyncable -9 < $$i > $$i.gz; touch -r $$i $$i.gz; done
|
99
129
|
|
100
130
|
ifneq ($(VERSION),)
|
101
131
|
rfproject := rainbows
|
@@ -152,11 +182,13 @@ release: verify package $(release_notes) $(release_changes)
|
|
152
182
|
# make tgz release on RubyForge
|
153
183
|
rubyforge add_release -f -n $(release_notes) -a $(release_changes) \
|
154
184
|
$(rfproject) $(rfpackage) $(VERSION) $(pkgtgz)
|
155
|
-
# push gem to
|
185
|
+
# push gem to RubyGems.org
|
156
186
|
gem push $(pkggem)
|
157
187
|
# in case of gem downloads from RubyForge releases page
|
158
188
|
-rubyforge add_file \
|
159
189
|
$(rfproject) $(rfpackage) $(VERSION) $(pkggem)
|
190
|
+
$(RAKE) raa_update VERSION=$(VERSION)
|
191
|
+
$(RAKE) fm_update VERSION=$(VERSION)
|
160
192
|
else
|
161
193
|
gem install-gem: GIT-VERSION-FILE
|
162
194
|
$(MAKE) $@ VERSION=$(GIT_VERSION)
|
data/NEWS
CHANGED
data/Rakefile
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# -*- encoding: binary -*-
|
2
|
+
autoload :Gem, 'rubygems'
|
2
3
|
|
3
4
|
# most tasks are in the GNUmakefile which offers better parallelism
|
4
5
|
|
@@ -89,8 +90,6 @@ end
|
|
89
90
|
|
90
91
|
desc "print release notes for Rubyforge"
|
91
92
|
task :release_notes do
|
92
|
-
require 'rubygems'
|
93
|
-
|
94
93
|
spec = Gem::Specification.load('zbatery.gemspec')
|
95
94
|
puts spec.description.strip
|
96
95
|
puts ""
|
@@ -121,7 +120,6 @@ end
|
|
121
120
|
|
122
121
|
desc "post to RAA"
|
123
122
|
task :raa_update do
|
124
|
-
require 'rubygems'
|
125
123
|
require 'net/http'
|
126
124
|
require 'net/netrc'
|
127
125
|
rc = Net::Netrc.locate('zbatery-raa') or abort "~/.netrc not found"
|
@@ -156,3 +154,32 @@ task :raa_update do
|
|
156
154
|
p res
|
157
155
|
puts res.body
|
158
156
|
end
|
157
|
+
|
158
|
+
desc "post to FM"
|
159
|
+
task :fm_update do
|
160
|
+
require 'tempfile'
|
161
|
+
require 'net/http'
|
162
|
+
require 'net/netrc'
|
163
|
+
require 'json'
|
164
|
+
version = ENV['VERSION'] or abort "VERSION= needed"
|
165
|
+
uri = URI.parse('http://freshmeat.net/projects/zbatery/releases.json')
|
166
|
+
rc = Net::Netrc.locate('zbatery-fm') or abort "~/.netrc not found"
|
167
|
+
api_token = rc.password
|
168
|
+
changelog = tags.find { |t| t[:tag] == "v#{version}" }[:body]
|
169
|
+
tmp = Tempfile.new('fm-changelog')
|
170
|
+
tmp.syswrite(changelog)
|
171
|
+
system(ENV["VISUAL"], tmp.path) or abort "#{ENV["VISUAL"]} failed: #$?"
|
172
|
+
changelog = File.read(tmp.path).strip
|
173
|
+
|
174
|
+
req = {
|
175
|
+
"auth_code" => api_token,
|
176
|
+
"release" => {
|
177
|
+
"tag_list" => "Stable",
|
178
|
+
"version" => version,
|
179
|
+
"changelog" => changelog,
|
180
|
+
},
|
181
|
+
}.to_json
|
182
|
+
Net::HTTP.start(uri.host, uri.port) do |http|
|
183
|
+
p http.post(uri.path, req, {'Content-Type'=>'application/json'})
|
184
|
+
end
|
185
|
+
end
|
data/lib/zbatery.rb
CHANGED
@@ -1,17 +1,18 @@
|
|
1
1
|
# -*- encoding: binary -*-
|
2
|
+
# :enddoc:
|
2
3
|
require 'rainbows'
|
3
4
|
|
4
5
|
module Zbatery
|
5
6
|
|
6
7
|
# current version of Zbatery
|
7
|
-
VERSION = "0.
|
8
|
+
VERSION = "0.3.0"
|
8
9
|
|
9
10
|
class << self
|
10
11
|
|
11
12
|
# runs the Zbatery HttpServer with +app+ and +options+ and does
|
12
13
|
# not return until the server has exited.
|
13
14
|
def run(app, options = {})
|
14
|
-
HttpServer.new(app, options).start.join
|
15
|
+
Rainbows::HttpServer.new(app, options).start.join
|
15
16
|
end
|
16
17
|
end
|
17
18
|
|
@@ -32,7 +33,37 @@ module Zbatery
|
|
32
33
|
# config files...
|
33
34
|
FORK_HOOK = lambda { |_,_| }
|
34
35
|
|
35
|
-
|
36
|
+
end
|
37
|
+
|
38
|
+
# :stopdoc:
|
39
|
+
# override stuff we don't need or can't use portably
|
40
|
+
module Rainbows
|
41
|
+
|
42
|
+
module Base
|
43
|
+
# master == worker in our case
|
44
|
+
def init_worker_process(worker)
|
45
|
+
after_fork.call(self, worker)
|
46
|
+
worker.user(*user) if user.kind_of?(Array) && ! worker.switched
|
47
|
+
build_app! unless preload_app
|
48
|
+
Rainbows::Response.setup(self.class)
|
49
|
+
Rainbows::MaxBody.setup
|
50
|
+
|
51
|
+
# avoid spurious wakeups and blocking-accept() with 1.8 green threads
|
52
|
+
if RUBY_VERSION.to_f < 1.9
|
53
|
+
require "io/nonblock"
|
54
|
+
HttpServer::LISTENERS.each { |l| l.nonblock = true }
|
55
|
+
end
|
56
|
+
|
57
|
+
logger.info "Zbatery #@use worker_connections=#@worker_connections"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# we can't/don't need to do the fchmod heartbeat Unicorn/Rainbows! does
|
62
|
+
def G.tick
|
63
|
+
alive
|
64
|
+
end
|
65
|
+
|
66
|
+
class HttpServer
|
36
67
|
|
37
68
|
# this class is only used to avoid breaking Unicorn user switching
|
38
69
|
class DeadIO
|
@@ -115,47 +146,20 @@ module Zbatery
|
|
115
146
|
|
116
147
|
def before_fork
|
117
148
|
hook = super
|
118
|
-
hook == FORK_HOOK or
|
149
|
+
hook == Zbatery::FORK_HOOK or
|
119
150
|
logger.warn "calling before_fork without forking"
|
120
151
|
hook
|
121
152
|
end
|
122
153
|
|
123
154
|
def after_fork
|
124
155
|
hook = super
|
125
|
-
hook == FORK_HOOK or
|
156
|
+
hook == Zbatery::FORK_HOOK or
|
126
157
|
logger.warn "calling after_fork without having forked"
|
127
158
|
hook
|
128
159
|
end
|
129
160
|
end
|
130
161
|
end
|
131
162
|
|
132
|
-
# :stopdoc:
|
133
|
-
# override stuff we don't need or can't use portably
|
134
|
-
module Rainbows
|
135
|
-
|
136
|
-
module Base
|
137
|
-
# master == worker in our case
|
138
|
-
def init_worker_process(worker)
|
139
|
-
after_fork.call(self, worker)
|
140
|
-
worker.user(*user) if user.kind_of?(Array) && ! worker.switched
|
141
|
-
build_app! unless preload_app
|
142
|
-
|
143
|
-
# avoid spurious wakeups and blocking-accept() with 1.8 green threads
|
144
|
-
if RUBY_VERSION.to_f < 1.9
|
145
|
-
require "io/nonblock"
|
146
|
-
HttpServer::LISTENERS.each { |l| l.nonblock = true }
|
147
|
-
end
|
148
|
-
|
149
|
-
logger.info "Zbatery #@use worker_connections=#@worker_connections"
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
|
-
# we can't/don't need to do the fchmod heartbeat Unicorn/Rainbows! does
|
154
|
-
def G.tick
|
155
|
-
alive
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
163
|
module Unicorn
|
160
164
|
|
161
165
|
class Configurator
|
data/t/.gitignore
CHANGED
data/t/GNUmakefile
CHANGED
@@ -4,6 +4,7 @@ all::
|
|
4
4
|
|
5
5
|
pid := $(shell echo $$PPID)
|
6
6
|
|
7
|
+
MRI = ruby
|
7
8
|
RUBY = ruby
|
8
9
|
zbatery_lib := $(shell cd ../lib && pwd)
|
9
10
|
-include ../local.mk
|
@@ -15,13 +16,11 @@ ifeq ($(RUBY_VERSION),)
|
|
15
16
|
$(error unable to detect RUBY_VERSION)
|
16
17
|
endif
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
else
|
21
|
-
RUBYLIB := $(zbatery_lib):$(RUBYLIB)
|
22
|
-
endif
|
23
|
-
export RUBYLIB RUBY_VERSION
|
19
|
+
RUBY_ENGINE := $(shell $(RUBY) -e 'puts((RUBY_ENGINE rescue "ruby"))')
|
20
|
+
export RUBY_VERSION RUBY_ENGINE
|
24
21
|
|
22
|
+
models += WriterThreadPool
|
23
|
+
models += WriterThreadSpawn
|
25
24
|
models += ThreadPool
|
26
25
|
models += ThreadSpawn
|
27
26
|
models += Rev
|
@@ -30,13 +29,19 @@ models += NeverBlock
|
|
30
29
|
models += RevThreadSpawn
|
31
30
|
models += RevThreadPool
|
32
31
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
32
|
+
ifeq ($(RUBY_ENGINE),ruby)
|
33
|
+
rp := )
|
34
|
+
ONENINE := $(shell case $(RUBY_VERSION) in 1.9.*$(rp) echo true;;esac)
|
35
|
+
ifeq ($(ONENINE),true)
|
36
|
+
models += Revactor
|
37
|
+
models += FiberSpawn
|
38
|
+
models += RevFiberSpawn
|
39
|
+
models += FiberPool
|
40
|
+
endif
|
41
|
+
endif
|
42
|
+
|
43
|
+
ifeq ($(RUBY_ENGINE),rbx)
|
44
|
+
models += ActorSpawn
|
40
45
|
endif
|
41
46
|
all_models := $(models) Base
|
42
47
|
|
@@ -63,7 +68,7 @@ $(all_models):
|
|
63
68
|
all:: $(T)
|
64
69
|
|
65
70
|
# can't rely on "set -o pipefail" since we don't require bash or ksh93 :<
|
66
|
-
t_pfx = trash/$@-$(RUBY_VERSION)
|
71
|
+
t_pfx = trash/$@-$(RUBY_ENGINE)-$(RUBY_VERSION)
|
67
72
|
TEST_OPTS =
|
68
73
|
# TRACER = strace -f -o $(t_pfx).strace -s 100000
|
69
74
|
# TRACER = /usr/bin/time -o $(t_pfx).time
|
@@ -76,11 +81,13 @@ ifdef V
|
|
76
81
|
endif
|
77
82
|
endif
|
78
83
|
|
79
|
-
|
80
|
-
|
84
|
+
bindir := $(CURDIR)/bin-$(RUBY_ENGINE)-$(RUBY_VERSION)
|
85
|
+
bin_zbatery := $(bindir)/zbatery
|
86
|
+
$(bin_zbatery): ruby_bin = $(shell which $(RUBY))
|
87
|
+
$(bin_zbatery): ../bin/zbatery
|
81
88
|
mkdir -p $(@D)
|
82
89
|
install -m 755 $^ $@.$(pid)
|
83
|
-
$(
|
90
|
+
$(MRI) -i -p -e '$$_.gsub!(%r{^#!.*$$},"#!$(ruby_bin)")' $@.$(pid)
|
84
91
|
mv $@.$(pid) $@
|
85
92
|
|
86
93
|
random_blob:
|
@@ -97,21 +104,28 @@ $(deps):
|
|
97
104
|
@test -s $@.$(pid) || \
|
98
105
|
{ echo >&2 "E '$(dep_bin)' not found in PATH=$(PATH)"; exit 1; }
|
99
106
|
@mv $@.$(pid) $@
|
100
|
-
|
107
|
+
|
108
|
+
libs := tmp/isolate/$(RUBY_ENGINE)-$(RUBY_VERSION)/.libs
|
109
|
+
$(libs): test_isolate.rb
|
110
|
+
mkdir -p $(@D)
|
111
|
+
$(RUBY) $< > $@+
|
112
|
+
mv $@+ $@
|
113
|
+
t_deps := $(libs) $(deps) $(bin_zbatery) trash/.gitignore
|
114
|
+
$(T): $(t_deps)
|
101
115
|
|
102
116
|
$(MODEL_T): export model = $(firstword $(subst ., ,$@))
|
103
117
|
$(MODEL_T): script = $(subst $(model).,,$@)
|
104
|
-
$(MODEL_T): trash/.gitignore
|
105
118
|
$(MODEL_T): export RUBY := $(RUBY)
|
106
|
-
$(MODEL_T): export PATH := $(
|
107
|
-
$(MODEL_T):
|
108
|
-
|
119
|
+
$(MODEL_T): export PATH := $(bindir):$(PATH)
|
120
|
+
$(MODEL_T): $(t_deps)
|
121
|
+
RUBYLIB=$(zbatery_lib):$$(cat $(libs)) \
|
122
|
+
$(TRACER) $(SHELL) $(SH_TEST_OPTS) $(script) $(TEST_OPTS)
|
109
123
|
|
110
124
|
trash/.gitignore:
|
111
125
|
mkdir -p $(@D)
|
112
126
|
echo '*' > $@
|
113
127
|
|
114
128
|
clean:
|
115
|
-
$(RM) -r trash/*.log trash/*.code
|
129
|
+
$(RM) -r trash/*.log trash/*.code $(bindir)
|
116
130
|
|
117
131
|
.PHONY: $(T) clean
|
data/t/my-tap-lib.sh
CHANGED
@@ -188,9 +188,10 @@ then
|
|
188
188
|
|
189
189
|
(
|
190
190
|
# use a subshell so seds are not waitable
|
191
|
-
$SED -e 's/^/#: /' $t_stdout &
|
192
|
-
$SED -e 's/^/#! /' $t_stderr &
|
191
|
+
$SED -e 's/^/#: /' < $t_stdout &
|
192
|
+
$SED -e 's/^/#! /' < $t_stderr &
|
193
193
|
) &
|
194
|
+
wait
|
194
195
|
exec > $t_stdout 2> $t_stderr
|
195
196
|
else
|
196
197
|
exec > /dev/null 2> /dev/null
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# SHA1 checksum generator
|
2
|
+
require 'digest/sha1'
|
3
|
+
use Rack::ContentLength
|
4
|
+
cap = 16384
|
5
|
+
app = lambda do |env|
|
6
|
+
/\A100-continue\z/i =~ env['HTTP_EXPECT'] and
|
7
|
+
return [ 100, {}, [] ]
|
8
|
+
digest = Digest::SHA1.new
|
9
|
+
input = env['rack.input']
|
10
|
+
if buf = input.read(rand(cap))
|
11
|
+
begin
|
12
|
+
raise "#{buf.size} > #{cap}" if buf.size > cap
|
13
|
+
digest.update(buf)
|
14
|
+
end while input.read(rand(cap), buf)
|
15
|
+
end
|
16
|
+
|
17
|
+
[ 200, {'Content-Type' => 'text/plain'}, [ digest.hexdigest << "\n" ] ]
|
18
|
+
end
|
19
|
+
run app
|
@@ -12,13 +12,14 @@ t_plan 10 "large file response slurp avoidance for $model"
|
|
12
12
|
|
13
13
|
t_begin "setup and startup" && {
|
14
14
|
rtmpfiles curl_out
|
15
|
-
zbatery_setup $model
|
15
|
+
zbatery_setup $model 1
|
16
16
|
# can't load Rack::Lint here since it'll cause Rev to slurp
|
17
17
|
zbatery -E none -D large-file-response.ru -c $unicorn_config
|
18
18
|
zbatery_wait_start
|
19
19
|
}
|
20
20
|
|
21
|
-
t_begin "read random blob size" && {
|
21
|
+
t_begin "read random blob sha1 and size" && {
|
22
|
+
random_blob_sha1=$(rsha1 < random_blob)
|
22
23
|
random_blob_size=$(wc -c < random_blob)
|
23
24
|
}
|
24
25
|
|
@@ -32,29 +33,29 @@ t_begin "read current RSS" && {
|
|
32
33
|
t_begin "send a series HTTP/1.1 requests sequentially" && {
|
33
34
|
for i in a b c
|
34
35
|
do
|
35
|
-
|
36
|
-
echo ok >$ok) |
|
37
|
-
test $
|
36
|
+
sha1=$( (curl -sSfv http://$listen/random_blob &&
|
37
|
+
echo ok >$ok) | rsha1)
|
38
|
+
test $sha1 = $random_blob_sha1
|
38
39
|
test xok = x$(cat $ok)
|
39
40
|
done
|
40
41
|
}
|
41
42
|
|
42
43
|
# this was a problem during development
|
43
44
|
t_begin "HTTP/1.0 test" && {
|
44
|
-
|
45
|
-
echo ok >$ok) |
|
46
|
-
test $
|
45
|
+
sha1=$( (curl -0 -sSfv http://$listen/random_blob &&
|
46
|
+
echo ok >$ok) | rsha1)
|
47
|
+
test $sha1 = $random_blob_sha1
|
47
48
|
test xok = x$(cat $ok)
|
48
49
|
}
|
49
50
|
|
50
51
|
t_begin "HTTP/0.9 test" && {
|
51
52
|
(
|
52
53
|
printf 'GET /random_blob\r\n'
|
53
|
-
|
54
|
+
rsha1 < $fifo > $tmp &
|
54
55
|
wait
|
55
56
|
echo ok > $ok
|
56
57
|
) | socat - TCP:$listen > $fifo
|
57
|
-
|
58
|
+
test $(cat $tmp) = $random_blob_sha1
|
58
59
|
test xok = x$(cat $ok)
|
59
60
|
}
|
60
61
|
|
@@ -72,8 +73,12 @@ t_begin "shutdown server" && {
|
|
72
73
|
|
73
74
|
t_begin "compare RSS before and after" && {
|
74
75
|
diff=$(( $rss_after - $rss_before ))
|
76
|
+
|
77
|
+
# default GC malloc limit in MRI:
|
78
|
+
fudge=$(( 8 * 1024 * 1024 ))
|
79
|
+
|
75
80
|
t_info "test diff=$diff < orig=$random_blob_size"
|
76
|
-
test $diff -le $random_blob_size
|
81
|
+
test $diff -le $(( $random_blob_size + $fudge ))
|
77
82
|
}
|
78
83
|
|
79
84
|
dbgcat r_err
|
@@ -0,0 +1,141 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
. ./test-lib.sh
|
3
|
+
test -r random_blob || die "random_blob required, run with 'make $0'"
|
4
|
+
case $RUBY_ENGINE in
|
5
|
+
ruby) ;;
|
6
|
+
*)
|
7
|
+
t_info "skipping $T since it can't load the sendfile gem, yet"
|
8
|
+
exit 0
|
9
|
+
;;
|
10
|
+
esac
|
11
|
+
|
12
|
+
t_plan 12 "large sendfile response for $model"
|
13
|
+
|
14
|
+
t_begin "setup and startup" && {
|
15
|
+
rtmpfiles curl_out a b c slow_a slow_b
|
16
|
+
zbatery_setup $model
|
17
|
+
echo 'require "sendfile"' >> $unicorn_config
|
18
|
+
echo 'def (::IO).copy_stream(*x); abort "NO"; end' >> $unicorn_config
|
19
|
+
|
20
|
+
# can't load Rack::Lint here since it clobbers body#to_path
|
21
|
+
zbatery -E none -D large-file-response.ru -c $unicorn_config
|
22
|
+
zbatery_wait_start
|
23
|
+
}
|
24
|
+
|
25
|
+
t_begin "read random blob sha1" && {
|
26
|
+
random_blob_sha1=$(rsha1 < random_blob)
|
27
|
+
three_sha1=$(cat random_blob random_blob random_blob | rsha1)
|
28
|
+
}
|
29
|
+
|
30
|
+
t_begin "send keepalive HTTP/1.1 requests in parallel" && {
|
31
|
+
for i in $a $b $c $slow_a $slow_b
|
32
|
+
do
|
33
|
+
curl -sSf http://$listen/random_blob \
|
34
|
+
http://$listen/random_blob \
|
35
|
+
http://$listen/random_blob | rsha1 > $i &
|
36
|
+
done
|
37
|
+
wait
|
38
|
+
for i in $a $b $c $slow_a $slow_b
|
39
|
+
do
|
40
|
+
test x$(cat $i) = x$three_sha1
|
41
|
+
done
|
42
|
+
}
|
43
|
+
|
44
|
+
t_begin "send a batch of abortive HTTP/1.1 requests in parallel" && {
|
45
|
+
for i in $a $b $c $slow_a $slow_b
|
46
|
+
do
|
47
|
+
rm -f $i
|
48
|
+
(
|
49
|
+
curl -sSf --max-time 5 --limit-rate 1K \
|
50
|
+
http://$listen/random_blob >/dev/null || echo ok > $i
|
51
|
+
) &
|
52
|
+
done
|
53
|
+
wait
|
54
|
+
}
|
55
|
+
|
56
|
+
t_begin "all requests timed out" && {
|
57
|
+
for i in $a $b $c $slow_a $slow_b
|
58
|
+
do
|
59
|
+
test x$(cat $i) = xok
|
60
|
+
done
|
61
|
+
}
|
62
|
+
|
63
|
+
s='$NF ~ /worker_connections=[0-9]+/{gsub(/[^0-9]/,"",$3); print $3; exit}'
|
64
|
+
t_begin "check proc to ensure file is closed properly (Linux only)" && {
|
65
|
+
worker_pid=$(awk "$s" < $r_err)
|
66
|
+
test -n "$worker_pid"
|
67
|
+
if test -d /proc/$worker_pid/fd
|
68
|
+
then
|
69
|
+
if ls -l /proc/$worker_pid/fd | grep random_blob
|
70
|
+
then
|
71
|
+
t_info "random_blob file is open ($model)"
|
72
|
+
fi
|
73
|
+
else
|
74
|
+
t_info "/proc/$worker_pid/fd not found"
|
75
|
+
fi
|
76
|
+
}
|
77
|
+
|
78
|
+
t_begin "send a bunch of HTTP/1.1 requests in parallel" && {
|
79
|
+
(
|
80
|
+
curl -sSf --limit-rate 1M http://$listen/random_blob | \
|
81
|
+
rsha1 > $slow_a
|
82
|
+
) &
|
83
|
+
(
|
84
|
+
curl -sSf --limit-rate 750K http://$listen/random_blob | \
|
85
|
+
rsha1 > $slow_b
|
86
|
+
) &
|
87
|
+
for i in $a $b $c
|
88
|
+
do
|
89
|
+
(
|
90
|
+
curl -sSf http://$listen/random_blob | rsha1 > $i
|
91
|
+
) &
|
92
|
+
done
|
93
|
+
wait
|
94
|
+
for i in $a $b $c $slow_a $slow_b
|
95
|
+
do
|
96
|
+
test x$(cat $i) = x$random_blob_sha1
|
97
|
+
done
|
98
|
+
}
|
99
|
+
|
100
|
+
# this was a problem during development
|
101
|
+
t_begin "HTTP/1.0 test" && {
|
102
|
+
sha1=$( (curl -0 -sSf http://$listen/random_blob &&
|
103
|
+
echo ok >$ok) | rsha1)
|
104
|
+
test $sha1 = $random_blob_sha1
|
105
|
+
test xok = x$(cat $ok)
|
106
|
+
}
|
107
|
+
|
108
|
+
t_begin "HTTP/0.9 test" && {
|
109
|
+
(
|
110
|
+
printf 'GET /random_blob\r\n'
|
111
|
+
rsha1 < $fifo > $tmp &
|
112
|
+
wait
|
113
|
+
echo ok > $ok
|
114
|
+
) | socat - TCP:$listen > $fifo
|
115
|
+
test $(cat $tmp) = $random_blob_sha1
|
116
|
+
test xok = x$(cat $ok)
|
117
|
+
}
|
118
|
+
|
119
|
+
t_begin "check proc to ensure file is closed properly (Linux only)" && {
|
120
|
+
worker_pid=$(awk "$s" < $r_err)
|
121
|
+
test -n "$worker_pid"
|
122
|
+
if test -d /proc/$worker_pid/fd
|
123
|
+
then
|
124
|
+
if ls -l /proc/$worker_pid/fd | grep random_blob
|
125
|
+
then
|
126
|
+
t_info "random_blob file is open ($model)"
|
127
|
+
fi
|
128
|
+
else
|
129
|
+
t_info "/proc/$worker_pid/fd not found"
|
130
|
+
fi
|
131
|
+
}
|
132
|
+
|
133
|
+
t_begin "shutdown server" && {
|
134
|
+
kill -QUIT $zbatery_pid
|
135
|
+
}
|
136
|
+
|
137
|
+
dbgcat r_err
|
138
|
+
|
139
|
+
t_begin "check stderr" && check_stderr
|
140
|
+
|
141
|
+
t_done
|
@@ -0,0 +1,61 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
. ./test-lib.sh
|
3
|
+
test -r random_blob || die "random_blob required, run with 'make $0'"
|
4
|
+
req_curl_chunked_upload_err_check
|
5
|
+
|
6
|
+
t_plan 6 "rack.input client_max_body_size default"
|
7
|
+
|
8
|
+
t_begin "setup and startup" && {
|
9
|
+
rtmpfiles curl_out curl_err cmbs_config
|
10
|
+
zbatery_setup $model
|
11
|
+
grep -v client_max_body_size < $unicorn_config > $cmbs_config
|
12
|
+
zbatery -D sha1-random-size.ru -c $cmbs_config
|
13
|
+
zbatery_wait_start
|
14
|
+
}
|
15
|
+
|
16
|
+
t_begin "regular request" && {
|
17
|
+
rm -f $ok
|
18
|
+
curl -vsSf -T random_blob -H Expect: \
|
19
|
+
http://$listen/ > $curl_out 2> $curl_err || > $ok
|
20
|
+
dbgcat curl_err
|
21
|
+
dbgcat curl_out
|
22
|
+
test -e $ok
|
23
|
+
}
|
24
|
+
|
25
|
+
t_begin "chunked request" && {
|
26
|
+
rm -f $ok
|
27
|
+
curl -vsSf -T- < random_blob -H Expect: \
|
28
|
+
http://$listen/ > $curl_out 2> $curl_err || > $ok
|
29
|
+
dbgcat curl_err
|
30
|
+
dbgcat curl_out
|
31
|
+
test -e $ok
|
32
|
+
}
|
33
|
+
|
34
|
+
t_begin "default size sha1 chunked" && {
|
35
|
+
blob_sha1=3b71f43ff30f4b15b5cd85dd9e95ebc7e84eb5a3
|
36
|
+
rm -f $ok
|
37
|
+
> $r_err
|
38
|
+
dd if=/dev/zero bs=1048576 count=1 | \
|
39
|
+
curl -vsSf -T- -H Expect: \
|
40
|
+
http://$listen/ > $curl_out 2> $curl_err
|
41
|
+
test "$(cat $curl_out)" = $blob_sha1
|
42
|
+
dbgcat curl_err
|
43
|
+
dbgcat curl_out
|
44
|
+
}
|
45
|
+
|
46
|
+
t_begin "default size sha1 content-length" && {
|
47
|
+
blob_sha1=3b71f43ff30f4b15b5cd85dd9e95ebc7e84eb5a3
|
48
|
+
rm -f $ok
|
49
|
+
dd if=/dev/zero bs=1048576 count=1 of=$tmp
|
50
|
+
curl -vsSf -T $tmp -H Expect: \
|
51
|
+
http://$listen/ > $curl_out 2> $curl_err
|
52
|
+
test "$(cat $curl_out)" = $blob_sha1
|
53
|
+
dbgcat curl_err
|
54
|
+
dbgcat curl_out
|
55
|
+
}
|
56
|
+
|
57
|
+
t_begin "shutdown" && {
|
58
|
+
kill $zbatery_pid
|
59
|
+
}
|
60
|
+
|
61
|
+
t_done
|
data/t/test-lib.sh
CHANGED
@@ -3,6 +3,12 @@
|
|
3
3
|
. ./my-tap-lib.sh
|
4
4
|
|
5
5
|
set +u
|
6
|
+
|
7
|
+
# sometimes we rely on http_proxy to avoid wasting bandwidth with Isolate
|
8
|
+
# and multiple Ruby versions
|
9
|
+
NO_PROXY=${UNICORN_TEST_ADDR-127.0.0.1}
|
10
|
+
export NO_PROXY
|
11
|
+
|
6
12
|
if test -z "$model"
|
7
13
|
then
|
8
14
|
# defaulting to Base would unfortunately fail some concurrency tests
|
@@ -13,7 +19,7 @@ fi
|
|
13
19
|
set -e
|
14
20
|
RUBY="${RUBY-ruby}"
|
15
21
|
RUBY_VERSION=${RUBY_VERSION-$($RUBY -e 'puts RUBY_VERSION')}
|
16
|
-
t_pfx=$PWD/trash/$model.$T-$RUBY_VERSION
|
22
|
+
t_pfx=$PWD/trash/$model.$T-$RUBY_ENGINE-$RUBY_VERSION
|
17
23
|
set -u
|
18
24
|
|
19
25
|
PATH=$PWD/bin:$PATH
|
@@ -21,16 +27,6 @@ export PATH
|
|
21
27
|
|
22
28
|
test -x $PWD/bin/unused_listen || die "must be run in 't' directory"
|
23
29
|
|
24
|
-
wait_for_pid () {
|
25
|
-
path="$1"
|
26
|
-
nr=30
|
27
|
-
while ! test -s "$path" && test $nr -gt 0
|
28
|
-
do
|
29
|
-
nr=$(($nr - 1))
|
30
|
-
sleep 1
|
31
|
-
done
|
32
|
-
}
|
33
|
-
|
34
30
|
# requires $1 and prints out the value of $2
|
35
31
|
require_check () {
|
36
32
|
lib=$1
|
@@ -42,6 +38,19 @@ require_check () {
|
|
42
38
|
fi
|
43
39
|
}
|
44
40
|
|
41
|
+
skip_models () {
|
42
|
+
for i in "$@"
|
43
|
+
do
|
44
|
+
if test x"$model" != x"$i"
|
45
|
+
then
|
46
|
+
continue
|
47
|
+
fi
|
48
|
+
t_info "skipping $T since it is not compatible with $model"
|
49
|
+
exit 0
|
50
|
+
done
|
51
|
+
}
|
52
|
+
|
53
|
+
|
45
54
|
# given a list of variable names, create temporary files and assign
|
46
55
|
# the pathnames to those variables
|
47
56
|
rtmpfiles () {
|
@@ -113,6 +122,7 @@ EOF
|
|
113
122
|
# boxes and sometimes sleep 1s in tests
|
114
123
|
kato=5
|
115
124
|
echo 'Rainbows! do'
|
125
|
+
echo " client_max_body_size nil"
|
116
126
|
if test $# -ge 1
|
117
127
|
then
|
118
128
|
echo " use :$1"
|
@@ -145,7 +155,22 @@ rsha1 () {
|
|
145
155
|
|
146
156
|
# last resort, see comments in sha1sum.rb for reasoning
|
147
157
|
test -n "$_cmd" || _cmd=sha1sum.rb
|
148
|
-
expr "$($_cmd
|
158
|
+
expr "$($_cmd)" : '\([a-f0-9]\{40\}\)'
|
159
|
+
}
|
160
|
+
|
161
|
+
req_curl_chunked_upload_err_check () {
|
162
|
+
set +e
|
163
|
+
curl --version 2>/dev/null | awk '$1 == "curl" {
|
164
|
+
split($2, v, /\./)
|
165
|
+
if ((v[1] < 7) || (v[1] == 7 && v[2] < 18))
|
166
|
+
code = 1
|
167
|
+
}
|
168
|
+
END { exit(code) }'
|
169
|
+
if test $? -ne 0
|
170
|
+
then
|
171
|
+
t_info "curl >= 7.18.0 required for $T"
|
172
|
+
exit 0
|
173
|
+
fi
|
149
174
|
}
|
150
175
|
|
151
176
|
case $model in
|
data/t/test_isolate.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'isolate'
|
3
|
+
engine = defined?(RUBY_ENGINE) ? RUBY_ENGINE : 'ruby'
|
4
|
+
|
5
|
+
path = "tmp/isolate/#{engine}-#{RUBY_VERSION}"
|
6
|
+
opts = {
|
7
|
+
:system => false,
|
8
|
+
# we want "ruby-1.8.7" and not "ruby-1.8", so disable multiruby
|
9
|
+
:multiruby => false,
|
10
|
+
:path => path,
|
11
|
+
}
|
12
|
+
|
13
|
+
old_out = $stdout.dup
|
14
|
+
$stdout.reopen($stderr)
|
15
|
+
|
16
|
+
Isolate.now!(opts) do
|
17
|
+
gem 'rack', '1.1.0'
|
18
|
+
gem 'unicorn', '1.1.0'
|
19
|
+
gem 'rainbows', '0.95.0'
|
20
|
+
|
21
|
+
if engine == "ruby"
|
22
|
+
gem 'sendfile', '1.0.0' # next Rubinius should support this
|
23
|
+
|
24
|
+
gem 'iobuffer', '0.1.3'
|
25
|
+
gem 'rev', '0.3.2'
|
26
|
+
|
27
|
+
gem 'eventmachine', '0.12.10'
|
28
|
+
gem 'sinatra', '1.0.0'
|
29
|
+
gem 'async_sinatra', '0.2.1'
|
30
|
+
|
31
|
+
gem 'neverblock', '0.1.6.2'
|
32
|
+
gem 'cramp', '0.11'
|
33
|
+
end
|
34
|
+
|
35
|
+
if defined?(::Fiber) && engine == "ruby"
|
36
|
+
gem 'case', '0.5'
|
37
|
+
gem 'revactor', '0.1.5'
|
38
|
+
gem 'rack-fiber_pool', '0.9.0'
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
$stdout.reopen(old_out)
|
43
|
+
puts Dir["#{path}/gems/*-*/lib"].map { |x| File.expand_path(x) }.join(':')
|
data/zbatery.gemspec
CHANGED
@@ -34,13 +34,13 @@ Gem::Specification.new do |s|
|
|
34
34
|
s.files = manifest
|
35
35
|
s.homepage = %q{http://zbatery.bogomip.org/}
|
36
36
|
s.summary = %q{Rack HTTP server without a fork stuck in it}
|
37
|
-
s.rdoc_options = [ "-
|
37
|
+
s.rdoc_options = [ "-t", "Zbatery - #{s.summary}" ]
|
38
38
|
s.require_paths = %w(lib)
|
39
39
|
s.rubyforge_project = %q{rainbows}
|
40
40
|
|
41
41
|
s.test_files = test_files
|
42
42
|
|
43
|
-
# rainbows has a boatload of dependencies
|
43
|
+
# rainbows has a boatload of optional dependencies
|
44
44
|
# required:
|
45
45
|
# unicorn + rack
|
46
46
|
# optional:
|
@@ -54,7 +54,8 @@ Gem::Specification.new do |s|
|
|
54
54
|
# Unicorn were vulnerable to a remote DoS when exposed directly to
|
55
55
|
# untrusted clients (a configuration only supported by Zbatery and Rainbows!,
|
56
56
|
# Unicorn has never and will never be supported without trusted LAN clients.
|
57
|
-
s.add_dependency(%q<rainbows>, [">= 0.
|
57
|
+
s.add_dependency(%q<rainbows>, [">= 0.95.0", "<= 1.0.0"])
|
58
|
+
s.add_development_dependency(%q<isolate>, "~> 2.1.0")
|
58
59
|
|
59
60
|
# s.licenses = %w(GPLv2 Ruby) # accessor not compatible with older RubyGems
|
60
61
|
end
|
metadata
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zbatery
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 19
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 3
|
9
|
+
- 0
|
10
|
+
version: 0.3.0
|
5
11
|
platform: ruby
|
6
12
|
authors:
|
7
13
|
- Zbatery hackers
|
@@ -9,22 +15,49 @@ autorequire:
|
|
9
15
|
bindir: bin
|
10
16
|
cert_chain: []
|
11
17
|
|
12
|
-
date: 2010-
|
18
|
+
date: 2010-07-10 00:00:00 +00:00
|
13
19
|
default_executable:
|
14
20
|
dependencies:
|
15
21
|
- !ruby/object:Gem::Dependency
|
16
22
|
name: rainbows
|
17
|
-
|
18
|
-
|
19
|
-
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
20
26
|
requirements:
|
21
27
|
- - ">="
|
22
28
|
- !ruby/object:Gem::Version
|
23
|
-
|
29
|
+
hash: 355
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
- 95
|
33
|
+
- 0
|
34
|
+
version: 0.95.0
|
24
35
|
- - <=
|
25
36
|
- !ruby/object:Gem::Version
|
37
|
+
hash: 23
|
38
|
+
segments:
|
39
|
+
- 1
|
40
|
+
- 0
|
41
|
+
- 0
|
26
42
|
version: 1.0.0
|
27
|
-
|
43
|
+
type: :runtime
|
44
|
+
version_requirements: *id001
|
45
|
+
- !ruby/object:Gem::Dependency
|
46
|
+
name: isolate
|
47
|
+
prerelease: false
|
48
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
hash: 11
|
54
|
+
segments:
|
55
|
+
- 2
|
56
|
+
- 1
|
57
|
+
- 0
|
58
|
+
version: 2.1.0
|
59
|
+
type: :development
|
60
|
+
version_requirements: *id002
|
28
61
|
description: |-
|
29
62
|
Zbatery is an HTTP server for Rack applications on systems that either
|
30
63
|
do not support fork(), or have no memory (nor need) to run the
|
@@ -75,10 +108,14 @@ files:
|
|
75
108
|
- t/bin/utee
|
76
109
|
- t/large-file-response.ru
|
77
110
|
- t/my-tap-lib.sh
|
111
|
+
- t/sha1-random-size.ru
|
78
112
|
- t/sleep.ru
|
79
113
|
- t/t0003-reopen-logs.sh
|
80
114
|
- t/t0005-large-file-response.sh
|
115
|
+
- t/t0020-large-sendfile-response.sh
|
116
|
+
- t/t0103-rack-input-limit.sh
|
81
117
|
- t/test-lib.sh
|
118
|
+
- t/test_isolate.rb
|
82
119
|
- zbatery.gemspec
|
83
120
|
has_rdoc: true
|
84
121
|
homepage: http://zbatery.bogomip.org/
|
@@ -86,27 +123,32 @@ licenses: []
|
|
86
123
|
|
87
124
|
post_install_message:
|
88
125
|
rdoc_options:
|
89
|
-
- -Na
|
90
126
|
- -t
|
91
127
|
- Zbatery - Rack HTTP server without a fork stuck in it
|
92
128
|
require_paths:
|
93
129
|
- lib
|
94
130
|
required_ruby_version: !ruby/object:Gem::Requirement
|
131
|
+
none: false
|
95
132
|
requirements:
|
96
133
|
- - ">="
|
97
134
|
- !ruby/object:Gem::Version
|
135
|
+
hash: 3
|
136
|
+
segments:
|
137
|
+
- 0
|
98
138
|
version: "0"
|
99
|
-
version:
|
100
139
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
140
|
+
none: false
|
101
141
|
requirements:
|
102
142
|
- - ">="
|
103
143
|
- !ruby/object:Gem::Version
|
144
|
+
hash: 3
|
145
|
+
segments:
|
146
|
+
- 0
|
104
147
|
version: "0"
|
105
|
-
version:
|
106
148
|
requirements: []
|
107
149
|
|
108
150
|
rubyforge_project: rainbows
|
109
|
-
rubygems_version: 1.3.
|
151
|
+
rubygems_version: 1.3.7
|
110
152
|
signing_key:
|
111
153
|
specification_version: 3
|
112
154
|
summary: Rack HTTP server without a fork stuck in it
|