unicorn 3.3.1 → 3.4.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/.wrongdoc.yml +2 -2
- data/GIT-VERSION-GEN +1 -1
- data/KNOWN_ISSUES +17 -7
- data/README +2 -2
- data/Rakefile +3 -2
- data/examples/nginx.conf +12 -8
- data/ext/unicorn_http/unicorn_http.rl +12 -1
- data/ext/unicorn_http/unicorn_http_common.rl +1 -1
- data/lib/unicorn/app/exec_cgi.rb +25 -22
- data/lib/unicorn/configurator.rb +17 -11
- data/lib/unicorn/const.rb +2 -2
- data/lib/unicorn/http_response.rb +1 -1
- data/lib/unicorn/http_server.rb +0 -1
- data/lib/unicorn/socket_helper.rb +33 -19
- data/lib/unicorn/tee_input.rb +1 -1
- data/script/isolate_for_tests +1 -1
- data/t/bin/unused_listen +2 -15
- data/test/exec/test_exec.rb +1 -2
- data/test/rails/test_rails.rb +1 -1
- data/test/test_helper.rb +3 -16
- data/test/unit/test_configurator.rb +8 -0
- data/test/unit/test_http_parser.rb +294 -130
- data/test/unit/test_http_parser_ng.rb +147 -126
- data/test/unit/test_request.rb +3 -3
- data/test/unit/test_response.rb +0 -12
- data/test/unit/test_server.rb +4 -7
- data/test/unit/test_tee_input.rb +25 -21
- data/test/unit/test_upload.rb +10 -2
- data/unicorn.gemspec +2 -2
- metadata +12 -12
data/test/unit/test_request.rb
CHANGED
@@ -121,7 +121,7 @@ class RequestTest < Test::Unit::TestCase
|
|
121
121
|
|
122
122
|
def test_no_content_stringio
|
123
123
|
client = MockRequest.new("GET / HTTP/1.1\r\nHost: foo\r\n\r\n")
|
124
|
-
|
124
|
+
env = nil
|
125
125
|
assert_nothing_raised { env = @request.read(client) }
|
126
126
|
assert_equal StringIO, env['rack.input'].class
|
127
127
|
end
|
@@ -130,7 +130,7 @@ class RequestTest < Test::Unit::TestCase
|
|
130
130
|
client = MockRequest.new("PUT / HTTP/1.1\r\n" \
|
131
131
|
"Content-Length: 0\r\n" \
|
132
132
|
"Host: foo\r\n\r\n")
|
133
|
-
|
133
|
+
env = nil
|
134
134
|
assert_nothing_raised { env = @request.read(client) }
|
135
135
|
assert_equal StringIO, env['rack.input'].class
|
136
136
|
end
|
@@ -139,7 +139,7 @@ class RequestTest < Test::Unit::TestCase
|
|
139
139
|
client = MockRequest.new("PUT / HTTP/1.1\r\n" \
|
140
140
|
"Content-Length: 1\r\n" \
|
141
141
|
"Host: foo\r\n\r\n")
|
142
|
-
|
142
|
+
env = nil
|
143
143
|
assert_nothing_raised { env = @request.read(client) }
|
144
144
|
assert_equal Unicorn::TeeInput, env['rack.input'].class
|
145
145
|
end
|
data/test/unit/test_response.rb
CHANGED
@@ -73,18 +73,6 @@ class ResponseTest < Test::Unit::TestCase
|
|
73
73
|
assert_equal 1, out.string.split(/\r\n/).grep(/^Status: 200 OK/i).size
|
74
74
|
end
|
75
75
|
|
76
|
-
# we always favor the code returned by the application, since "Status"
|
77
|
-
# in the header hash is not allowed by Rack (but not every app is
|
78
|
-
# fully Rack-compliant).
|
79
|
-
def test_status_header_ignores_app_hash
|
80
|
-
out = StringIO.new
|
81
|
-
header_hash = {"X-Whatever" => "stuff", 'StaTus' => "666" }
|
82
|
-
http_response_write(out,200, header_hash, [])
|
83
|
-
assert ! out.closed?
|
84
|
-
assert_equal 1, out.string.split(/\r\n/).grep(/^Status: 200 OK/i).size
|
85
|
-
assert_equal 1, out.string.split(/\r\n/).grep(/^Status:/i).size
|
86
|
-
end
|
87
|
-
|
88
76
|
def test_body_closed
|
89
77
|
expect_body = %w(1 2 3 4).join("\n")
|
90
78
|
body = StringIO.new(expect_body)
|
data/test/unit/test_server.rb
CHANGED
@@ -10,7 +10,7 @@ require 'test/test_helper'
|
|
10
10
|
|
11
11
|
include Unicorn
|
12
12
|
|
13
|
-
class TestHandler
|
13
|
+
class TestHandler
|
14
14
|
|
15
15
|
def call(env)
|
16
16
|
while env['rack.input'].read(4096)
|
@@ -19,7 +19,7 @@ class TestHandler
|
|
19
19
|
rescue Unicorn::ClientShutdown, Unicorn::HttpParserError => e
|
20
20
|
$stderr.syswrite("#{e.class}: #{e.message} #{e.backtrace.empty?}\n")
|
21
21
|
raise e
|
22
|
-
|
22
|
+
end
|
23
23
|
end
|
24
24
|
|
25
25
|
|
@@ -169,7 +169,6 @@ class WebServerTest < Test::Unit::TestCase
|
|
169
169
|
|
170
170
|
def test_client_malformed_body
|
171
171
|
sock = nil
|
172
|
-
buf = nil
|
173
172
|
bs = 15653984
|
174
173
|
assert_nothing_raised do
|
175
174
|
sock = TCPSocket.new('127.0.0.1', @port)
|
@@ -271,7 +270,7 @@ class WebServerTest < Test::Unit::TestCase
|
|
271
270
|
def test_file_streamed_request
|
272
271
|
body = "a" * (Unicorn::Const::MAX_BODY * 2)
|
273
272
|
long = "PUT /test HTTP/1.1\r\nContent-length: #{body.length}\r\n\r\n" + body
|
274
|
-
do_test(long, Unicorn::Const::CHUNK_SIZE * 2 -400)
|
273
|
+
do_test(long, Unicorn::Const::CHUNK_SIZE * 2 - 400)
|
275
274
|
end
|
276
275
|
|
277
276
|
def test_file_streamed_request_bad_body
|
@@ -279,13 +278,11 @@ class WebServerTest < Test::Unit::TestCase
|
|
279
278
|
long = "GET /test HTTP/1.1\r\nContent-ength: #{body.length}\r\n\r\n" + body
|
280
279
|
assert_raises(EOFError,Errno::ECONNRESET,Errno::EPIPE,Errno::EINVAL,
|
281
280
|
Errno::EBADF) {
|
282
|
-
do_test(long, Unicorn::Const::CHUNK_SIZE * 2 -400)
|
281
|
+
do_test(long, Unicorn::Const::CHUNK_SIZE * 2 - 400)
|
283
282
|
}
|
284
283
|
end
|
285
284
|
|
286
285
|
def test_listener_names
|
287
286
|
assert_equal [ "127.0.0.1:#@port" ], Unicorn.listener_names
|
288
287
|
end
|
289
|
-
|
290
288
|
end
|
291
|
-
|
data/test/unit/test_tee_input.rb
CHANGED
@@ -12,7 +12,6 @@ class TestTeeInput < Test::Unit::TestCase
|
|
12
12
|
|
13
13
|
def setup
|
14
14
|
@rs = $/
|
15
|
-
@env = {}
|
16
15
|
@rd, @wr = Kgio::UNIXSocket.pair
|
17
16
|
@rd.sync = @wr.sync = true
|
18
17
|
@start_pid = $$
|
@@ -154,12 +153,12 @@ class TestTeeInput < Test::Unit::TestCase
|
|
154
153
|
|
155
154
|
def test_chunked
|
156
155
|
@parser = Unicorn::HttpParser.new
|
157
|
-
@buf
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
assert_equal "", @buf
|
156
|
+
@parser.buf << "POST / HTTP/1.1\r\n" \
|
157
|
+
"Host: localhost\r\n" \
|
158
|
+
"Transfer-Encoding: chunked\r\n" \
|
159
|
+
"\r\n"
|
160
|
+
assert @parser.parse
|
161
|
+
assert_equal "", @parser.buf
|
163
162
|
|
164
163
|
pid = fork {
|
165
164
|
@rd.close
|
@@ -189,12 +188,13 @@ class TestTeeInput < Test::Unit::TestCase
|
|
189
188
|
|
190
189
|
def test_chunked_ping_pong
|
191
190
|
@parser = Unicorn::HttpParser.new
|
192
|
-
|
191
|
+
buf = @parser.buf
|
192
|
+
buf << "POST / HTTP/1.1\r\n" \
|
193
193
|
"Host: localhost\r\n" \
|
194
194
|
"Transfer-Encoding: chunked\r\n" \
|
195
195
|
"\r\n"
|
196
|
-
|
197
|
-
assert_equal "",
|
196
|
+
assert @parser.parse
|
197
|
+
assert_equal "", buf
|
198
198
|
chunks = %w(aa bbb cccc dddd eeee)
|
199
199
|
rd, wr = IO.pipe
|
200
200
|
|
@@ -219,13 +219,14 @@ class TestTeeInput < Test::Unit::TestCase
|
|
219
219
|
|
220
220
|
def test_chunked_with_trailer
|
221
221
|
@parser = Unicorn::HttpParser.new
|
222
|
-
|
222
|
+
buf = @parser.buf
|
223
|
+
buf << "POST / HTTP/1.1\r\n" \
|
223
224
|
"Host: localhost\r\n" \
|
224
225
|
"Trailer: Hello\r\n" \
|
225
226
|
"Transfer-Encoding: chunked\r\n" \
|
226
227
|
"\r\n"
|
227
|
-
|
228
|
-
assert_equal "",
|
228
|
+
assert @parser.parse
|
229
|
+
assert_equal "", buf
|
229
230
|
|
230
231
|
pid = fork {
|
231
232
|
@rd.close
|
@@ -239,7 +240,7 @@ class TestTeeInput < Test::Unit::TestCase
|
|
239
240
|
assert_nil ti.len
|
240
241
|
assert ! @parser.body_eof?
|
241
242
|
assert_equal 25, ti.size
|
242
|
-
assert_equal "World", @env['HTTP_HELLO']
|
243
|
+
assert_equal "World", @parser.env['HTTP_HELLO']
|
243
244
|
status = nil
|
244
245
|
assert_nothing_raised { pid, status = Process.waitpid2(pid) }
|
245
246
|
assert status.success?
|
@@ -247,13 +248,14 @@ class TestTeeInput < Test::Unit::TestCase
|
|
247
248
|
|
248
249
|
def test_chunked_and_size_slow
|
249
250
|
@parser = Unicorn::HttpParser.new
|
250
|
-
|
251
|
+
buf = @parser.buf
|
252
|
+
buf << "POST / HTTP/1.1\r\n" \
|
251
253
|
"Host: localhost\r\n" \
|
252
254
|
"Trailer: Hello\r\n" \
|
253
255
|
"Transfer-Encoding: chunked\r\n" \
|
254
256
|
"\r\n"
|
255
|
-
|
256
|
-
assert_equal "",
|
257
|
+
assert @parser.parse
|
258
|
+
assert_equal "", buf
|
257
259
|
|
258
260
|
@wr.write("9\r\nabcde")
|
259
261
|
ti = TeeInput.new(@rd, @parser)
|
@@ -264,7 +266,7 @@ class TestTeeInput < Test::Unit::TestCase
|
|
264
266
|
assert_equal 9, ti.size
|
265
267
|
assert_equal "fghi", ti.read(9)
|
266
268
|
assert_equal nil, ti.read(9)
|
267
|
-
assert_equal "World", @env['HTTP_HELLO']
|
269
|
+
assert_equal "World", @parser.env['HTTP_HELLO']
|
268
270
|
end
|
269
271
|
|
270
272
|
def test_gets_read_mix
|
@@ -280,12 +282,14 @@ private
|
|
280
282
|
def init_request(body, size = nil)
|
281
283
|
@parser = Unicorn::HttpParser.new
|
282
284
|
body = body.to_s.freeze
|
283
|
-
|
285
|
+
buf = @parser.buf
|
286
|
+
buf << "POST / HTTP/1.1\r\n" \
|
284
287
|
"Host: localhost\r\n" \
|
285
288
|
"Content-Length: #{size || body.size}\r\n" \
|
286
289
|
"\r\n#{body}"
|
287
|
-
|
288
|
-
assert_equal body,
|
290
|
+
assert @parser.parse
|
291
|
+
assert_equal body, buf
|
292
|
+
@buf = buf
|
289
293
|
@parser
|
290
294
|
end
|
291
295
|
|
data/test/unit/test_upload.rb
CHANGED
@@ -145,8 +145,14 @@ class UploadTest < Test::Unit::TestCase
|
|
145
145
|
end
|
146
146
|
|
147
147
|
def test_put_excessive_overwrite_closed
|
148
|
+
tmp = Tempfile.new('overwrite_check')
|
149
|
+
tmp.sync = true
|
148
150
|
start_server(lambda { |env|
|
149
|
-
|
151
|
+
nr = 0
|
152
|
+
while buf = env['rack.input'].read(65536)
|
153
|
+
nr += buf.size
|
154
|
+
end
|
155
|
+
tmp.write(nr.to_s)
|
150
156
|
[ 200, @hdr, [] ]
|
151
157
|
})
|
152
158
|
sock = TCPSocket.new(@addr, @port)
|
@@ -157,7 +163,9 @@ class UploadTest < Test::Unit::TestCase
|
|
157
163
|
assert_raise(Errno::ECONNRESET, Errno::EPIPE) do
|
158
164
|
::Unicorn::Const::CHUNK_SIZE.times { sock.syswrite(buf) }
|
159
165
|
end
|
160
|
-
|
166
|
+
assert_nothing_raised { sock.gets }
|
167
|
+
tmp.rewind
|
168
|
+
assert_equal length, tmp.read.to_i
|
161
169
|
end
|
162
170
|
|
163
171
|
# Despite reading numerous articles and inspecting the 1.9.1-p0 C
|
data/unicorn.gemspec
CHANGED
@@ -35,10 +35,10 @@ Gem::Specification.new do |s|
|
|
35
35
|
# commented out. Nevertheless, upgrading to Rails 2.3.4 or later is
|
36
36
|
# *strongly* recommended for security reasons.
|
37
37
|
s.add_dependency(%q<rack>)
|
38
|
-
s.add_dependency(%q<kgio>, '~> 2.
|
38
|
+
s.add_dependency(%q<kgio>, '~> 2.2')
|
39
39
|
|
40
40
|
s.add_development_dependency('isolate', '~> 3.0.0')
|
41
|
-
s.add_development_dependency('wrongdoc', '~> 1.
|
41
|
+
s.add_development_dependency('wrongdoc', '~> 1.5')
|
42
42
|
|
43
43
|
# s.licenses = %w(GPLv2 Ruby) # licenses= method is not in older RubyGems
|
44
44
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: unicorn
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 23
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 3
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 3.
|
8
|
+
- 4
|
9
|
+
- 0
|
10
|
+
version: 3.4.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Unicorn hackers
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-02-04 00:00:00 +00:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -40,11 +40,11 @@ dependencies:
|
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
42
42
|
- !ruby/object:Gem::Version
|
43
|
-
hash:
|
43
|
+
hash: 7
|
44
44
|
segments:
|
45
45
|
- 2
|
46
|
-
-
|
47
|
-
version: "2.
|
46
|
+
- 2
|
47
|
+
version: "2.2"
|
48
48
|
type: :runtime
|
49
49
|
version_requirements: *id002
|
50
50
|
- !ruby/object:Gem::Dependency
|
@@ -71,11 +71,11 @@ dependencies:
|
|
71
71
|
requirements:
|
72
72
|
- - ~>
|
73
73
|
- !ruby/object:Gem::Version
|
74
|
-
hash:
|
74
|
+
hash: 5
|
75
75
|
segments:
|
76
76
|
- 1
|
77
|
-
-
|
78
|
-
version: "1.
|
77
|
+
- 5
|
78
|
+
version: "1.5"
|
79
79
|
type: :development
|
80
80
|
version_requirements: *id004
|
81
81
|
description: |-
|
@@ -389,7 +389,7 @@ rdoc_options:
|
|
389
389
|
- -t
|
390
390
|
- "Unicorn: Rack HTTP server for fast clients and Unix"
|
391
391
|
- -W
|
392
|
-
- http://
|
392
|
+
- http://bogomips.org/unicorn.git/tree/%s
|
393
393
|
require_paths:
|
394
394
|
- lib
|
395
395
|
- ext
|