unicorn 5.4.1 → 5.5.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5e12c8bfe14a84877de48727dd053f35d815c68e35e62aa9db57fb1bdc520d22
4
- data.tar.gz: 9e74449cbf6adf07b27f6745829e794a11c29537917c6a8e7cd31fd59669625f
3
+ metadata.gz: fd24ac80ee80caf33952ba3633987a9ea419ca59258ddf7324772f54a065e637
4
+ data.tar.gz: 9e61596b998976ca1394c4d54692723dfee281e9f0f37c52fa93361a90e454ee
5
5
  SHA512:
6
- metadata.gz: 643c4edec67b12b5fd6d0708e26b169e68ead4332d862b84aa3fc0319fec2f2e3d6a1822ee8b74d7570b5ce42cda9705aba5ac18a1ab1987a018f270d86b8994
7
- data.tar.gz: bbc7ab165c6d9a4a8bd2e23a3740029c8653d09a0573bec41d4cfbdcbfcfce27de88859d608c06e0aabb76ffcb015924b54b276b731875554f593a399810bd58
6
+ metadata.gz: 17e84b1b9471644d292afb786b869578a3e7c78a1a02bd0fcdbf4b704412b10587c06b2eeae1c826d9ef02e33189309ec22033737d27b27a15383455aa29285f
7
+ data.tar.gz: 0e00360d347d0cdb2918c20a4ee7afc5164845881296917e1234d4befd94b2cb68a6ec5440587b6c3aad9a10814675a5d5b228ffb4774d9ad153c012e9a53ba3
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  cgit_url: https://bogomips.org/unicorn.git
3
- git_url: git://bogomips.org/unicorn.git
3
+ git_url: https://bogomips.org/unicorn.git
4
4
  rdoc_url: https://bogomips.org/unicorn/
5
5
  ml_url: https://bogomips.org/unicorn-public/
6
6
  merge_html:
@@ -23,10 +23,10 @@ Most database adapters allow configurable timeouts.
23
23
  Net::HTTP and Net::SMTP in the Ruby standard library allow
24
24
  configurable timeouts.
25
25
 
