unicorn 5.0.1 → 5.3.1
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.
- checksums.yaml +4 -4
- data/.manifest +1 -0
- data/.olddoc.yml +6 -4
- data/Documentation/unicorn.1.txt +2 -3
- data/Documentation/unicorn_rails.1.txt +3 -3
- data/FAQ +1 -1
- data/GIT-VERSION-FILE +1 -1
- data/GIT-VERSION-GEN +1 -1
- data/GNUmakefile +3 -3
- data/HACKING +1 -2
- data/ISSUES +21 -17
- data/KNOWN_ISSUES +2 -2
- data/LATEST +102 -28
- data/Links +3 -3
- data/NEWS +373 -0
- data/README +7 -19
- data/SIGNALS +1 -1
- data/Sandbox +6 -5
- data/TODO +0 -2
- data/TUNING +19 -1
- data/examples/big_app_gc.rb +1 -1
- data/examples/init.sh +36 -8
- data/examples/logrotate.conf +16 -1
- data/examples/nginx.conf +1 -1
- data/examples/unicorn.conf.minimal.rb +2 -2
- data/examples/unicorn.conf.rb +2 -2
- data/examples/unicorn@.service +7 -0
- data/ext/unicorn_http/common_field_optimization.h +2 -2
- data/ext/unicorn_http/ext_help.h +0 -20
- data/ext/unicorn_http/extconf.rb +1 -1
- data/ext/unicorn_http/global_variables.h +2 -2
- data/ext/unicorn_http/httpdate.c +2 -2
- data/ext/unicorn_http/unicorn_http.c +673 -358
- data/ext/unicorn_http/unicorn_http.rl +32 -16
- data/ext/unicorn_http/unicorn_http_common.rl +1 -1
- data/lib/unicorn/configurator.rb +71 -12
- data/lib/unicorn/http_request.rb +89 -9
- data/lib/unicorn/http_response.rb +5 -2
- data/lib/unicorn/http_server.rb +66 -22
- data/lib/unicorn/oob_gc.rb +4 -4
- data/lib/unicorn/socket_helper.rb +19 -4
- data/lib/unicorn/stream_input.rb +5 -4
- data/lib/unicorn/tee_input.rb +8 -10
- data/lib/unicorn/version.rb +1 -1
- data/lib/unicorn/worker.rb +17 -6
- data/lib/unicorn.rb +31 -20
- data/man/man1/unicorn.1 +54 -55
- data/man/man1/unicorn_rails.1 +47 -46
- data/t/t0011-active-unix-socket.sh +1 -1
- data/t/t0012-reload-empty-config.sh +2 -1
- data/t/test-lib.sh +2 -2
- data/test/exec/test_exec.rb +6 -5
- data/test/unit/test_ccc.rb +90 -0
- data/test/unit/test_http_parser.rb +31 -17
- data/test/unit/test_socket_helper.rb +8 -4
- data/test/unit/test_util.rb +2 -2
- data/unicorn.gemspec +15 -17
- metadata +6 -19
data/man/man1/unicorn_rails.1
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
.TH UNICORN_RAILS 1 "September 17, 2009" "Unicorn User Manual"
|
|
1
|
+
.TH "UNICORN_RAILS" "1" "September 17, 2009" "Unicorn User Manual" ""
|
|
2
2
|
.SH NAME
|
|
3
3
|
.PP
|
|
4
|
-
unicorn_rails
|
|
5
|
-
server
|
|
4
|
+
unicorn_rails \- unicorn launcher for Rails 1.x and 2.x users
|
|
6
5
|
.SH SYNOPSIS
|
|
7
6
|
.PP
|
|
8
|
-
unicorn_rails [
|
|
7
|
+
unicorn_rails [\-c CONFIG_FILE] [\-E RAILS_ENV] [\-D] [RACKUP_FILE]
|
|
9
8
|
.SH DESCRIPTION
|
|
10
9
|
.PP
|
|
11
|
-
A rackup(1)
|
|
10
|
+
A rackup(1)\-like command to launch Rails applications using Unicorn.
|
|
12
11
|
It is expected to be started in your Rails application root
|
|
13
12
|
(RAILS_ROOT), but the "working_directory" directive may be used in the
|
|
14
13
|
CONFIG_FILE.
|
|
@@ -24,14 +23,14 @@ The outward interface resembles rackup(1), the internals and default
|
|
|
24
23
|
middleware loading is designed like the \f[C]script/server\f[] command
|
|
25
24
|
distributed with Rails.
|
|
26
25
|
.PP
|
|
27
|
-
While Unicorn takes a myriad of command
|
|
26
|
+
While Unicorn takes a myriad of command\-line options for compatibility
|
|
28
27
|
with ruby(1) and rackup(1), it is recommended to stick to the few
|
|
29
|
-
command
|
|
28
|
+
command\-line options specified in the SYNOPSIS and use the CONFIG_FILE
|
|
30
29
|
as much as possible.
|
|
31
30
|
.SH UNICORN OPTIONS
|
|
32
31
|
.TP
|
|
33
|
-
.B
|
|
34
|
-
Path to the Unicorn
|
|
32
|
+
.B \-c, \-\-config\-file CONFIG_FILE
|
|
33
|
+
Path to the Unicorn\-specific config file.
|
|
35
34
|
The config file is implemented as a Ruby DSL, so Ruby code may executed.
|
|
36
35
|
See the RDoc/ri for the \f[I]Unicorn::Configurator\f[] class for the
|
|
37
36
|
full list of directives available from the DSL.
|
|
@@ -41,7 +40,7 @@ output.
|
|
|
41
40
|
.RS
|
|
42
41
|
.RE
|
|
43
42
|
.TP
|
|
44
|
-
.B
|
|
43
|
+
.B \-D, \-\-daemonize
|
|
45
44
|
Run daemonized in the background.
|
|
46
45
|
The process is detached from the controlling terminal and stdin is
|
|
47
46
|
redirected to "/dev/null".
|
|
@@ -58,7 +57,7 @@ Unicorn config file.
|
|
|
58
57
|
.RS
|
|
59
58
|
.RE
|
|
60
59
|
.TP
|
|
61
|
-
.B
|
|
60
|
+
.B \-E, \-\-env RAILS_ENV
|
|
62
61
|
Run under the given RAILS_ENV.
|
|
63
62
|
This sets the RAILS_ENV environment variable.
|
|
64
63
|
Acceptable values are exactly those you expect in your Rails
|
|
@@ -66,38 +65,38 @@ application, typically "development" or "production".
|
|
|
66
65
|
.RS
|
|
67
66
|
.RE
|
|
68
67
|
.TP
|
|
69
|
-
.B
|
|
68
|
+
.B \-l, \-\-listen ADDRESS
|
|
70
69
|
Listens on a given ADDRESS.
|
|
71
70
|
ADDRESS may be in the form of HOST:PORT or PATH, HOST:PORT is taken to
|
|
72
71
|
mean a TCP socket and PATH is meant to be a path to a UNIX domain
|
|
73
72
|
socket.
|
|
74
73
|
Defaults to "0.0.0.0:8080" (all addresses on TCP port 8080).
|
|
75
74
|
For production deployments, specifying the "listen" directive in
|
|
76
|
-
CONFIG_FILE is recommended as it allows fine
|
|
75
|
+
CONFIG_FILE is recommended as it allows fine\-tuning of socket options.
|
|
77
76
|
.RS
|
|
78
77
|
.RE
|
|
79
78
|
.SH RACKUP COMPATIBILITY OPTIONS
|
|
80
79
|
.TP
|
|
81
|
-
.B
|
|
80
|
+
.B \-o, \-\-host HOST
|
|
82
81
|
Listen on a TCP socket belonging to HOST, default is "0.0.0.0" (all
|
|
83
82
|
addresses).
|
|
84
|
-
If specified multiple times on the command
|
|
85
|
-
value takes effect.
|
|
83
|
+
If specified multiple times on the command\-line, only the
|
|
84
|
+
last\-specified value takes effect.
|
|
86
85
|
This option only exists for compatibility with the rackup(1) command,
|
|
87
|
-
use of "
|
|
86
|
+
use of "\-l"/"\-\-listen" switch is recommended instead.
|
|
88
87
|
.RS
|
|
89
88
|
.RE
|
|
90
89
|
.TP
|
|
91
|
-
.B
|
|
90
|
+
.B \-p, \-\-port PORT
|
|
92
91
|
Listen on the specified TCP PORT, default is 8080.
|
|
93
|
-
If specified multiple times on the command
|
|
94
|
-
value takes effect.
|
|
92
|
+
If specified multiple times on the command\-line, only the
|
|
93
|
+
last\-specified value takes effect.
|
|
95
94
|
This option only exists for compatibility with the rackup(1) command,
|
|
96
|
-
use of "
|
|
95
|
+
use of "\-l"/"\-\-listen" switch is recommended instead.
|
|
97
96
|
.RS
|
|
98
97
|
.RE
|
|
99
98
|
.TP
|
|
100
|
-
.B
|
|
99
|
+
.B \-\-path PATH
|
|
101
100
|
Mounts the Rails application at the given PATH (instead of "/").
|
|
102
101
|
This is equivalent to setting the RAILS_RELATIVE_URL_ROOT environment
|
|
103
102
|
variable.
|
|
@@ -106,38 +105,39 @@ This is only supported under Rails 2.3 or later at the moment.
|
|
|
106
105
|
.RE
|
|
107
106
|
.SH RUBY OPTIONS
|
|
108
107
|
.TP
|
|
109
|
-
.B
|
|
108
|
+
.B \-e, \-\-eval LINE
|
|
110
109
|
Evaluate a LINE of Ruby code.
|
|
111
|
-
This evaluation happens immediately as the command
|
|
110
|
+
This evaluation happens immediately as the command\-line is being
|
|
111
|
+
parsed.
|
|
112
112
|
.RS
|
|
113
113
|
.RE
|
|
114
114
|
.TP
|
|
115
|
-
.B
|
|
115
|
+
.B \-d, \-\-debug
|
|
116
116
|
Turn on debug mode, the $DEBUG variable is set to true.
|
|
117
117
|
For Rails >= 2.3.x, this loads the \f[I]Rails::Rack::Debugger\f[]
|
|
118
118
|
middleware.
|
|
119
119
|
.RS
|
|
120
120
|
.RE
|
|
121
121
|
.TP
|
|
122
|
-
.B
|
|
122
|
+
.B \-w, \-\-warn
|
|
123
123
|
Turn on verbose warnings, the $VERBOSE variable is set to true.
|
|
124
124
|
.RS
|
|
125
125
|
.RE
|
|
126
126
|
.TP
|
|
127
|
-
.B
|
|
128
|
-
specify
|
|
129
|
-
|
|
127
|
+
.B \-I, \-\-include PATH
|
|
128
|
+
specify
|
|
129
|
+
\f[I]L\f[]\f[I]O\f[]\f[I]A\f[]\f[I]D\f[]~\f[I]P\f[]~\f[I]A\f[]\f[I]T\f[]\f[I]H\f[].\f[I]P\f[]\f[I]A\f[]\f[I]T\f[]\f[I]H\f[]\f[I]w\f[]\f[I]i\f[]\f[I]l\f[]\f[I]l\f[]\f[I]b\f[]\f[I]e\f[]\f[I]p\f[]\f[I]r\f[]\f[I]e\f[]\f[I]p\f[]\f[I]e\f[]\f[I]n\f[]\f[I]d\f[]\f[I]e\f[]\f[I]d\f[]\f[I]t\f[]\f[I]o\f[]LOAD_PATH.
|
|
130
130
|
The \[aq]:\[aq] character may be used to delimit multiple directories.
|
|
131
131
|
This directive may be used more than once.
|
|
132
132
|
Modifications to $LOAD_PATH take place immediately and in the order they
|
|
133
|
-
were specified on the command
|
|
133
|
+
were specified on the command\-line.
|
|
134
134
|
.RS
|
|
135
135
|
.RE
|
|
136
136
|
.TP
|
|
137
|
-
.B
|
|
137
|
+
.B \-r, \-\-require LIBRARY
|
|
138
138
|
require a specified LIBRARY before executing the application.
|
|
139
139
|
The "require" statement will be executed immediately and in the order
|
|
140
|
-
they were specified on the command
|
|
140
|
+
they were specified on the command\-line.
|
|
141
141
|
.RS
|
|
142
142
|
.RE
|
|
143
143
|
.SH RACKUP FILE
|
|
@@ -149,15 +149,16 @@ Unlike many other Rack applications, RACKUP_FILE is completely
|
|
|
149
149
|
\f[I]optional\f[] for Rails, but may be used to disable some of the
|
|
150
150
|
default middleware for performance.
|
|
151
151
|
.PP
|
|
152
|
-
Embedded command
|
|
152
|
+
Embedded command\-line options are mostly parsed for compatibility with
|
|
153
153
|
rackup(1) but strongly discouraged.
|
|
154
154
|
.SH ENVIRONMENT VARIABLES
|
|
155
155
|
.PP
|
|
156
|
-
The RAILS_ENV variable is set by the aforementioned
|
|
157
|
-
The RAILS_RELATIVE_URL_ROOT is set by the aforementioned
|
|
156
|
+
The RAILS_ENV variable is set by the aforementioned \-E switch.
|
|
157
|
+
The RAILS_RELATIVE_URL_ROOT is set by the aforementioned \-\-path
|
|
158
|
+
switch.
|
|
158
159
|
Either of these variables may also be set in the shell or the Unicorn
|
|
159
160
|
CONFIG_FILE.
|
|
160
|
-
All application or library
|
|
161
|
+
All application or library\-specific environment variables (e.g.
|
|
161
162
|
TMPDIR, RAILS_ASSET_ID) may always be set in the Unicorn CONFIG_FILE in
|
|
162
163
|
addition to the spawning shell.
|
|
163
164
|
When transparently upgrading Unicorn, all environment variables set in
|
|
@@ -168,28 +169,28 @@ variable internally when doing transparent upgrades.
|
|
|
168
169
|
.PP
|
|
169
170
|
The following UNIX signals may be sent to the master process:
|
|
170
171
|
.IP \[bu] 2
|
|
171
|
-
HUP
|
|
172
|
+
HUP \- reload config file, app, and gracefully restart all workers
|
|
172
173
|
.IP \[bu] 2
|
|
173
|
-
INT/TERM
|
|
174
|
+
INT/TERM \- quick shutdown, kills all workers immediately
|
|
174
175
|
.IP \[bu] 2
|
|
175
|
-
QUIT
|
|
176
|
+
QUIT \- graceful shutdown, waits for workers to finish their current
|
|
176
177
|
request before finishing.
|
|
177
178
|
.IP \[bu] 2
|
|
178
|
-
USR1
|
|
179
|
+
USR1 \- reopen all logs owned by the master and all workers See
|
|
179
180
|
Unicorn::Util.reopen_logs for what is considered a log.
|
|
180
181
|
.IP \[bu] 2
|
|
181
|
-
USR2
|
|
182
|
+
USR2 \- reexecute the running binary.
|
|
182
183
|
A separate QUIT should be sent to the original process once the child is
|
|
183
184
|
verified to be up and running.
|
|
184
185
|
.IP \[bu] 2
|
|
185
|
-
WINCH
|
|
186
|
+
WINCH \- gracefully stops workers but keep the master running.
|
|
186
187
|
This will only work for daemonized processes.
|
|
187
188
|
.IP \[bu] 2
|
|
188
|
-
TTIN
|
|
189
|
+
TTIN \- increment the number of worker processes by one
|
|
189
190
|
.IP \[bu] 2
|
|
190
|
-
TTOU
|
|
191
|
+
TTOU \- decrement the number of worker processes by one
|
|
191
192
|
.PP
|
|
192
|
-
See the SIGNALS (
|
|
193
|
+
See the SIGNALS (https://bogomips.org/unicorn/SIGNALS.html) document for
|
|
193
194
|
full description of all signals used by Unicorn.
|
|
194
195
|
.SH SEE ALSO
|
|
195
196
|
.IP \[bu] 2
|
|
@@ -199,7 +200,7 @@ unicorn(1)
|
|
|
199
200
|
.IP \[bu] 2
|
|
200
201
|
\f[I]Unicorn::Configurator\f[] ri/RDoc
|
|
201
202
|
.IP \[bu] 2
|
|
202
|
-
Unicorn RDoc (
|
|
203
|
+
Unicorn RDoc (https://bogomips.org/unicorn/)
|
|
203
204
|
.IP \[bu] 2
|
|
204
205
|
Rack RDoc (http://www.rubydoc.info/github/rack/rack/)
|
|
205
206
|
.IP \[bu] 2
|
|
@@ -18,7 +18,8 @@ after_fork { |s,w| }
|
|
|
18
18
|
next if key =~ %r{\Astd(?:err|out)_path\z}
|
|
19
19
|
key = key.to_sym
|
|
20
20
|
def_value = defaults[key]
|
|
21
|
-
srv_value = srv.__send__(key)
|
|
21
|
+
srv_value = srv.respond_to?(key) ? srv.__send__(key)
|
|
22
|
+
: srv.instance_variable_get("@#{key}")
|
|
22
23
|
fp << "#{key}|#{srv_value}|#{def_value}\\n"
|
|
23
24
|
end
|
|
24
25
|
}
|
data/t/test-lib.sh
CHANGED
|
@@ -106,8 +106,8 @@ check_stderr () {
|
|
|
106
106
|
# unicorn_setup
|
|
107
107
|
unicorn_setup () {
|
|
108
108
|
eval $(unused_listen)
|
|
109
|
-
port=$(expr $listen : '[^:]*:\([0-9]
|
|
110
|
-
host=$(expr $listen : '\([^:]*\):[0-9]
|
|
109
|
+
port=$(expr $listen : '[^:]*:\([0-9]*\)')
|
|
110
|
+
host=$(expr $listen : '\([^:][^:]*\):[0-9][0-9]*')
|
|
111
111
|
|
|
112
112
|
rtmpfiles unicorn_config pid r_err r_out fifo tmp ok
|
|
113
113
|
cat > $unicorn_config <<EOF
|
data/test/exec/test_exec.rb
CHANGED
|
@@ -97,6 +97,9 @@ run lambda { |env|
|
|
|
97
97
|
end
|
|
98
98
|
|
|
99
99
|
def test_sd_listen_fds_emulation
|
|
100
|
+
# [ruby-core:69895] [Bug #11336] fixed by r51576
|
|
101
|
+
return if RUBY_VERSION.to_f < 2.3
|
|
102
|
+
|
|
100
103
|
File.open("config.ru", "wb") { |fp| fp.write(HI) }
|
|
101
104
|
sock = TCPServer.new(@addr, @port)
|
|
102
105
|
|
|
@@ -119,14 +122,12 @@ run lambda { |env|
|
|
|
119
122
|
res = hit(["http://#@addr:#@port/"])
|
|
120
123
|
assert_equal [ "HI\n" ], res
|
|
121
124
|
assert_shutdown(pid)
|
|
122
|
-
|
|
125
|
+
assert sock.getsockopt(:SOL_SOCKET, :SO_KEEPALIVE).bool,
|
|
123
126
|
'unicorn should always set SO_KEEPALIVE on inherited sockets'
|
|
124
127
|
end
|
|
125
128
|
ensure
|
|
126
129
|
sock.close if sock
|
|
127
|
-
|
|
128
|
-
# [ruby-core:69895] [Bug #11336] fixed by r51576
|
|
129
|
-
end if RUBY_VERSION.to_f >= 2.3
|
|
130
|
+
end
|
|
130
131
|
|
|
131
132
|
def test_inherit_listener_unspecified
|
|
132
133
|
File.open("config.ru", "wb") { |fp| fp.write(HI) }
|
|
@@ -142,7 +143,7 @@ run lambda { |env|
|
|
|
142
143
|
res = hit(["http://#@addr:#@port/"])
|
|
143
144
|
assert_equal [ "HI\n" ], res
|
|
144
145
|
assert_shutdown(pid)
|
|
145
|
-
|
|
146
|
+
assert sock.getsockopt(:SOL_SOCKET, :SO_KEEPALIVE).bool,
|
|
146
147
|
'unicorn should always set SO_KEEPALIVE on inherited sockets'
|
|
147
148
|
ensure
|
|
148
149
|
sock.close if sock
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
require 'socket'
|
|
2
|
+
require 'unicorn'
|
|
3
|
+
require 'io/wait'
|
|
4
|
+
require 'tempfile'
|
|
5
|
+
require 'test/unit'
|
|
6
|
+
|
|
7
|
+
class TestCccTCPI < Test::Unit::TestCase
|
|
8
|
+
def test_ccc_tcpi
|
|
9
|
+
start_pid = $$
|
|
10
|
+
host = '127.0.0.1'
|
|
11
|
+
srv = TCPServer.new(host, 0)
|
|
12
|
+
port = srv.addr[1]
|
|
13
|
+
err = Tempfile.new('unicorn_ccc')
|
|
14
|
+
rd, wr = IO.pipe
|
|
15
|
+
sleep_pipe = IO.pipe
|
|
16
|
+
pid = fork do
|
|
17
|
+
sleep_pipe[1].close
|
|
18
|
+
reqs = 0
|
|
19
|
+
rd.close
|
|
20
|
+
worker_pid = nil
|
|
21
|
+
app = lambda do |env|
|
|
22
|
+
worker_pid ||= begin
|
|
23
|
+
at_exit { wr.write(reqs.to_s) if worker_pid == $$ }
|
|
24
|
+
$$
|
|
25
|
+
end
|
|
26
|
+
reqs += 1
|
|
27
|
+
|
|
28
|
+
# will wake up when writer closes
|
|
29
|
+
sleep_pipe[0].read if env['PATH_INFO'] == '/sleep'
|
|
30
|
+
|
|
31
|
+
[ 200, [ %w(Content-Length 0), %w(Content-Type text/plain) ], [] ]
|
|
32
|
+
end
|
|
33
|
+
ENV['UNICORN_FD'] = srv.fileno.to_s
|
|
34
|
+
opts = {
|
|
35
|
+
listeners: [ "#{host}:#{port}" ],
|
|
36
|
+
stderr_path: err.path,
|
|
37
|
+
check_client_connection: true,
|
|
38
|
+
}
|
|
39
|
+
uni = Unicorn::HttpServer.new(app, opts)
|
|
40
|
+
uni.start.join
|
|
41
|
+
end
|
|
42
|
+
wr.close
|
|
43
|
+
|
|
44
|
+
# make sure the server is running, at least
|
|
45
|
+
client = TCPSocket.new(host, port)
|
|
46
|
+
client.write("GET / HTTP/1.1\r\nHost: example.com\r\n\r\n")
|
|
47
|
+
assert client.wait_readable(10), 'never got response from server'
|
|
48
|
+
res = client.read
|
|
49
|
+
assert_match %r{\AHTTP/1\.1 200}, res, 'got part of first response'
|
|
50
|
+
assert_match %r{\r\n\r\n\z}, res, 'got end of response, server is ready'
|
|
51
|
+
client.close
|
|
52
|
+
|
|
53
|
+
# start a slow request...
|
|
54
|
+
sleeper = TCPSocket.new(host, port)
|
|
55
|
+
sleeper.write("GET /sleep HTTP/1.1\r\nHost: example.com\r\n\r\n")
|
|
56
|
+
|
|
57
|
+
# and a bunch of aborted ones
|
|
58
|
+
nr = 100
|
|
59
|
+
nr.times do |i|
|
|
60
|
+
client = TCPSocket.new(host, port)
|
|
61
|
+
client.write("GET /collections/#{rand(10000)} HTTP/1.1\r\n" \
|
|
62
|
+
"Host: example.com\r\n\r\n")
|
|
63
|
+
client.close
|
|
64
|
+
end
|
|
65
|
+
sleep_pipe[1].close # wake up the reader in the worker
|
|
66
|
+
res = sleeper.read
|
|
67
|
+
assert_match %r{\AHTTP/1\.1 200}, res, 'got part of first sleeper response'
|
|
68
|
+
assert_match %r{\r\n\r\n\z}, res, 'got end of sleeper response'
|
|
69
|
+
sleeper.close
|
|
70
|
+
kpid = pid
|
|
71
|
+
pid = nil
|
|
72
|
+
Process.kill(:QUIT, kpid)
|
|
73
|
+
_, status = Process.waitpid2(kpid)
|
|
74
|
+
assert status.success?
|
|
75
|
+
reqs = rd.read.to_i
|
|
76
|
+
warn "server got #{reqs} requests with #{nr} CCC aborted\n" if $DEBUG
|
|
77
|
+
assert_operator reqs, :<, nr
|
|
78
|
+
assert_operator reqs, :>=, 2, 'first 2 requests got through, at least'
|
|
79
|
+
ensure
|
|
80
|
+
return if start_pid != $$
|
|
81
|
+
srv.close if srv
|
|
82
|
+
if pid
|
|
83
|
+
Process.kill(:QUIT, pid)
|
|
84
|
+
_, status = Process.waitpid2(pid)
|
|
85
|
+
assert status.success?
|
|
86
|
+
end
|
|
87
|
+
err.close! if err
|
|
88
|
+
rd.close if rd
|
|
89
|
+
end
|
|
90
|
+
end
|
|
@@ -230,6 +230,24 @@ class HttpParserTest < Test::Unit::TestCase
|
|
|
230
230
|
assert_equal expect, req['HTTP_X_SSL_BULLSHIT']
|
|
231
231
|
end
|
|
232
232
|
|
|
233
|
+
def test_multiline_header_0d0a
|
|
234
|
+
parser = HttpParser.new
|
|
235
|
+
parser.buf << "GET / HTTP/1.0\r\n" \
|
|
236
|
+
"X-Multiline-Header: foo bar\r\n\tcha cha\r\n\tzha zha\r\n\r\n"
|
|
237
|
+
req = parser.env
|
|
238
|
+
assert_equal req, parser.parse
|
|
239
|
+
assert_equal 'foo bar cha cha zha zha', req['HTTP_X_MULTILINE_HEADER']
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
def test_multiline_header_0a
|
|
243
|
+
parser = HttpParser.new
|
|
244
|
+
parser.buf << "GET / HTTP/1.0\n" \
|
|
245
|
+
"X-Multiline-Header: foo bar\n\tcha cha\n\tzha zha\n\n"
|
|
246
|
+
req = parser.env
|
|
247
|
+
assert_equal req, parser.parse
|
|
248
|
+
assert_equal 'foo bar cha cha zha zha', req['HTTP_X_MULTILINE_HEADER']
|
|
249
|
+
end
|
|
250
|
+
|
|
233
251
|
def test_continuation_eats_leading_spaces
|
|
234
252
|
parser = HttpParser.new
|
|
235
253
|
header = "GET / HTTP/1.1\r\n" \
|
|
@@ -833,22 +851,18 @@ class HttpParserTest < Test::Unit::TestCase
|
|
|
833
851
|
assert_equal '', parser.env['HTTP_HOST']
|
|
834
852
|
end
|
|
835
853
|
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
after = $1.to_i
|
|
847
|
-
diff = after - before
|
|
848
|
-
assert(diff < 10000, "memory grew more than 10M: #{diff}")
|
|
854
|
+
def test_memsize
|
|
855
|
+
require 'objspace'
|
|
856
|
+
if ObjectSpace.respond_to?(:memsize_of)
|
|
857
|
+
n = ObjectSpace.memsize_of(Unicorn::HttpParser.new)
|
|
858
|
+
assert_kind_of Integer, n
|
|
859
|
+
# need to update this when 128-bit machines come out
|
|
860
|
+
# n.b. actual struct size on 64-bit is 56 bytes + 40 bytes for RVALUE
|
|
861
|
+
# Ruby <= 2.2 objspace did not count the 40-byte RVALUE, 2.3 does.
|
|
862
|
+
assert_operator n, :<=, 96
|
|
863
|
+
assert_operator n, :>, 0
|
|
849
864
|
end
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
865
|
+
rescue LoadError
|
|
866
|
+
# not all Ruby implementations have objspace
|
|
867
|
+
end
|
|
854
868
|
end
|
|
@@ -150,28 +150,31 @@ class TestSocketHelper < Test::Unit::TestCase
|
|
|
150
150
|
end
|
|
151
151
|
|
|
152
152
|
def test_tcp_defer_accept_default
|
|
153
|
+
return unless defined?(TCP_DEFER_ACCEPT)
|
|
153
154
|
port = unused_port @test_addr
|
|
154
155
|
name = "#@test_addr:#{port}"
|
|
155
156
|
sock = bind_listen(name)
|
|
156
157
|
cur = sock.getsockopt(Socket::SOL_TCP, TCP_DEFER_ACCEPT).unpack('i')[0]
|
|
157
158
|
assert cur >= 1
|
|
158
|
-
end
|
|
159
|
+
end
|
|
159
160
|
|
|
160
161
|
def test_tcp_defer_accept_disable
|
|
162
|
+
return unless defined?(TCP_DEFER_ACCEPT)
|
|
161
163
|
port = unused_port @test_addr
|
|
162
164
|
name = "#@test_addr:#{port}"
|
|
163
165
|
sock = bind_listen(name, :tcp_defer_accept => false)
|
|
164
166
|
cur = sock.getsockopt(Socket::SOL_TCP, TCP_DEFER_ACCEPT).unpack('i')[0]
|
|
165
167
|
assert_equal 0, cur
|
|
166
|
-
end
|
|
168
|
+
end
|
|
167
169
|
|
|
168
170
|
def test_tcp_defer_accept_nr
|
|
171
|
+
return unless defined?(TCP_DEFER_ACCEPT)
|
|
169
172
|
port = unused_port @test_addr
|
|
170
173
|
name = "#@test_addr:#{port}"
|
|
171
174
|
sock = bind_listen(name, :tcp_defer_accept => 60)
|
|
172
175
|
cur = sock.getsockopt(Socket::SOL_TCP, TCP_DEFER_ACCEPT).unpack('i')[0]
|
|
173
176
|
assert cur > 1
|
|
174
|
-
end
|
|
177
|
+
end
|
|
175
178
|
|
|
176
179
|
def test_ipv6only
|
|
177
180
|
port = begin
|
|
@@ -186,6 +189,7 @@ class TestSocketHelper < Test::Unit::TestCase
|
|
|
186
189
|
end
|
|
187
190
|
|
|
188
191
|
def test_reuseport
|
|
192
|
+
return unless defined?(Socket::SO_REUSEPORT)
|
|
189
193
|
port = unused_port @test_addr
|
|
190
194
|
name = "#@test_addr:#{port}"
|
|
191
195
|
sock = bind_listen(name, :reuseport => true)
|
|
@@ -193,5 +197,5 @@ class TestSocketHelper < Test::Unit::TestCase
|
|
|
193
197
|
assert_operator cur, :>, 0
|
|
194
198
|
rescue Errno::ENOPROTOOPT
|
|
195
199
|
# kernel does not support SO_REUSEPORT (older Linux)
|
|
196
|
-
end
|
|
200
|
+
end
|
|
197
201
|
end
|
data/test/unit/test_util.rb
CHANGED
|
@@ -69,7 +69,7 @@ class TestUtil < Test::Unit::TestCase
|
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
tmp.close!
|
|
72
|
-
end
|
|
72
|
+
end
|
|
73
73
|
|
|
74
74
|
def test_reopen_logs_renamed_with_internal_encoding
|
|
75
75
|
tmp = Tempfile.new('')
|
|
@@ -101,5 +101,5 @@ class TestUtil < Test::Unit::TestCase
|
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
103
|
tmp.close!
|
|
104
|
-
end
|
|
104
|
+
end
|
|
105
105
|
end
|
data/unicorn.gemspec
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
# -*- encoding: binary -*-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
require 'olddoc'
|
|
5
|
-
extend Olddoc::Gemspec
|
|
6
|
-
name, summary, title = readme_metadata
|
|
2
|
+
manifest = File.exist?('.manifest') ?
|
|
3
|
+
IO.readlines('.manifest').map!(&:chomp!) : `git ls-files`.split("\n")
|
|
7
4
|
|
|
8
5
|
# don't bother with tests that fork, not worth our time to get working
|
|
9
6
|
# with `gem check -t` ... (of course we care for them when testing with
|
|
@@ -14,16 +11,18 @@ end.compact
|
|
|
14
11
|
|
|
15
12
|
Gem::Specification.new do |s|
|
|
16
13
|
s.name = %q{unicorn}
|
|
17
|
-
s.version = ENV[
|
|
18
|
-
s.authors = [
|
|
19
|
-
s.summary =
|
|
20
|
-
s.description =
|
|
14
|
+
s.version = (ENV['VERSION'] || '5.3.1').dup
|
|
15
|
+
s.authors = ['unicorn hackers']
|
|
16
|
+
s.summary = 'Rack HTTP server for fast clients and Unix'
|
|
17
|
+
s.description = File.read('README').split("\n\n")[1]
|
|
21
18
|
s.email = %q{unicorn-public@bogomips.org}
|
|
22
19
|
s.executables = %w(unicorn unicorn_rails)
|
|
23
20
|
s.extensions = %w(ext/unicorn_http/extconf.rb)
|
|
24
|
-
s.extra_rdoc_files =
|
|
21
|
+
s.extra_rdoc_files = IO.readlines('.document').map!(&:chomp!).keep_if do |f|
|
|
22
|
+
File.exist?(f)
|
|
23
|
+
end
|
|
25
24
|
s.files = manifest
|
|
26
|
-
s.homepage =
|
|
25
|
+
s.homepage = 'https://bogomips.org/unicorn/'
|
|
27
26
|
s.test_files = test_files
|
|
28
27
|
|
|
29
28
|
# technically we need ">= 1.9.3", too, but avoid the array here since
|
|
@@ -31,16 +30,15 @@ Gem::Specification.new do |s|
|
|
|
31
30
|
# version requirements here.
|
|
32
31
|
s.required_ruby_version = '< 3.0'
|
|
33
32
|
|
|
34
|
-
#
|
|
35
|
-
#
|
|
36
|
-
#
|
|
37
|
-
|
|
38
|
-
|
|
33
|
+
# We do not have a hard dependency on rack, it's possible to load
|
|
34
|
+
# things which respond to #call. HTTP status lines in responses
|
|
35
|
+
# won't have descriptive text, only the numeric status.
|
|
36
|
+
s.add_development_dependency(%q<rack>)
|
|
37
|
+
|
|
39
38
|
s.add_dependency(%q<kgio>, '~> 2.6')
|
|
40
39
|
s.add_dependency(%q<raindrops>, '~> 0.7')
|
|
41
40
|
|
|
42
41
|
s.add_development_dependency('test-unit', '~> 3.0')
|
|
43
|
-
s.add_development_dependency('olddoc', '~> 1.0')
|
|
44
42
|
|
|
45
43
|
# Note: To avoid ambiguity, we intentionally avoid the SPDX-compatible
|
|
46
44
|
# 'Ruby' here since Ruby 1.9.3 switched to BSD-2-Clause, but we
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: unicorn
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 5.
|
|
4
|
+
version: 5.3.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- unicorn hackers
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2017-10-03 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rack
|
|
@@ -17,7 +17,7 @@ dependencies:
|
|
|
17
17
|
- - ">="
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
19
|
version: '0'
|
|
20
|
-
type: :
|
|
20
|
+
type: :development
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
@@ -66,20 +66,6 @@ dependencies:
|
|
|
66
66
|
- - "~>"
|
|
67
67
|
- !ruby/object:Gem::Version
|
|
68
68
|
version: '3.0'
|
|
69
|
-
- !ruby/object:Gem::Dependency
|
|
70
|
-
name: olddoc
|
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
|
72
|
-
requirements:
|
|
73
|
-
- - "~>"
|
|
74
|
-
- !ruby/object:Gem::Version
|
|
75
|
-
version: '1.0'
|
|
76
|
-
type: :development
|
|
77
|
-
prerelease: false
|
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
-
requirements:
|
|
80
|
-
- - "~>"
|
|
81
|
-
- !ruby/object:Gem::Version
|
|
82
|
-
version: '1.0'
|
|
83
69
|
description: |-
|
|
84
70
|
unicorn is an HTTP server for Rack applications designed to only serve
|
|
85
71
|
fast clients on low-latency, high-bandwidth connections and take
|
|
@@ -264,6 +250,7 @@ files:
|
|
|
264
250
|
- test/exec/README
|
|
265
251
|
- test/exec/test_exec.rb
|
|
266
252
|
- test/test_helper.rb
|
|
253
|
+
- test/unit/test_ccc.rb
|
|
267
254
|
- test/unit/test_configurator.rb
|
|
268
255
|
- test/unit/test_droplet.rb
|
|
269
256
|
- test/unit/test_http_parser.rb
|
|
@@ -280,7 +267,7 @@ files:
|
|
|
280
267
|
- unicorn.gemspec
|
|
281
268
|
- unicorn_1
|
|
282
269
|
- unicorn_rails_1
|
|
283
|
-
homepage:
|
|
270
|
+
homepage: https://bogomips.org/unicorn/
|
|
284
271
|
licenses:
|
|
285
272
|
- GPL-2.0+
|
|
286
273
|
- Ruby-1.8
|
|
@@ -301,7 +288,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
301
288
|
version: '0'
|
|
302
289
|
requirements: []
|
|
303
290
|
rubyforge_project:
|
|
304
|
-
rubygems_version: 2.
|
|
291
|
+
rubygems_version: 2.6.13
|
|
305
292
|
signing_key:
|
|
306
293
|
specification_version: 4
|
|
307
294
|
summary: Rack HTTP server for fast clients and Unix
|