unicorn 1.1.7 → 2.0.0pre1
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/GIT-VERSION-GEN +1 -1
- data/GNUmakefile +14 -5
- data/Rakefile +3 -28
- data/TODO +7 -0
- data/bin/unicorn +9 -13
- data/bin/unicorn_rails +12 -14
- data/examples/big_app_gc.rb +33 -2
- data/ext/unicorn_http/global_variables.h +3 -1
- data/ext/unicorn_http/unicorn_http.rl +15 -6
- data/lib/unicorn.rb +67 -820
- data/lib/unicorn/app/exec_cgi.rb +3 -4
- data/lib/unicorn/configurator.rb +20 -25
- data/lib/unicorn/const.rb +26 -25
- data/lib/unicorn/http_request.rb +64 -57
- data/lib/unicorn/http_response.rb +16 -35
- data/lib/unicorn/http_server.rb +700 -0
- data/lib/unicorn/launcher.rb +4 -3
- data/lib/unicorn/oob_gc.rb +50 -61
- data/lib/unicorn/socket_helper.rb +4 -4
- data/lib/unicorn/tee_input.rb +18 -26
- data/lib/unicorn/tmpio.rb +29 -0
- data/lib/unicorn/util.rb +51 -85
- data/lib/unicorn/worker.rb +40 -0
- data/local.mk.sample +0 -9
- data/script/isolate_for_tests +43 -0
- data/t/GNUmakefile +8 -1
- data/t/t0003-working_directory.sh +0 -5
- data/t/t0010-reap-logging.sh +55 -0
- data/t/t0303-rails3-alt-working_directory_config.ru.sh +0 -5
- data/t/test-rails3.sh +1 -1
- data/test/exec/test_exec.rb +1 -1
- data/test/unit/test_http_parser_ng.rb +11 -0
- data/test/unit/test_request.rb +12 -0
- data/test/unit/test_response.rb +23 -21
- data/test/unit/test_signals.rb +1 -1
- data/test/unit/test_tee_input.rb +21 -19
- data/unicorn.gemspec +3 -2
- metadata +47 -25
- data/t/oob_gc.ru +0 -21
- data/t/oob_gc_path.ru +0 -21
- data/t/t0012-reload-empty-config.sh +0 -82
- data/t/t0018-write-on-close.sh +0 -23
- data/t/t9001-oob_gc.sh +0 -47
- data/t/t9002-oob_gc-path.sh +0 -75
- data/t/write-on-close.ru +0 -11
data/local.mk.sample
CHANGED
@@ -37,15 +37,6 @@ else
|
|
37
37
|
RUBY := $(prefix)/bin/ruby --disable-gems
|
38
38
|
endif
|
39
39
|
|
40
|
-
# FIXME: use isolate more
|
41
|
-
ifndef RUBYLIB
|
42
|
-
gems := rack-1.1.0
|
43
|
-
gem_paths := $(addprefix $(HOME)/lib/ruby/gems/1.8/gems/,$(gems))
|
44
|
-
sp :=
|
45
|
-
sp +=
|
46
|
-
export RUBYLIB := $(subst $(sp),:,$(addsuffix /lib,$(gem_paths)))
|
47
|
-
endif
|
48
|
-
|
49
40
|
# pipefail is THE reason to use bash (v3+) or never revisions of ksh93
|
50
41
|
# SHELL := /bin/bash -e -o pipefail
|
51
42
|
SHELL := /bin/ksh93 -e -o pipefail
|
@@ -0,0 +1,43 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# scripts/Makefiles can read and eval the output of this script and
|
3
|
+
# use it as RUBYLIB
|
4
|
+
require 'rubygems'
|
5
|
+
require 'isolate'
|
6
|
+
fp = File.open(__FILE__, "rb")
|
7
|
+
fp.flock(File::LOCK_EX)
|
8
|
+
|
9
|
+
ruby_engine = defined?(RUBY_ENGINE) ? RUBY_ENGINE : 'ruby'
|
10
|
+
opts = {
|
11
|
+
:system => false,
|
12
|
+
# we want "ruby-1.8.7" and not "ruby-1.8", so disable :multiruby
|
13
|
+
:multiruby => false,
|
14
|
+
:path => "tmp/isolate/#{ruby_engine}-#{RUBY_VERSION}",
|
15
|
+
}
|
16
|
+
|
17
|
+
pid = fork do
|
18
|
+
Isolate.now!(opts) do
|
19
|
+
gem 'sqlite3-ruby', '1.2.5'
|
20
|
+
gem 'kgio', '1.2.0'
|
21
|
+
gem 'rack', '1.1.0'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
_, status = Process.waitpid2(pid)
|
25
|
+
status.success? or abort status.inspect
|
26
|
+
lib_paths = Dir["#{opts[:path]}/gems/*-*/lib"].map { |x| File.expand_path(x) }
|
27
|
+
libs = "tmp/isolate/.#{ruby_engine}-#{RUBY_VERSION}.libs"
|
28
|
+
File.open("#{libs}.#$$", "w") { |fp| fp.puts lib_paths.join(':') }
|
29
|
+
File.rename("#{libs}.#$$", libs)
|
30
|
+
|
31
|
+
# pure Ruby gems can be shared across all Rubies
|
32
|
+
%w(3.0.0).each do |rails_ver|
|
33
|
+
opts[:path] = "tmp/isolate/rails-#{rails_ver}"
|
34
|
+
pid = fork do
|
35
|
+
Isolate.now!(opts) do
|
36
|
+
gem 'rails', rails_ver
|
37
|
+
end
|
38
|
+
end
|
39
|
+
_, status = Process.waitpid2(pid)
|
40
|
+
status.success? or abort status.inspect
|
41
|
+
more = Dir["#{opts[:path]}/gems/*-*/lib"].map { |x| File.expand_path(x) }
|
42
|
+
lib_paths.concat(more)
|
43
|
+
end
|
data/t/GNUmakefile
CHANGED
@@ -17,6 +17,13 @@ endif
|
|
17
17
|
RUBY_ENGINE := $(shell $(RUBY) -e 'puts((RUBY_ENGINE rescue "ruby"))')
|
18
18
|
export RUBY_ENGINE
|
19
19
|
|
20
|
+
isolate_libs := ../tmp/isolate/.$(RUBY_ENGINE)-$(RUBY_VERSION).libs
|
21
|
+
MYLIBS := $(shell cat $(isolate_libs))
|
22
|
+
ifeq ($(MY_LIBS),)
|
23
|
+
ignore := $(shell cd .. && $(RUBY) ./script/isolate_for_tests)
|
24
|
+
MYLIBS := $(shell cat $(isolate_libs))
|
25
|
+
endif
|
26
|
+
|
20
27
|
T = $(wildcard t[0-9][0-9][0-9][0-9]-*.sh)
|
21
28
|
|
22
29
|
all:: $(T)
|
@@ -58,7 +65,7 @@ $(test_prefix)/.stamp:
|
|
58
65
|
$(T): export RUBY := $(RUBY)
|
59
66
|
$(T): export RAKE := $(RAKE)
|
60
67
|
$(T): export PATH := $(test_prefix)/bin:$(PATH)
|
61
|
-
$(T): export RUBYLIB := $(test_prefix)/lib:$(
|
68
|
+
$(T): export RUBYLIB := $(test_prefix)/lib:$(MYLIBS)
|
62
69
|
$(T): dep $(test_prefix)/.stamp trash/.gitignore
|
63
70
|
$(TRACER) $(SHELL) $(SH_TEST_OPTS) $@ $(TEST_OPTS)
|
64
71
|
|
@@ -0,0 +1,55 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
. ./test-lib.sh
|
3
|
+
t_plan 9 "reap worker logging messages"
|
4
|
+
|
5
|
+
t_begin "setup and start" && {
|
6
|
+
unicorn_setup
|
7
|
+
cat >> $unicorn_config <<EOF
|
8
|
+
after_fork { |s,w| File.open('$fifo','w') { |f| f.write '.' } }
|
9
|
+
EOF
|
10
|
+
unicorn -c $unicorn_config pid.ru &
|
11
|
+
test '.' = $(cat $fifo)
|
12
|
+
unicorn_wait_start
|
13
|
+
}
|
14
|
+
|
15
|
+
t_begin "kill 1st worker=0" && {
|
16
|
+
pid_1=$(curl http://$listen/)
|
17
|
+
kill -9 $pid_1
|
18
|
+
}
|
19
|
+
|
20
|
+
t_begin "wait for 2nd worker to start" && {
|
21
|
+
test '.' = $(cat $fifo)
|
22
|
+
}
|
23
|
+
|
24
|
+
t_begin "ensure log of 1st reap is an ERROR" && {
|
25
|
+
dbgcat r_err
|
26
|
+
grep 'ERROR.*reaped.*worker=0' $r_err | grep $pid_1
|
27
|
+
dbgcat r_err
|
28
|
+
> $r_err
|
29
|
+
}
|
30
|
+
|
31
|
+
t_begin "kill 2nd worker gracefully" && {
|
32
|
+
pid_2=$(curl http://$listen/)
|
33
|
+
kill -QUIT $pid_2
|
34
|
+
}
|
35
|
+
|
36
|
+
t_begin "wait for 3rd worker=0 to start " && {
|
37
|
+
test '.' = $(cat $fifo)
|
38
|
+
}
|
39
|
+
|
40
|
+
t_begin "ensure log of 2nd reap is a INFO" && {
|
41
|
+
grep 'INFO.*reaped.*worker=0' $r_err | grep $pid_2
|
42
|
+
> $r_err
|
43
|
+
}
|
44
|
+
|
45
|
+
t_begin "killing succeeds" && {
|
46
|
+
kill $unicorn_pid
|
47
|
+
wait
|
48
|
+
kill -0 $unicorn_pid && false
|
49
|
+
}
|
50
|
+
|
51
|
+
t_begin "check stderr" && {
|
52
|
+
check_stderr
|
53
|
+
}
|
54
|
+
|
55
|
+
t_done
|
data/t/test-rails3.sh
CHANGED
@@ -13,7 +13,7 @@ rails_gems=../tmp/isolate/rails-$RAILS_VERSION/gems
|
|
13
13
|
rails_bin="$rails_gems/rails-$RAILS_VERSION/bin/rails"
|
14
14
|
if ! test -d "$arch_gems" || ! test -d "$rails_gems" || ! test -x "$rails_bin"
|
15
15
|
then
|
16
|
-
( cd ../ &&
|
16
|
+
( cd ../ && ./script/isolate_for_tests )
|
17
17
|
fi
|
18
18
|
|
19
19
|
for i in $arch_gems/*-* $rails_gems/*-*
|
data/test/exec/test_exec.rb
CHANGED
@@ -440,6 +440,17 @@ class HttpParserNgTest < Test::Unit::TestCase
|
|
440
440
|
end
|
441
441
|
end
|
442
442
|
|
443
|
+
def test_backtrace_is_empty
|
444
|
+
begin
|
445
|
+
@parser.headers({}, "AAADFSFDSFD\r\n\r\n")
|
446
|
+
assert false, "should never get here line:#{__LINE__}"
|
447
|
+
rescue HttpParserError => e
|
448
|
+
assert_equal [], e.backtrace
|
449
|
+
return
|
450
|
+
end
|
451
|
+
assert false, "should never get here line:#{__LINE__}"
|
452
|
+
end
|
453
|
+
|
443
454
|
def test_ignore_version_header
|
444
455
|
http = "GET / HTTP/1.1\r\nVersion: hello\r\n\r\n"
|
445
456
|
req = {}
|
data/test/unit/test_request.rb
CHANGED
@@ -11,7 +11,11 @@ class RequestTest < Test::Unit::TestCase
|
|
11
11
|
|
12
12
|
class MockRequest < StringIO
|
13
13
|
alias_method :readpartial, :sysread
|
14
|
+
alias_method :kgio_read!, :sysread
|
14
15
|
alias_method :read_nonblock, :sysread
|
16
|
+
def kgio_addr
|
17
|
+
'127.0.0.1'
|
18
|
+
end
|
15
19
|
end
|
16
20
|
|
17
21
|
def setup
|
@@ -159,6 +163,14 @@ class RequestTest < Test::Unit::TestCase
|
|
159
163
|
buf = (' ' * bs).freeze
|
160
164
|
length = bs * count
|
161
165
|
client = Tempfile.new('big_put')
|
166
|
+
def client.kgio_addr; '127.0.0.1'; end
|
167
|
+
def client.kgio_read(*args)
|
168
|
+
readpartial(*args)
|
169
|
+
rescue EOFError
|
170
|
+
end
|
171
|
+
def client.kgio_read!(*args)
|
172
|
+
readpartial(*args)
|
173
|
+
end
|
162
174
|
client.syswrite(
|
163
175
|
"PUT / HTTP/1.1\r\n" \
|
164
176
|
"Host: foo\r\n" \
|
data/test/unit/test_response.rb
CHANGED
@@ -11,18 +11,20 @@ require 'test/test_helper'
|
|
11
11
|
include Unicorn
|
12
12
|
|
13
13
|
class ResponseTest < Test::Unit::TestCase
|
14
|
-
|
14
|
+
include Unicorn::HttpResponse
|
15
|
+
|
15
16
|
def test_response_headers
|
16
17
|
out = StringIO.new
|
17
|
-
|
18
|
-
assert
|
18
|
+
http_response_write(out,[200, {"X-Whatever" => "stuff"}, ["cool"]])
|
19
|
+
assert out.closed?
|
20
|
+
|
19
21
|
assert out.length > 0, "output didn't have data"
|
20
22
|
end
|
21
23
|
|
22
24
|
def test_response_string_status
|
23
25
|
out = StringIO.new
|
24
|
-
|
25
|
-
assert
|
26
|
+
http_response_write(out,['200', {}, []])
|
27
|
+
assert out.closed?
|
26
28
|
assert out.length > 0, "output didn't have data"
|
27
29
|
assert_equal 1, out.string.split(/\r\n/).grep(/^Status: 200 OK/).size
|
28
30
|
end
|
@@ -31,8 +33,8 @@ class ResponseTest < Test::Unit::TestCase
|
|
31
33
|
old_ofs = $,
|
32
34
|
$, = "\f\v"
|
33
35
|
out = StringIO.new
|
34
|
-
|
35
|
-
assert
|
36
|
+
http_response_write(out,[200, {"X-k" => "cd","X-y" => "z"}, ["cool"]])
|
37
|
+
assert out.closed?
|
36
38
|
resp = out.string
|
37
39
|
assert ! resp.include?("\f\v"), "output didn't use $, ($OFS)"
|
38
40
|
ensure
|
@@ -41,16 +43,16 @@ class ResponseTest < Test::Unit::TestCase
|
|
41
43
|
|
42
44
|
def test_response_200
|
43
45
|
io = StringIO.new
|
44
|
-
|
45
|
-
assert
|
46
|
+
http_response_write(io, [200, {}, []])
|
47
|
+
assert io.closed?
|
46
48
|
assert io.length > 0, "output didn't have data"
|
47
49
|
end
|
48
50
|
|
49
51
|
def test_response_with_default_reason
|
50
52
|
code = 400
|
51
53
|
io = StringIO.new
|
52
|
-
|
53
|
-
assert
|
54
|
+
http_response_write(io, [code, {}, []])
|
55
|
+
assert io.closed?
|
54
56
|
lines = io.string.split(/\r\n/)
|
55
57
|
assert_match(/.* Bad Request$/, lines.first,
|
56
58
|
"wrong default reason phrase")
|
@@ -58,8 +60,8 @@ class ResponseTest < Test::Unit::TestCase
|
|
58
60
|
|
59
61
|
def test_rack_multivalue_headers
|
60
62
|
out = StringIO.new
|
61
|
-
|
62
|
-
assert
|
63
|
+
http_response_write(out,[200, {"X-Whatever" => "stuff\nbleh"}, []])
|
64
|
+
assert out.closed?
|
63
65
|
assert_match(/^X-Whatever: stuff\r\nX-Whatever: bleh\r\n/, out.string)
|
64
66
|
end
|
65
67
|
|
@@ -67,8 +69,8 @@ class ResponseTest < Test::Unit::TestCase
|
|
67
69
|
# some broken clients still rely on it
|
68
70
|
def test_status_header_added
|
69
71
|
out = StringIO.new
|
70
|
-
|
71
|
-
assert
|
72
|
+
http_response_write(out,[200, {"X-Whatever" => "stuff"}, []])
|
73
|
+
assert out.closed?
|
72
74
|
assert_equal 1, out.string.split(/\r\n/).grep(/^Status: 200 OK/i).size
|
73
75
|
end
|
74
76
|
|
@@ -78,8 +80,8 @@ class ResponseTest < Test::Unit::TestCase
|
|
78
80
|
def test_status_header_ignores_app_hash
|
79
81
|
out = StringIO.new
|
80
82
|
header_hash = {"X-Whatever" => "stuff", 'StaTus' => "666" }
|
81
|
-
|
82
|
-
assert
|
83
|
+
http_response_write(out,[200, header_hash, []])
|
84
|
+
assert out.closed?
|
83
85
|
assert_equal 1, out.string.split(/\r\n/).grep(/^Status: 200 OK/i).size
|
84
86
|
assert_equal 1, out.string.split(/\r\n/).grep(/^Status:/i).size
|
85
87
|
end
|
@@ -89,16 +91,16 @@ class ResponseTest < Test::Unit::TestCase
|
|
89
91
|
body = StringIO.new(expect_body)
|
90
92
|
body.rewind
|
91
93
|
out = StringIO.new
|
92
|
-
|
93
|
-
assert
|
94
|
+
http_response_write(out,[200, {}, body])
|
95
|
+
assert out.closed?
|
94
96
|
assert body.closed?
|
95
97
|
assert_match(expect_body, out.string.split(/\r\n/).last)
|
96
98
|
end
|
97
99
|
|
98
100
|
def test_unknown_status_pass_through
|
99
101
|
out = StringIO.new
|
100
|
-
|
101
|
-
assert
|
102
|
+
http_response_write(out,["666 I AM THE BEAST", {}, [] ])
|
103
|
+
assert out.closed?
|
102
104
|
headers = out.string.split(/\r\n\r\n/).first.split(/\r\n/)
|
103
105
|
assert %r{\AHTTP/\d\.\d 666 I AM THE BEAST\z}.match(headers[0])
|
104
106
|
status = headers.grep(/\AStatus:/i).first
|
data/test/unit/test_signals.rb
CHANGED
@@ -166,7 +166,7 @@ class SignalsTest < Test::Unit::TestCase
|
|
166
166
|
expect = @bs * @count
|
167
167
|
assert_equal(expect, got, "expect=#{expect} got=#{got}")
|
168
168
|
assert_nothing_raised { sock.close }
|
169
|
-
end
|
169
|
+
end
|
170
170
|
|
171
171
|
def test_request_read
|
172
172
|
app = lambda { |env|
|
data/test/unit/test_tee_input.rb
CHANGED
@@ -5,11 +5,12 @@ require 'digest/sha1'
|
|
5
5
|
require 'unicorn'
|
6
6
|
|
7
7
|
class TestTeeInput < Test::Unit::TestCase
|
8
|
+
MockRequest = Struct.new(:env, :parser, :buf)
|
8
9
|
|
9
10
|
def setup
|
10
11
|
@rs = $/
|
11
12
|
@env = {}
|
12
|
-
@rd, @wr =
|
13
|
+
@rd, @wr = Kgio::UNIXSocket.pair
|
13
14
|
@rd.sync = @wr.sync = true
|
14
15
|
@start_pid = $$
|
15
16
|
end
|
@@ -27,8 +28,8 @@ class TestTeeInput < Test::Unit::TestCase
|
|
27
28
|
end
|
28
29
|
|
29
30
|
def test_gets_long
|
30
|
-
|
31
|
-
ti = Unicorn::TeeInput.new(@rd,
|
31
|
+
r = init_request("hello", 5 + (4096 * 4 * 3) + "#$/foo#$/".size)
|
32
|
+
ti = Unicorn::TeeInput.new(@rd, r)
|
32
33
|
status = line = nil
|
33
34
|
pid = fork {
|
34
35
|
@rd.close
|
@@ -48,8 +49,8 @@ class TestTeeInput < Test::Unit::TestCase
|
|
48
49
|
end
|
49
50
|
|
50
51
|
def test_gets_short
|
51
|
-
|
52
|
-
ti = Unicorn::TeeInput.new(@rd,
|
52
|
+
r = init_request("hello", 5 + "#$/foo".size)
|
53
|
+
ti = Unicorn::TeeInput.new(@rd, r)
|
53
54
|
status = line = nil
|
54
55
|
pid = fork {
|
55
56
|
@rd.close
|
@@ -67,8 +68,8 @@ class TestTeeInput < Test::Unit::TestCase
|
|
67
68
|
end
|
68
69
|
|
69
70
|
def test_small_body
|
70
|
-
|
71
|
-
ti = Unicorn::TeeInput.new(@rd,
|
71
|
+
r = init_request('hello')
|
72
|
+
ti = Unicorn::TeeInput.new(@rd, r)
|
72
73
|
assert_equal 0, @parser.content_length
|
73
74
|
assert @parser.body_eof?
|
74
75
|
assert_equal StringIO, ti.tmp.class
|
@@ -80,8 +81,8 @@ class TestTeeInput < Test::Unit::TestCase
|
|
80
81
|
end
|
81
82
|
|
82
83
|
def test_read_with_buffer
|
83
|
-
|
84
|
-
ti = Unicorn::TeeInput.new(@rd,
|
84
|
+
r = init_request('hello')
|
85
|
+
ti = Unicorn::TeeInput.new(@rd, r)
|
85
86
|
buf = ''
|
86
87
|
rv = ti.read(4, buf)
|
87
88
|
assert_equal 'hell', rv
|
@@ -95,8 +96,8 @@ class TestTeeInput < Test::Unit::TestCase
|
|
95
96
|
end
|
96
97
|
|
97
98
|
def test_big_body
|
98
|
-
|
99
|
-
ti = Unicorn::TeeInput.new(@rd,
|
99
|
+
r = init_request('.' * Unicorn::Const::MAX_BODY << 'a')
|
100
|
+
ti = Unicorn::TeeInput.new(@rd, r)
|
100
101
|
assert_equal 0, @parser.content_length
|
101
102
|
assert @parser.body_eof?
|
102
103
|
assert_kind_of File, ti.tmp
|
@@ -106,9 +107,9 @@ class TestTeeInput < Test::Unit::TestCase
|
|
106
107
|
|
107
108
|
def test_read_in_full_if_content_length
|
108
109
|
a, b = 300, 3
|
109
|
-
|
110
|
+
r = init_request('.' * b, 300)
|
110
111
|
assert_equal 300, @parser.content_length
|
111
|
-
ti = Unicorn::TeeInput.new(@rd,
|
112
|
+
ti = Unicorn::TeeInput.new(@rd, r)
|
112
113
|
pid = fork {
|
113
114
|
@wr.write('.' * 197)
|
114
115
|
sleep 1 # still a *potential* race here that would make the test moot...
|
@@ -121,8 +122,8 @@ class TestTeeInput < Test::Unit::TestCase
|
|
121
122
|
end
|
122
123
|
|
123
124
|
def test_big_body_multi
|
124
|
-
|
125
|
-
ti = Unicorn::TeeInput.new(@rd,
|
125
|
+
r = init_request('.', Unicorn::Const::MAX_BODY + 1)
|
126
|
+
ti = Unicorn::TeeInput.new(@rd, r)
|
126
127
|
assert_equal Unicorn::Const::MAX_BODY, @parser.content_length
|
127
128
|
assert ! @parser.body_eof?
|
128
129
|
assert_kind_of File, ti.tmp
|
@@ -163,7 +164,7 @@ class TestTeeInput < Test::Unit::TestCase
|
|
163
164
|
@wr.write("0\r\n\r\n")
|
164
165
|
}
|
165
166
|
@wr.close
|
166
|
-
ti = Unicorn::TeeInput.new(@rd, @env, @parser, @buf)
|
167
|
+
ti = Unicorn::TeeInput.new(@rd, MockRequest.new(@env, @parser, @buf))
|
167
168
|
assert_nil @parser.content_length
|
168
169
|
assert_nil ti.len
|
169
170
|
assert ! @parser.body_eof?
|
@@ -201,7 +202,7 @@ class TestTeeInput < Test::Unit::TestCase
|
|
201
202
|
end
|
202
203
|
@wr.write("0\r\n\r\n")
|
203
204
|
}
|
204
|
-
ti = Unicorn::TeeInput.new(@rd, @env, @parser, @buf)
|
205
|
+
ti = Unicorn::TeeInput.new(@rd, MockRequest.new(@env, @parser, @buf))
|
205
206
|
assert_nil @parser.content_length
|
206
207
|
assert_nil ti.len
|
207
208
|
assert ! @parser.body_eof?
|
@@ -230,7 +231,7 @@ class TestTeeInput < Test::Unit::TestCase
|
|
230
231
|
@wr.write("Hello: World\r\n\r\n")
|
231
232
|
}
|
232
233
|
@wr.close
|
233
|
-
ti = Unicorn::TeeInput.new(@rd, @env, @parser, @buf)
|
234
|
+
ti = Unicorn::TeeInput.new(@rd, MockRequest.new(@env, @parser, @buf))
|
234
235
|
assert_nil @parser.content_length
|
235
236
|
assert_nil ti.len
|
236
237
|
assert ! @parser.body_eof?
|
@@ -243,7 +244,7 @@ class TestTeeInput < Test::Unit::TestCase
|
|
243
244
|
|
244
245
|
private
|
245
246
|
|
246
|
-
def
|
247
|
+
def init_request(body, size = nil)
|
247
248
|
@parser = Unicorn::HttpParser.new
|
248
249
|
body = body.to_s.freeze
|
249
250
|
@buf = "POST / HTTP/1.1\r\n" \
|
@@ -252,6 +253,7 @@ private
|
|
252
253
|
"\r\n#{body}"
|
253
254
|
assert_equal @env, @parser.headers(@env, @buf)
|
254
255
|
assert_equal body, @buf
|
256
|
+
MockRequest.new(@env, @parser, @buf)
|
255
257
|
end
|
256
258
|
|
257
259
|
end
|