26
- Even for things as fast as {memcached}[http://memcached.org/],
27
- {dalli}[http://rubygems.org/gems/dalli],
28
- {memcached}[http://rubygems.org/gems/memcached] and
29
- {memcache-client}[http://rubygems.org/gems/memcache-client] RubyGems all
26
+ Even for things as fast as {memcached}[https://memcached.org/],
27
+ {dalli}[https://rubygems.org/gems/dalli],
28
+ {memcached}[https://rubygems.org/gems/memcached] and
29
+ {memcache-client}[https://rubygems.org/gems/memcache-client] RubyGems all
30
30
  offer configurable timeouts.
31
31
 
32
32
  Consult the relevant documentation for the libraries you use on
@@ -182,6 +182,6 @@ the unicorn config file.
182
182
  * [Rackup HowTo][3]
183
183
 
184
184
  [1]: https://bogomips.org/unicorn/
185
- [2]: http://www.rubydoc.info/github/rack/rack/
185
+ [2]: https://www.rubydoc.info/github/rack/rack/
186
186
  [3]: https://github.com/rack/rack/wiki/tutorial-rackup-howto
187
187
  [4]: https://bogomips.org/unicorn/SIGNALS.html
@@ -170,6 +170,6 @@ used by Unicorn.
170
170
  * [Rackup HowTo][3]
171
171
 
172
172
  [1]: https://bogomips.org/unicorn/
173
- [2]: http://www.rubydoc.info/github/rack/rack/
173
+ [2]: https://www.rubydoc.info/github/rack/rack/
174
174
  [3]: https://github.com/rack/rack/wiki/tutorial-rackup-howto
175
175
  [4]: https://bogomips.org/unicorn/SIGNALS.html
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
- DEF_VER = "v5.4.1"
2
+ DEF_VER = "v5.5.0.pre1"
3
3
  CONSTANT = "Unicorn::Const::UNICORN_VERSION"
4
4
  RVF = "lib/unicorn/version.rb"
5
5
  GVF = "GIT-VERSION-FILE"
data/ISSUES CHANGED
@@ -39,6 +39,7 @@ https://bugs.ruby-lang.org/ and discuss+fix them on the ruby-core
39
39
  list at mailto:ruby-core@ruby-lang.org
40
40
  Subscription to post is required to ruby-core, unfortunately:
41
41
  mailto:ruby-core-request@ruby-lang.org?subject=subscribe
42
+ Unofficial archives are available at: https://public-inbox.org/ruby-core/
42
43
 
43
44
  For uncommon bugs in Rack, we may forward bugs to
44
45
  mailto:rack-devel@googlegroups.com and discuss there.
@@ -46,6 +47,7 @@ Subscription (without any web UI or Google account) is possible via:
46
47
  mailto:rack-devel+subscribe@googlegroups.com
47
48
  Note: not everyone can use the proprietary bug tracker used by Rack,
48
49
  but their mailing list remains operational.
50
+ Unofficial archives are available at: https://public-inbox.org/rack-devel/
49
51
 
50
52
  Uncommon bugs we encounter in the Linux kernel should be Cc:-ed to the
51
53
  Linux kernel mailing list (LKML) at mailto:linux-kernel@vger.kernel.org
@@ -54,11 +56,12 @@ and subsystem maintainers such as mailto:netdev@vger.kernel.org
54
56
  involved with any problematic commits (including those in the
55
57
  Signed-off-by: and other trailer lines). No subscription is necessary,
56
58
  and the our mailing list follows the same conventions as LKML for
57
- interopability. There is a kernel.org Bugzilla instance, but it is
58
- ignored by most developers.
59
+ interopability. Archives are available at https://lore.kernel.org/lkml/
60
+ There is a kernel.org Bugzilla instance, but it is ignored by most.
59
61
 
60
62
  Likewise for any rare glibc bugs we might encounter, we should Cc:
61
63
  mailto:libc-alpha@sourceware.org
64
+ Unofficial archives are available at: https://public-inbox.org/libc-alpha/
62
65
  Keep in mind glibc upstream does use Bugzilla for tracking bugs:
63
66
  https://sourceware.org/bugzilla/
64
67
 
data/LICENSE CHANGED
@@ -8,8 +8,8 @@ any later version. We currently prefer the GPLv3 or later for
8
8
  derivative works, but the GPLv2 is fine.
9
9
 
10
10
  The complete texts of the GPLv2 and GPLv3 are below:
11
- GPLv2 - http://www.gnu.org/licenses/gpl-2.0.txt
12
- GPLv3 - http://www.gnu.org/licenses/gpl-3.0.txt
11
+ GPLv2 - https://www.gnu.org/licenses/gpl-2.0.txt
12
+ GPLv3 - https://www.gnu.org/licenses/gpl-3.0.txt
13
13
 
14
14
  You may (against our _preference_) also use the Ruby 1.8 license terms
15
15
  which we inherited from the original Mongrel project when we forked it:
data/Links CHANGED
@@ -10,7 +10,7 @@ The unicorn project is not responsible for the content in these links.
10
10
  Furthermore, the unicorn project has never, does not and will never endorse:
11
11
 
12
12
  * any for-profit entities or services
13
- * any non-{Free Software}[http://www.gnu.org/philosophy/free-sw.html]
13
+ * any non-{Free Software}[https://www.gnu.org/philosophy/free-sw.html]
14
14
 
15
15
  The existence of these links does not imply endorsement of any entities
16
16
  or services behind them.
@@ -31,25 +31,25 @@ or services behind them.
31
31
 
32
32
  === unicorn is written to work with
33
33
 
34
- * {Rack}[http://rack.github.io/] - a minimal interface between webservers
34
+ * {Rack}[https://rack.github.io/] - a minimal interface between webservers
35
35
  supporting Ruby and Ruby frameworks
36
36
 
37
37
  * {Ruby}[https://www.ruby-lang.org/en/] - the programming language of
38
38
  Rack and unicorn
39
39
 
40
- * {nginx}[http://nginx.org/] (Free versions) -
40
+ * {nginx}[https://nginx.org/] (Free versions) -
41
41
  the reverse proxy for use with unicorn
42
42
 
43
43
  === Derivatives
44
44
 
45
- * {Green Unicorn}[http://gunicorn.org/] - a Python version of unicorn
45
+ * {Green Unicorn}[https://gunicorn.org/] - a Python version of unicorn
46
46
 
47
- * {Starman}[http://search.cpan.org/dist/Starman/] - Plack/PSGI version
47
+ * {Starman}[https://metacpan.org/release/Starman/] - Plack/PSGI version
48
48
  of unicorn
49
49
 
50
50
  === Prior Work
51
51
 
52
- * {Mongrel}[http://rubygems.org/gems/mongrel] - the awesome webserver
52
+ * {Mongrel}[https://rubygems.org/gems/mongrel] - the awesome webserver
53
53
  unicorn is based on
54
54
 
55
55
  * {david}[https://bogomips.org/david.git] - a tool to explain why you need
data/README CHANGED
@@ -10,7 +10,7 @@ both the the request and response in between unicorn and slow clients.
10
10
 
11
11
  * Designed for Rack, Unix, fast clients, and ease-of-debugging. We
12
12
  cut out everything that is better supported by the operating system,
13
- {nginx}[http://nginx.org/] or {Rack}[http://rack.github.io/].
13
+ {nginx}[https://nginx.org/] or {Rack}[https://rack.github.io/].
14
14
 
15
15
  * Compatible with Ruby 1.9.3 and later.
16
16
  unicorn 4.x remains supported for Ruby 1.8 users.
@@ -37,12 +37,15 @@ both the the request and response in between unicorn and slow clients.
37
37
  You can upgrade unicorn, your entire application, libraries
38
38
  and even your Ruby interpreter without dropping clients.
39
39
 
40
+ * transparent upgrades using systemd socket activation is
41
+ supported since unicorn 5.0
42
+
40
43
  * before_fork and after_fork hooks in case your application
41
44
  has special needs when dealing with forked processes. These
42
45
  should not be needed when the "preload_app" directive is
43
46
  false (the default).
44
47
 
45
- * Can be used with copy-on-write-friendly memory management
48
+ * Can be used with copy-on-write-friendly GC in Ruby 2.0+
46
49
  to save memory (by setting "preload_app" to true).
47
50
 
48
51
  * Able to listen on multiple interfaces including UNIX sockets,
@@ -55,7 +58,7 @@ both the the request and response in between unicorn and slow clients.
55
58
 
56
59
  == License
57
60
 
58
- unicorn is copyright 2009-2016 by all contributors (see logs in git).
61
+ unicorn is copyright 2009-2018 by all contributors (see logs in git).
59
62
  It is based on Mongrel 1.1.5.
60
63
  Mongrel is copyright 2007 Zed A. Shaw and contributors.
61
64
 
@@ -77,13 +80,13 @@ You may install it via RubyGems on RubyGems.org:
77
80
  You can get the latest source via git from the following locations
78
81
  (these versions may not be stable):
79
82
 
80
- git://bogomips.org/unicorn.git
81
- git://repo.or.cz/unicorn.git (mirror)
83
+ https://bogomips.org/unicorn.git
84
+ https://repo.or.cz/unicorn.git (mirror)
82
85
 
83
86
  You may browse the code from the web:
84
87
 
85
88
  * https://bogomips.org/unicorn.git
86
- * http://repo.or.cz/w/unicorn.git (gitweb)
89
+ * https://repo.or.cz/w/unicorn.git (gitweb)
87
90
 
88
91
  See the HACKING guide on how to contribute and build prerelease gems
89
92
  from git.
@@ -122,6 +125,10 @@ unicorn is designed to only serve fast clients either on the local host
122
125
  or a fast LAN. See the PHILOSOPHY and DESIGN documents for more details
123
126
  regarding this.
124
127
 
128
+ Due to its ability to tolerate crashes and isolate clients, unicorn
129
+ is unfortunately known to prolong the existence of bugs in applications
130
+ and libraries which run on top of it.
131
+
125
132
  == Contact
126
133
 
127
134
  All feedback (bug reports, user/development dicussion, patches, pull
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}[http://bundler.io/] or
6
+ {Bundler}[https://bundler.io/] or
7
7
  {Isolate}[https://github.com/jbarnette/isolate].
8
8
 
9
9
  == General deployment
@@ -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
- http://bundler.io/man/bundle-exec.1.html
69
+ https://bundler.io/man/bundle-exec.1.html
70
70
 
71
71
  == Isolate
72
72
 
@@ -6,6 +6,7 @@
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 @@
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 @@
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
 
@@ -2,7 +2,7 @@
2
2
  # /etc/logrotate.d/unicorn_app on my Debian systems
3
3
  #
4
4
  # See the logrotate(8) manpage for more information:
5
- # http://linux.die.net/man/8/logrotate
5
+ # https://linux.die.net/man/8/logrotate
6
6
  #
7
7
  # public logrotate-related discussion in our archives:
8
8
  # https://bogomips.org/unicorn-public/?q=logrotate
@@ -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 http://wiki.nginx.org/NginxHttpGzipModule
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;
@@ -117,7 +118,7 @@ http {
117
118
 
118
119
  location @app {
119
120
  # an HTTP header important enough to have its own Wikipedia entry:
120
- # http://en.wikipedia.org/wiki/X-Forwarded-For
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,
@@ -58,6 +58,23 @@ 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
80
  static void init_common_fields(VALUE mark_ary)
@@ -65,18 +82,19 @@ static void init_common_fields(VALUE mark_ary)
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 = rb_str_new(cf->name, cf->len);
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 = rb_str_new(tmp, HTTP_PREFIX_LEN + cf->len);
96
+ cf->value = str_new_dd_freeze(tmp, HTTP_PREFIX_LEN + cf->len);
78
97
  }
79
- cf->value = rb_obj_freeze(cf->value);
80
98
  rb_ary_push(mark_ary, cf->value);
81
99
  }
82
100
  }
@@ -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 rb_obj_freeze(f);
126
+ return HASH_ASET_DEDUPE ? f : str_dd_freeze(f);
109
127
  }
110
128
 
111
129
  #endif /* common_field_optimization_h */
@@ -8,4 +8,34 @@
8
8
  have_func("rb_hash_clear", "ruby.h") # Ruby 2.0+
9
9
  have_func("gmtime_r", "time.h")
10
10
 
11
+ message('checking if String#-@ (str_uminus) dedupes... ')
12
+ begin
13
+ a = -(%w(t e s t).join)
14
+ b = -(%w(t e s t).join)
15
+ if a.equal?(b)
16
+ $CPPFLAGS += ' -DSTR_UMINUS_DEDUPE=1 '
17
+ message("yes\n")
18
+ else
19
+ $CPPFLAGS += ' -DSTR_UMINUS_DEDUPE=0 '
20
+ message("no, needs Ruby 2.5+\n")
21
+ end
22
+ rescue NoMethodError
23
+ $CPPFLAGS += ' -DSTR_UMINUS_DEDUPE=0 '
24
+ message("no, String#-@ not available\n")
25
+ end
26
+
27
+ message('checking if Hash#[]= (rb_hash_aset) dedupes... ')
28
+ h = {}
29
+ x = {}
30
+ r = rand.to_s
31
+ h[%W(#{r}).join('')] = :foo
32
+ x[%W(#{r}).join('')] = :foo
33
+ if x.keys[0].equal?(h.keys[0])
34
+ $CPPFLAGS += ' -DHASH_ASET_DEDUPE=1 '
35
+ message("yes\n")
36
+ else
37
+ $CPPFLAGS += ' -DHASH_ASET_DEDUPE=0 '
38
+ message("no, needs Ruby 2.6+\n")
39
+ end
40
+
11
41
  create_makefile("unicorn_http")
@@ -2,6 +2,8 @@
2
2
  require 'etc'
3
3
  require 'stringio'
4
4
  require 'kgio'
5
+ require 'raindrops'
6
+ require 'io/wait'
5
7
 
6
8
  begin
7
9
  require 'rack'
@@ -43,12 +45,8 @@ def self.builder(ru, op)
43
45
  abort "rack and Rack::Builder must be available for processing #{ru}"
44
46
  end
45
47
 
46
- # Op is going to get cleared before the returned lambda is called, so
47
- # save this value so that it's still there when we need it:
48
- no_default_middleware = op[:no_default_middleware]
49
-
50
48
  # always called after config file parsing, may be called after forking
51
- lambda do ||
49
+ lambda do |_, server|
52
50
  inner_app = case ru
53
51
  when /\.ru$/
54
52
  raw = File.read(ru)
@@ -64,7 +62,7 @@ def self.builder(ru, op)
64
62
  pp({ :inner_app => inner_app })
65
63
  end
66
64
 
67
- return inner_app if no_default_middleware
65
+ return inner_app unless server.default_middleware
68
66
 
69
67
  middleware = { # order matters
70
68
  ContentLength: nil,
@@ -112,9 +110,22 @@ def self.log_error(logger, prefix, exc)
112
110
  exc.backtrace.each { |line| logger.error(line) }
113
111
  end
114
112
 
115
- # remove this when we only support Ruby >= 2.0
113
+ F_SETPIPE_SZ = 1031 if RUBY_PLATFORM =~ /linux/
114
+
116
115
  def self.pipe # :nodoc:
117
- Kgio::Pipe.new.each { |io| io.close_on_exec = true }
116
+ Kgio::Pipe.new.each do |io|
117
+ io.close_on_exec = true # remove this when we only support Ruby >= 2.0
118
+
119
+ # shrink pipes to minimize impact on /proc/sys/fs/pipe-user-pages-soft
120
+ # limits.
121
+ if defined?(F_SETPIPE_SZ)
122
+ begin
123
+ io.fcntl(F_SETPIPE_SZ, Raindrops::PAGE_SIZE)
124
+ rescue Errno::EINVAL
125
+ # old kernel
126
+ end
127
+ end
128
+ end
118
129
  end
119
130
  # :startdoc:
120
131
  end
@@ -88,6 +88,9 @@ def reload(merge_defaults = true) #:nodoc:
88
88
  RACKUP[:set_listener] and
89
89
  set[:listeners] << "#{RACKUP[:host]}:#{RACKUP[:port]}"
90
90
 
91
+ RACKUP[:no_default_middleware] and
92
+ set[:default_middleware] = false
93
+
91
94
  # unicorn_rails creates dirs here after working_directory is bound
92
95
  after_reload.call if after_reload
93
96
 
@@ -235,7 +238,7 @@ def before_exec(*args, &block)
235
238
  # server 192.168.0.9:8080 fail_timeout=0;
236
239
  # }
237
240
  #
238
- # See http://nginx.org/en/docs/http/ngx_http_upstream_module.html
241
+ # See https://nginx.org/en/docs/http/ngx_http_upstream_module.html
239
242
  # for more details on nginx upstream configuration.
240
243
  def timeout(seconds)
241
244
  set_int(:timeout, seconds, 3)
@@ -265,6 +268,14 @@ def worker_processes(nr)
265
268
  set_int(:worker_processes, nr, 1)
266
269
  end
267
270
 
271
+ # sets whether to add default middleware in the development and
272
+ # deployment RACK_ENVs.
273
+ #
274
+ # default_middleware is only available in unicorn 5.5.0+
275
+ def default_middleware(bool)
276
+ set_bool(:default_middleware, bool)
277
+ end
278
+
268
279
  # sets listeners to the given +addresses+, replacing or augmenting the
269
280
  # current set. This is for the global listener pool shared by all
270
281
  # worker processes. For per-worker listeners, see the after_fork example
@@ -2,7 +2,6 @@
2
2
  # :enddoc:
3
3
  # no stable API here
4
4
  require 'unicorn_http'
5
- require 'raindrops'
6
5
 
7
6
  # TODO: remove redundant names
8
7
  Unicorn.const_set(:HttpRequest, Unicorn::HttpParser)
@@ -66,7 +65,7 @@ def read(socket)
66
65
  clear
67
66
  e = env
68
67
 
69
- # From http://www.ietf.org/rfc/rfc3875:
68
+ # From https://www.ietf.org/rfc/rfc3875:
70
69
  # "Script authors should be aware that the REMOTE_ADDR and
71
70
  # REMOTE_HOST meta-variables (see sections 4.1.8 and 4.1.9)
72
71
  # may not identify the ultimate source of the request. They
@@ -14,7 +14,8 @@ class Unicorn::HttpServer
14
14
  attr_accessor :app, :timeout, :worker_processes,
15
15
  :before_fork, :after_fork, :before_exec,
16
16
  :listener_opts, :preload_app,
17
- :orig_app, :config, :ready_pipe, :user
17
+ :orig_app, :config, :ready_pipe, :user,
18
+ :default_middleware
18
19
  attr_writer :after_worker_exit, :after_worker_ready, :worker_exec
19
20
 
20
21
  attr_reader :pid, :logger
@@ -70,6 +71,7 @@ def initialize(app, options = {})
70
71
  @app = app
71
72
  @request = Unicorn::HttpRequest.new
72
73
  @reexec_pid = 0
74
+ @default_middleware = true
73
75
  options = options.dup
74
76
  @ready_pipe = options.delete(:ready_pipe)
75
77
  @init_listeners = options[:listeners] ? options[:listeners].dup : []
@@ -82,7 +84,7 @@ def initialize(app, options = {})
82
84
  # * The master process never closes or reinitializes this once
83
85
  # initialized. Signal handlers in the master process will write to
84
86
  # it to wake up the master from IO.select in exactly the same manner
85
- # djb describes in http://cr.yp.to/docs/selfpipe.html
87
+ # djb describes in https://cr.yp.to/docs/selfpipe.html
86
88
  #
87
89
  # * The workers immediately close the pipe they inherit. See the
88
90
  # Unicorn::Worker class for the pipe workers use.
@@ -380,7 +382,7 @@ def check_client_connection=(bool)
380
382
 
381
383
  # wait for a signal hander to wake us up and then consume the pipe
382
384
  def master_sleep(sec)
383
- @self_pipe[0].kgio_wait_readable(sec) or return
385
+ @self_pipe[0].wait(sec) or return
384
386
  # 11 bytes is the maximum string length which can be embedded within
385
387
  # the Ruby itself and not require a separate malloc (on 32-bit MRI 1.9+).
386
388
  # Most reads are only one byte here and uncommon, so it's not worth a
@@ -520,9 +522,6 @@ def after_fork_internal
520
522
  Unicorn::Configurator::RACKUP.clear
521
523
  @ready_pipe = @init_listeners = @before_exec = @before_fork = nil
522
524
 
523
- # http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/36450
524
- srand # remove in unicorn 6
525
-
526
525
  # The OpenSSL PRNG is seeded with only the pid, and apps with frequently
527
526
  # dying workers can recycle pids
528
527
  OpenSSL::Random.seed(rand.to_s) if defined?(OpenSSL::Random)
@@ -787,12 +786,12 @@ def listener_names(listeners = LISTENERS)
787
786
  end
788
787
 
789
788
  def build_app!
790
- if app.respond_to?(:arity) && app.arity == 0
789
+ if app.respond_to?(:arity) && (app.arity == 0 || app.arity == 2)
791
790
  if defined?(Gem) && Gem.respond_to?(:refresh)
792
791
  logger.info "Refreshing Gem list"
793
792
  Gem.refresh
794
793
  end
795
- self.app = app.call
794
+ self.app = app.arity == 0 ? app.call : app.call(nil, self)
796
795
  end
797
796
  end
798
797
 
@@ -31,7 +31,7 @@ def self.daemonize!(options)
31
31
  # \_ parent - exits immediately ASAP
32
32
  # \_ unicorn master - writes to pipe when ready
33
33
 
34
- rd, wr = IO.pipe
34
+ rd, wr = Unicorn.pipe
35
35
  grandparent = $$
36
36
  if fork
37
37
  wr.close # grandparent does not write
@@ -83,6 +83,7 @@ def set_tcp_sockopt(sock, opt)
83
83
  rescue => e
84
84
  logger.error("#{sock_name(sock)} " \
85
85
  "failed to set accept_filter=#{name} (#{e.inspect})")
86
+ logger.error("perhaps accf_http(9) needs to be loaded".freeze)
86
87
  end if arg != got
87
88
  end
88
89
  end
@@ -64,7 +64,7 @@ def self.reopen_logs
64
64
  fp.reopen(fp.path, "a")
65
65
  else
66
66
  # We should not need this workaround, Ruby can be fixed:
67
- # http://bugs.ruby-lang.org/issues/9036
67
+ # https://bugs.ruby-lang.org/issues/9036
68
68
  # MRI will not call call fclose(3) or freopen(3) here
69
69
  # since there's no associated std{in,out,err} FILE * pointer
70
70
  # This should atomically use dup3(2) (or dup2(2)) syscall
@@ -122,6 +122,11 @@ def close # :nodoc:
122
122
  # the +after_fork+ hook after any privileged functions need to be
123
123
  # run (e.g. to set per-worker CPU affinity, niceness, etc)
124
124
  #
125
+ # +group+ can be specified as a string, or as an array of two
126
+ # strings. If an array of two strings is given, the first string
127
+ # is used as the primary group of the process, and the second is
128
+ # used as the group of the log files.
129
+ #
125
130
  # Any and all errors raised within this method will be propagated
126
131
  # directly back to the caller (usually the +after_fork+ hook.
127
132
  # These errors commonly include ArgumentError for specifying an
@@ -134,8 +139,17 @@ def user(user, group = nil, chroot = false)
134
139
  # insufficient because modern systems have fine-grained
135
140
  # capabilities. Let the caller handle any and all errors.
136
141
  uid = Etc.getpwnam(user).uid
137
- gid = Etc.getgrnam(group).gid if group
138
- Unicorn::Util.chown_logs(uid, gid)
142
+
143
+ if group
144
+ if group.is_a?(Array)
145
+ group, log_group = group
146
+ log_gid = Etc.getgrnam(log_group).gid
147
+ end
148
+ gid = Etc.getgrnam(group).gid
149
+ log_gid ||= gid
150
+ end
151
+
152
+ Unicorn::Util.chown_logs(uid, log_gid)
139
153
  if gid && Process.egid != gid
140
154
  Process.initgroups(user, gid)
141
155
  Process::GID.change_privilege(gid)
data/t/README CHANGED
@@ -10,17 +10,17 @@ comfortable writing integration tests with.
10
10
 
11
11
  == Requirements
12
12
 
13
- * {Ruby 1.9.3+}[https://www.ruby-lang.org/] (duh!)
14
- * {GNU make}[http://www.gnu.org/software/make/]
13
+ * {Ruby 1.9.3+}[https://www.ruby-lang.org/en/] (duh!)
14
+ * {GNU make}[https://www.gnu.org/software/make/]
15
15
  * {socat}[http://www.dest-unreach.org/socat/]
16
- * {curl}[http://curl.haxx.se/]
16
+ * {curl}[https://curl.haxx.se/]
17
17
  * standard UNIX shell utilities (Bourne sh, awk, sed, grep, ...)
18
18
 
19
19
  We do not use bashisms or any non-portable, non-POSIX constructs
20
20
  in our shell code. We use the "pipefail" option if available and
21
21
  mainly test with {ksh}[http://kornshell.com/], but occasionally
22
22
  with {dash}[http://gondor.apana.org.au/~herbert/dash/] and
23
- {bash}[http://www.gnu.org/software/bash/], too.
23
+ {bash}[https://www.gnu.org/software/bash/], too.
24
24
 
25
25
  == Running Tests
26
26
 
@@ -0,0 +1,25 @@
1
+ #!/bin/sh
2
+ . ./test-lib.sh
3
+ t_plan 3 "-N / --no-default-middleware option not supported in config.ru"
4
+
5
+ t_begin "setup and start" && {
6
+ unicorn_setup
7
+ RACK_ENV=development unicorn -D -c $unicorn_config t0301.ru
8
+ unicorn_wait_start
9
+ }
10
+
11
+ t_begin "check switches parsed as expected and -N ignored for Rack::Lint" && {
12
+ debug=false
13
+ lint=
14
+ eval "$(curl -sf http://$listen/vars)"
15
+ test x"$debug" = xtrue
16
+ test x"$lint" != x
17
+ test -f "$lint"
18
+ }
19
+
20
+ t_begin "killing succeeds" && {
21
+ kill $unicorn_pid
22
+ check_stderr
23
+ }
24
+
25
+ t_done
@@ -0,0 +1,13 @@
1
+ #\-N --debug
2
+ run(lambda do |env|
3
+ case env['PATH_INFO']
4
+ when '/vars'
5
+ b = "debug=#{$DEBUG.inspect}\n" \
6
+ "lint=#{caller.grep(%r{rack/lint\.rb})[0].split(':')[0]}\n"
7
+ end
8
+ h = {
9
+ 'Content-Length' => b.size.to_s,
10
+ 'Content-Type' => 'text/plain',
11
+ }
12
+ [ 200, h, [ b ] ]
13
+ end)
@@ -865,4 +865,20 @@ def test_memsize
865
865
  rescue LoadError
866
866
  # not all Ruby implementations have objspace
867
867
  end
868
+
869
+ def test_dedupe
870
+ parser = HttpParser.new
871
+ # n.b. String#freeze optimization doesn't work under modern test-unit
872
+ exp = -'HTTP_HOST'
873
+ get = "GET / HTTP/1.1\r\nHost: example.com\r\nHavpbea-fhpxf: true\r\n\r\n"
874
+ assert parser.add_parse(get)
875
+ key = parser.env.keys.detect { |k| k == exp }
876
+ assert_same exp, key
877
+
878
+ if RUBY_VERSION.to_r >= 2.6 # 2.6.0-rc1+
879
+ exp = -'HTTP_HAVPBEA_FHPXF'
880
+ key = parser.env.keys.detect { |k| k == exp }
881
+ assert_same exp, key
882
+ end
883
+ end if RUBY_VERSION.to_r >= 2.5 && RUBY_ENGINE == 'ruby'
868
884
  end
@@ -102,4 +102,29 @@ def test_reopen_logs_renamed_with_internal_encoding
102
102
  }
103
103
  tmp.close!
104
104
  end
105
+
106
+ def test_pipe
107
+ r, w = Unicorn.pipe
108
+ assert r
109
+ assert w
110
+
111
+ return if RUBY_PLATFORM !~ /linux/
112
+
113
+ begin
114
+ f_getpipe_sz = 1032
115
+ IO.pipe do |a, b|
116
+ a_sz = a.fcntl(f_getpipe_sz)
117
+ b_sz = b.fcntl(f_getpipe_sz)
118
+ assert_kind_of Integer, a_sz
119
+ r_sz = r.fcntl(f_getpipe_sz)
120
+ assert_equal Raindrops::PAGE_SIZE, r_sz
121
+ assert_operator a_sz, :>=, r_sz
122
+ end
123
+ rescue Errno::EINVAL
124
+ # Linux <= 2.6.34
125
+ end
126
+ ensure
127
+ w.close
128
+ r.close
129
+ end
105
130
  end
@@ -11,7 +11,7 @@
11
11
 
12
12
  Gem::Specification.new do |s|
13
13
  s.name = %q{unicorn}
14
- s.version = (ENV['VERSION'] || '5.4.1').dup
14
+ s.version = (ENV['VERSION'] || '5.5.0.pre1').dup
15
15
  s.authors = ['unicorn hackers']
16
16
  s.summary = 'Rack HTTP server for fast clients and Unix'
17
17
  s.description = File.read('README').split("\n\n")[1]
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.1
4
+ version: 5.5.0.pre1
5
5
  platform: ruby
6
6
  authors:
7
7
  - unicorn hackers
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-07-23 00:00:00.000000000 Z
11
+ date: 2018-12-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -238,6 +238,8 @@ files:
238
238
  - t/t0116.ru
239
239
  - t/t0200-rack-hijack.sh
240
240
  - t/t0300-no-default-middleware.sh
241
+ - t/t0301-no-default-middleware-ignored-in-config.sh
242
+ - t/t0301.ru
241
243
  - t/t9000-preread-input.sh
242
244
  - t/t9001-oob_gc.sh
243
245
  - t/t9002-oob_gc-path.sh
@@ -283,9 +285,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
283
285
  version: '3.0'
284
286
  required_rubygems_version: !ruby/object:Gem::Requirement
285
287
  requirements:
286
- - - ">="
288
+ - - ">"
287
289
  - !ruby/object:Gem::Version
288
- version: '0'
290
+ version: 1.3.1
289
291
  requirements: []
290
292
  rubyforge_project:
291
293
  rubygems_version: 2.7.7