unicorn 5.4.1 → 5.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.manifest +7 -3
- data/.olddoc.yml +12 -7
- data/Application_Timeouts +4 -4
- data/Documentation/.gitignore +1 -3
- data/Documentation/unicorn.1 +222 -0
- data/Documentation/unicorn_rails.1 +207 -0
- data/FAQ +1 -1
- data/GIT-VERSION-FILE +1 -1
- data/GIT-VERSION-GEN +1 -1
- data/GNUmakefile +111 -57
- data/HACKING +1 -1
- data/ISSUES +21 -23
- data/KNOWN_ISSUES +2 -2
- data/LATEST +22 -28
- data/LICENSE +2 -2
- data/Links +13 -11
- data/NEWS +65 -0
- data/README +25 -11
- data/SIGNALS +1 -1
- data/Sandbox +4 -4
- data/archive/slrnpull.conf +1 -1
- data/bin/unicorn +3 -1
- data/bin/unicorn_rails +2 -2
- data/examples/big_app_gc.rb +1 -1
- data/examples/logrotate.conf +3 -3
- data/examples/nginx.conf +4 -3
- 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 +24 -6
- data/ext/unicorn_http/extconf.rb +35 -0
- data/ext/unicorn_http/global_variables.h +2 -2
- data/ext/unicorn_http/httpdate.c +2 -2
- data/ext/unicorn_http/unicorn_http.c +257 -224
- data/ext/unicorn_http/unicorn_http.rl +47 -14
- data/lib/unicorn/configurator.rb +25 -4
- data/lib/unicorn/http_request.rb +12 -2
- data/lib/unicorn/http_server.rb +38 -11
- data/lib/unicorn/launcher.rb +1 -1
- data/lib/unicorn/oob_gc.rb +2 -2
- data/lib/unicorn/socket_helper.rb +1 -0
- data/lib/unicorn/tmpio.rb +8 -2
- data/lib/unicorn/util.rb +1 -1
- data/lib/unicorn/version.rb +1 -1
- data/lib/unicorn/worker.rb +16 -2
- data/lib/unicorn.rb +23 -9
- data/man/man1/unicorn.1 +89 -88
- data/man/man1/unicorn_rails.1 +78 -83
- data/t/GNUmakefile +3 -72
- data/t/README +4 -4
- data/t/t0301-no-default-middleware-ignored-in-config.sh +25 -0
- data/t/t0301.ru +13 -0
- data/test/benchmark/README +14 -4
- data/test/benchmark/ddstream.ru +50 -0
- data/test/benchmark/readinput.ru +40 -0
- data/test/benchmark/uconnect.perl +66 -0
- data/test/exec/test_exec.rb +9 -7
- data/test/test_helper.rb +22 -30
- data/test/unit/test_http_parser.rb +16 -0
- data/test/unit/test_http_parser_ng.rb +81 -0
- data/test/unit/test_server.rb +30 -0
- data/test/unit/test_upload.rb +4 -9
- data/test/unit/test_util.rb +25 -0
- data/unicorn.gemspec +8 -7
- metadata +15 -11
- data/Documentation/GNUmakefile +0 -30
- data/Documentation/unicorn.1.txt +0 -187
- data/Documentation/unicorn_rails.1.txt +0 -175
data/SIGNALS
CHANGED
@@ -8,7 +8,7 @@ should be possible to easily share process management scripts between
|
|
8
8
|
Unicorn and nginx.
|
9
9
|
|
10
10
|
One example init script is distributed with unicorn:
|
11
|
-
https://
|
11
|
+
https://yhbt.net/unicorn/examples/init.sh
|
12
12
|
|
13
13
|
=== Master Process
|
14
14
|
|
data/Sandbox
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
Since unicorn includes executables and is usually used to start a Ruby
|
4
4
|
process, there are certain caveats to using it with tools that sandbox
|
5
5
|
RubyGems installations such as
|
6
|
-
{Bundler}[
|
6
|
+
{Bundler}[https://bundler.io/] or
|
7
7
|
{Isolate}[https://github.com/jbarnette/isolate].
|
8
8
|
|
9
9
|
== General deployment
|
@@ -34,7 +34,7 @@ is the primary issue with sandboxing tools such as Bundler and Isolate.
|
|
34
34
|
If you're bundling unicorn, use "bundle exec unicorn" (or "bundle exec
|
35
35
|
unicorn_rails") to start unicorn with the correct environment variables
|
36
36
|
|
37
|
-
ref: https://
|
37
|
+
ref: https://yhbt.net/unicorn-public/9ECF07C4-5216-47BE-961D-AFC0F0C82060@internetfamo.us/
|
38
38
|
|
39
39
|
Otherwise (if you choose to not sandbox your unicorn installation), we
|
40
40
|
expect the tips for Isolate (below) apply, too.
|
@@ -44,7 +44,7 @@ expect the tips for Isolate (below) apply, too.
|
|
44
44
|
This is no longer be an issue as of bundler 0.9.17
|
45
45
|
|
46
46
|
ref:
|
47
|
-
https://
|
47
|
+
https://yhbt.net/unicorn-public/8FC34B23-5994-41CC-B5AF-7198EF06909E@tramchase.com/
|
48
48
|
|
49
49
|
=== BUNDLE_GEMFILE for Capistrano users
|
50
50
|
|
@@ -66,7 +66,7 @@ before_exec hook as illustrated by https://gist.github.com/534668
|
|
66
66
|
Ruby 2.0.0 enforces FD_CLOEXEC on file descriptors by default. unicorn
|
67
67
|
has been prepared for this behavior since unicorn 4.1.0, and bundler
|
68
68
|
needs the "--keep-file-descriptors" option for "bundle exec":
|
69
|
-
|
69
|
+
https://bundler.io/man/bundle-exec.1.html
|
70
70
|
|
71
71
|
== Isolate
|
72
72
|
|
data/archive/slrnpull.conf
CHANGED
data/bin/unicorn
CHANGED
@@ -6,6 +6,7 @@ require 'optparse'
|
|
6
6
|
ENV["RACK_ENV"] ||= "development"
|
7
7
|
rackup_opts = Unicorn::Configurator::RACKUP
|
8
8
|
options = rackup_opts[:options]
|
9
|
+
set_no_default_middleware = true
|
9
10
|
|
10
11
|
op = OptionParser.new("", 24, ' ') do |opts|
|
11
12
|
cmd = File.basename($0)
|
@@ -60,7 +61,7 @@ op = OptionParser.new("", 24, ' ') do |opts|
|
|
60
61
|
|
61
62
|
opts.on("-N", "--no-default-middleware",
|
62
63
|
"do not load middleware implied by RACK_ENV") do |e|
|
63
|
-
rackup_opts[:no_default_middleware] = true
|
64
|
+
rackup_opts[:no_default_middleware] = true if set_no_default_middleware
|
64
65
|
end
|
65
66
|
|
66
67
|
opts.on("-D", "--daemonize", "run daemonized in the background") do |d|
|
@@ -110,6 +111,7 @@ op = OptionParser.new("", 24, ' ') do |opts|
|
|
110
111
|
opts.parse! ARGV
|
111
112
|
end
|
112
113
|
|
114
|
+
set_no_default_middleware = false
|
113
115
|
app = Unicorn.builder(ARGV[0] || 'config.ru', op)
|
114
116
|
op = nil
|
115
117
|
|
data/bin/unicorn_rails
CHANGED
@@ -132,11 +132,11 @@ def rails_builder(ru, op, daemonize)
|
|
132
132
|
|
133
133
|
# this lambda won't run until after forking if preload_app is false
|
134
134
|
# this runs after config file reloading
|
135
|
-
lambda do
|
135
|
+
lambda do |x, server|
|
136
136
|
# Rails 3 includes a config.ru, use it if we find it after
|
137
137
|
# working_directory is bound.
|
138
138
|
::File.exist?('config.ru') and
|
139
|
-
return Unicorn.builder('config.ru', op).call
|
139
|
+
return Unicorn.builder('config.ru', op).call(x, server)
|
140
140
|
|
141
141
|
# Load Rails and (possibly) the private version of Rack it bundles.
|
142
142
|
begin
|
data/examples/big_app_gc.rb
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
# see {Unicorn::OobGC}[https://
|
1
|
+
# see {Unicorn::OobGC}[https://yhbt.net/unicorn/Unicorn/OobGC.html]
|
2
2
|
# Unicorn::OobGC was broken in Unicorn v3.3.1 - v3.6.1 and fixed in v3.6.2
|
data/examples/logrotate.conf
CHANGED
@@ -2,10 +2,10 @@
|
|
2
2
|
# /etc/logrotate.d/unicorn_app on my Debian systems
|
3
3
|
#
|
4
4
|
# See the logrotate(8) manpage for more information:
|
5
|
-
#
|
5
|
+
# https://linux.die.net/man/8/logrotate
|
6
6
|
#
|
7
7
|
# public logrotate-related discussion in our archives:
|
8
|
-
# https://
|
8
|
+
# https://yhbt.net/unicorn-public/?q=logrotate
|
9
9
|
|
10
10
|
# Modify the following glob to match the logfiles your app writes to:
|
11
11
|
/var/log/unicorn_app/*.log {
|
@@ -33,7 +33,7 @@
|
|
33
33
|
systemctl kill -s SIGUSR1 unicorn@2.service
|
34
34
|
|
35
35
|
# Examples for other process management systems appreciated
|
36
|
-
# Mail us at unicorn-public@
|
36
|
+
# Mail us at unicorn-public@yhbt.net
|
37
37
|
# (see above for archives)
|
38
38
|
|
39
39
|
# If you use a pid file and assuming your pid file
|
data/examples/nginx.conf
CHANGED
@@ -56,7 +56,8 @@ http {
|
|
56
56
|
# to configure it all in one place here for static files and also
|
57
57
|
# to disable gzip for clients who don't get gzip/deflate right.
|
58
58
|
# There are other gzip settings that may be needed used to deal with
|
59
|
-
# bad clients out there, see
|
59
|
+
# bad clients out there, see
|
60
|
+
# https://nginx.org/en/docs/http/ngx_http_gzip_module.html
|
60
61
|
gzip on;
|
61
62
|
gzip_http_version 1.0;
|
62
63
|
gzip_proxied any;
|
@@ -112,12 +113,12 @@ http {
|
|
112
113
|
# try_files directive appeared in in nginx 0.7.27 and has stabilized
|
113
114
|
# over time. Older versions of nginx (e.g. 0.6.x) requires
|
114
115
|
# "if (!-f $request_filename)" which was less efficient:
|
115
|
-
# https://
|
116
|
+
# https://yhbt.net/unicorn.git/tree/examples/nginx.conf?id=v3.3.1#n127
|
116
117
|
try_files $uri/index.html $uri.html $uri @app;
|
117
118
|
|
118
119
|
location @app {
|
119
120
|
# an HTTP header important enough to have its own Wikipedia entry:
|
120
|
-
#
|
121
|
+
# https://en.wikipedia.org/wiki/X-Forwarded-For
|
121
122
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
122
123
|
|
123
124
|
# enable this if you forward HTTPS traffic to unicorn,
|
@@ -1,9 +1,9 @@
|
|
1
1
|
# Minimal sample configuration file for Unicorn (not Rack) when used
|
2
2
|
# with daemonization (unicorn -D) started in your working directory.
|
3
3
|
#
|
4
|
-
# See https://
|
4
|
+
# See https://yhbt.net/unicorn/Unicorn/Configurator.html for complete
|
5
5
|
# documentation.
|
6
|
-
# See also https://
|
6
|
+
# See also https://yhbt.net/unicorn/examples/unicorn.conf.rb for
|
7
7
|
# a more verbose configuration using more features.
|
8
8
|
|
9
9
|
listen 2007 # by default Unicorn listens on port 8080
|
data/examples/unicorn.conf.rb
CHANGED
@@ -2,10 +2,10 @@
|
|
2
2
|
#
|
3
3
|
# This configuration file documents many features of Unicorn
|
4
4
|
# that may not be needed for some applications. See
|
5
|
-
# https://
|
5
|
+
# https://yhbt.net/unicorn/examples/unicorn.conf.minimal.rb
|
6
6
|
# for a much simpler configuration file.
|
7
7
|
#
|
8
|
-
# See https://
|
8
|
+
# See https://yhbt.net/unicorn/Unicorn/Configurator.html for complete
|
9
9
|
# documentation.
|
10
10
|
|
11
11
|
# Use at least one worker per core if you're on a dedicated server,
|
data/examples/unicorn@.service
CHANGED
@@ -14,7 +14,14 @@ After = unicorn.socket
|
|
14
14
|
# bundler users must use the "--keep-file-descriptors" switch, here:
|
15
15
|
# ExecStart = bundle exec --keep-file-descriptors unicorn -c ...
|
16
16
|
ExecStart = /usr/bin/unicorn -c /path/to/unicorn.conf.rb /path/to/config.ru
|
17
|
+
|
18
|
+
# NonBlocking MUST be true if using socket activation with unicorn.
|
19
|
+
# Otherwise, there's a small window in-between when the non-blocking
|
20
|
+
# flag is set by us and our accept4 call where systemd can momentarily
|
21
|
+
# make the socket blocking, causing us to block on accept4:
|
22
|
+
NonBlocking = true
|
17
23
|
Sockets = unicorn.socket
|
24
|
+
|
18
25
|
KillSignal = SIGQUIT
|
19
26
|
User = nobody
|
20
27
|
Group = nogroup
|
@@ -58,26 +58,44 @@ static struct common_field common_http_fields[] = {
|
|
58
58
|
|
59
59
|
#define HTTP_PREFIX "HTTP_"
|
60
60
|
#define HTTP_PREFIX_LEN (sizeof(HTTP_PREFIX) - 1)
|
61
|
+
static ID id_uminus;
|
62
|
+
|
63
|
+
/* this dedupes under Ruby 2.5+ (December 2017) */
|
64
|
+
static VALUE str_dd_freeze(VALUE str)
|
65
|
+
{
|
66
|
+
if (STR_UMINUS_DEDUPE)
|
67
|
+
return rb_funcall(str, id_uminus, 0);
|
68
|
+
|
69
|
+
/* freeze,since it speeds up older MRI slightly */
|
70
|
+
OBJ_FREEZE(str);
|
71
|
+
return str;
|
72
|
+
}
|
73
|
+
|
74
|
+
static VALUE str_new_dd_freeze(const char *ptr, long len)
|
75
|
+
{
|
76
|
+
return str_dd_freeze(rb_str_new(ptr, len));
|
77
|
+
}
|
61
78
|
|
62
79
|
/* this function is not performance-critical, called only at load time */
|
63
|
-
static void init_common_fields(
|
80
|
+
static void init_common_fields(void)
|
64
81
|
{
|
65
82
|
int i;
|
66
83
|
struct common_field *cf = common_http_fields;
|
67
84
|
char tmp[64];
|
85
|
+
|
86
|
+
id_uminus = rb_intern("-@");
|
68
87
|
memcpy(tmp, HTTP_PREFIX, HTTP_PREFIX_LEN);
|
69
88
|
|
70
89
|
for(i = ARRAY_SIZE(common_http_fields); --i >= 0; cf++) {
|
71
90
|
/* Rack doesn't like certain headers prefixed with "HTTP_" */
|
72
91
|
if (!strcmp("CONTENT_LENGTH", cf->name) ||
|
73
92
|
!strcmp("CONTENT_TYPE", cf->name)) {
|
74
|
-
cf->value =
|
93
|
+
cf->value = str_new_dd_freeze(cf->name, cf->len);
|
75
94
|
} else {
|
76
95
|
memcpy(tmp + HTTP_PREFIX_LEN, cf->name, cf->len + 1);
|
77
|
-
cf->value =
|
96
|
+
cf->value = str_new_dd_freeze(tmp, HTTP_PREFIX_LEN + cf->len);
|
78
97
|
}
|
79
|
-
|
80
|
-
rb_ary_push(mark_ary, cf->value);
|
98
|
+
rb_gc_register_mark_object(cf->value);
|
81
99
|
}
|
82
100
|
}
|
83
101
|
|
@@ -105,7 +123,7 @@ static VALUE uncommon_field(const char *field, size_t flen)
|
|
105
123
|
memcpy(RSTRING_PTR(f) + HTTP_PREFIX_LEN, field, flen);
|
106
124
|
assert(*(RSTRING_PTR(f) + RSTRING_LEN(f)) == '\0' &&
|
107
125
|
"string didn't end with \\0"); /* paranoia */
|
108
|
-
return
|
126
|
+
return HASH_ASET_DEDUPE ? f : str_dd_freeze(f);
|
109
127
|
}
|
110
128
|
|
111
129
|
#endif /* common_field_optimization_h */
|
data/ext/unicorn_http/extconf.rb
CHANGED
@@ -1,6 +1,11 @@
|
|
1
1
|
# -*- encoding: binary -*-
|
2
2
|
require 'mkmf'
|
3
3
|
|
4
|
+
unless RUBY_VERSION < '3.1'
|
5
|
+
warn "Unicorn was only tested against MRI up to 3.0.\n" \
|
6
|
+
"It might not properly work with #{RUBY_VERSION}"
|
7
|
+
end
|
8
|
+
|
4
9
|
have_macro("SIZEOF_OFF_T", "ruby.h") or check_sizeof("off_t", "sys/types.h")
|
5
10
|
have_macro("SIZEOF_SIZE_T", "ruby.h") or check_sizeof("size_t", "sys/types.h")
|
6
11
|
have_macro("SIZEOF_LONG", "ruby.h") or check_sizeof("long", "sys/types.h")
|
@@ -8,4 +13,34 @@ have_func("rb_str_set_len", "ruby.h") or abort 'Ruby 1.9.3+ required'
|
|
8
13
|
have_func("rb_hash_clear", "ruby.h") # Ruby 2.0+
|
9
14
|
have_func("gmtime_r", "time.h")
|
10
15
|
|
16
|
+
message('checking if String#-@ (str_uminus) dedupes... ')
|
17
|
+
begin
|
18
|
+
a = -(%w(t e s t).join)
|
19
|
+
b = -(%w(t e s t).join)
|
20
|
+
if a.equal?(b)
|
21
|
+
$CPPFLAGS += ' -DSTR_UMINUS_DEDUPE=1 '
|
22
|
+
message("yes\n")
|
23
|
+
else
|
24
|
+
$CPPFLAGS += ' -DSTR_UMINUS_DEDUPE=0 '
|
25
|
+
message("no, needs Ruby 2.5+\n")
|
26
|
+
end
|
27
|
+
rescue NoMethodError
|
28
|
+
$CPPFLAGS += ' -DSTR_UMINUS_DEDUPE=0 '
|
29
|
+
message("no, String#-@ not available\n")
|
30
|
+
end
|
31
|
+
|
32
|
+
message('checking if Hash#[]= (rb_hash_aset) dedupes... ')
|
33
|
+
h = {}
|
34
|
+
x = {}
|
35
|
+
r = rand.to_s
|
36
|
+
h[%W(#{r}).join('')] = :foo
|
37
|
+
x[%W(#{r}).join('')] = :foo
|
38
|
+
if x.keys[0].equal?(h.keys[0])
|
39
|
+
$CPPFLAGS += ' -DHASH_ASET_DEDUPE=1 '
|
40
|
+
message("yes\n")
|
41
|
+
else
|
42
|
+
$CPPFLAGS += ' -DHASH_ASET_DEDUPE=0 '
|
43
|
+
message("no, needs Ruby 2.6+\n")
|
44
|
+
end
|
45
|
+
|
11
46
|
create_makefile("unicorn_http")
|
@@ -56,7 +56,7 @@ NORETURN(static void parser_raise(VALUE klass, const char *));
|
|
56
56
|
/** Defines global strings in the init method. */
|
57
57
|
#define DEF_GLOBAL(N, val) do { \
|
58
58
|
g_##N = rb_obj_freeze(rb_str_new(val, sizeof(val) - 1)); \
|
59
|
-
|
59
|
+
rb_gc_register_mark_object(g_##N); \
|
60
60
|
} while (0)
|
61
61
|
|
62
62
|
/* Defines the maximum allowed lengths for various input elements.*/
|
@@ -67,7 +67,7 @@ DEF_MAX_LENGTH(FRAGMENT, 1024); /* Don't know if this length is specified somewh
|
|
67
67
|
DEF_MAX_LENGTH(REQUEST_PATH, 4096); /* common PATH_MAX on modern systems */
|
68
68
|
DEF_MAX_LENGTH(QUERY_STRING, (1024 * 10));
|
69
69
|
|
70
|
-
static void init_globals(
|
70
|
+
static void init_globals(void)
|
71
71
|
{
|
72
72
|
DEF_GLOBAL(rack_url_scheme, "rack.url_scheme");
|
73
73
|
DEF_GLOBAL(request_method, "REQUEST_METHOD");
|
data/ext/unicorn_http/httpdate.c
CHANGED
@@ -64,13 +64,13 @@ static VALUE httpdate(VALUE self)
|
|
64
64
|
return buf;
|
65
65
|
}
|
66
66
|
|
67
|
-
void init_unicorn_httpdate(
|
67
|
+
void init_unicorn_httpdate(void)
|
68
68
|
{
|
69
69
|
VALUE mod = rb_define_module("Unicorn");
|
70
70
|
mod = rb_define_module_under(mod, "HttpResponse");
|
71
71
|
|
72
72
|
buf = rb_str_new(0, buf_capa - 1);
|
73
|
-
|
73
|
+
rb_gc_register_mark_object(buf);
|
74
74
|
buf_ptr = RSTRING_PTR(buf);
|
75
75
|
httpdate(Qnil);
|
76
76
|
|