unicorn 4.9.0 → 6.0.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.
Files changed (95) hide show
  1. checksums.yaml +5 -5
  2. data/.gitattributes +5 -0
  3. data/.olddoc.yml +13 -6
  4. data/Application_Timeouts +7 -7
  5. data/DESIGN +2 -4
  6. data/Documentation/.gitignore +1 -3
  7. data/Documentation/unicorn.1 +222 -0
  8. data/Documentation/unicorn_rails.1 +207 -0
  9. data/FAQ +17 -8
  10. data/GIT-VERSION-GEN +1 -1
  11. data/GNUmakefile +121 -56
  12. data/HACKING +1 -2
  13. data/ISSUES +40 -41
  14. data/KNOWN_ISSUES +11 -11
  15. data/LICENSE +2 -2
  16. data/Links +24 -25
  17. data/PHILOSOPHY +0 -6
  18. data/README +46 -39
  19. data/SIGNALS +2 -2
  20. data/Sandbox +10 -9
  21. data/TODO +0 -2
  22. data/TUNING +30 -9
  23. data/archive/slrnpull.conf +1 -1
  24. data/bin/unicorn +4 -2
  25. data/bin/unicorn_rails +3 -3
  26. data/examples/big_app_gc.rb +1 -1
  27. data/examples/init.sh +36 -8
  28. data/examples/logrotate.conf +17 -2
  29. data/examples/nginx.conf +14 -14
  30. data/examples/unicorn.conf.minimal.rb +2 -2
  31. data/examples/unicorn.conf.rb +3 -6
  32. data/examples/unicorn.socket +11 -0
  33. data/examples/unicorn@.service +40 -0
  34. data/ext/unicorn_http/common_field_optimization.h +23 -5
  35. data/ext/unicorn_http/ext_help.h +0 -20
  36. data/ext/unicorn_http/extconf.rb +37 -1
  37. data/ext/unicorn_http/global_variables.h +1 -1
  38. data/ext/unicorn_http/httpdate.c +2 -2
  39. data/ext/unicorn_http/unicorn_http.rl +167 -170
  40. data/ext/unicorn_http/unicorn_http_common.rl +1 -1
  41. data/lib/unicorn.rb +66 -46
  42. data/lib/unicorn/configurator.rb +110 -44
  43. data/lib/unicorn/const.rb +2 -25
  44. data/lib/unicorn/http_request.rb +110 -31
  45. data/lib/unicorn/http_response.rb +17 -31
  46. data/lib/unicorn/http_server.rb +238 -157
  47. data/lib/unicorn/launcher.rb +1 -1
  48. data/lib/unicorn/oob_gc.rb +6 -6
  49. data/lib/unicorn/socket_helper.rb +58 -78
  50. data/lib/unicorn/stream_input.rb +8 -7
  51. data/lib/unicorn/tee_input.rb +8 -10
  52. data/lib/unicorn/tmpio.rb +8 -7
  53. data/lib/unicorn/util.rb +5 -4
  54. data/lib/unicorn/worker.rb +36 -23
  55. data/t/GNUmakefile +3 -72
  56. data/t/README +4 -4
  57. data/t/t0011-active-unix-socket.sh +1 -1
  58. data/t/t0012-reload-empty-config.sh +2 -1
  59. data/t/t0301-no-default-middleware-ignored-in-config.sh +25 -0
  60. data/t/t0301.ru +13 -0
  61. data/t/test-lib.sh +2 -2
  62. data/test/benchmark/README +14 -4
  63. data/test/benchmark/ddstream.ru +50 -0
  64. data/test/benchmark/readinput.ru +40 -0
  65. data/test/benchmark/uconnect.perl +66 -0
  66. data/test/exec/test_exec.rb +73 -19
  67. data/test/test_helper.rb +40 -31
  68. data/test/unit/test_ccc.rb +91 -0
  69. data/test/unit/test_droplet.rb +1 -1
  70. data/test/unit/test_http_parser.rb +46 -16
  71. data/test/unit/test_http_parser_ng.rb +97 -114
  72. data/test/unit/test_request.rb +10 -10
  73. data/test/unit/test_response.rb +28 -16
  74. data/test/unit/test_server.rb +86 -12
  75. data/test/unit/test_signals.rb +8 -8
  76. data/test/unit/test_socket_helper.rb +14 -10
  77. data/test/unit/test_upload.rb +9 -14
  78. data/test/unit/test_util.rb +27 -2
  79. data/unicorn.gemspec +27 -19
  80. metadata +24 -45
  81. data/Documentation/GNUmakefile +0 -30
  82. data/Documentation/unicorn.1.txt +0 -185
  83. data/Documentation/unicorn_rails.1.txt +0 -175
  84. data/examples/git.ru +0 -13
  85. data/lib/unicorn/app/exec_cgi.rb +0 -154
  86. data/lib/unicorn/app/inetd.rb +0 -109
  87. data/lib/unicorn/ssl_client.rb +0 -11
  88. data/lib/unicorn/ssl_configurator.rb +0 -104
  89. data/lib/unicorn/ssl_server.rb +0 -42
  90. data/t/hijack.ru +0 -42
  91. data/t/t0016-trust-x-forwarded-false.sh +0 -30
  92. data/t/t0017-trust-x-forwarded-true.sh +0 -30
  93. data/t/t0200-rack-hijack.sh +0 -27
  94. data/test/unit/test_http_parser_xftrust.rb +0 -38
  95. data/test/unit/test_sni_hostnames.rb +0 -47
@@ -4,7 +4,7 @@
4
4
 
5
5
  #### HTTP PROTOCOL GRAMMAR
6
6
  # line endings
7
- CRLF = "\r\n";
7
+   CRLF = ("\r\n" | "\n");
8
8
 
9
9
  # character types
10
10
  CTL = (cntrl | 127);
data/lib/unicorn.rb CHANGED
@@ -1,9 +1,15 @@
1
1
  # -*- encoding: binary -*-
2
- require 'fcntl'
3
2
  require 'etc'
4
3
  require 'stringio'
5
- require 'rack'
6
4
  require 'kgio'
5
+ require 'raindrops'
6
+ require 'io/wait'
7
+
8
+ begin
9
+ require 'rack'
10
+ rescue LoadError
11
+ warn 'rack not available, functionality reduced'
12
+ end
7
13
 
8
14
  # :stopdoc:
9
15
  # Unicorn module containing all of the classes (include C extensions) for
@@ -11,19 +17,20 @@
11
17
  # enough functionality to service web application requests fast as possible.
12
18
  # :startdoc:
13
19
 
14
- # \Unicorn exposes very little of an user-visible API and most of its
15
- # internals are subject to change. \Unicorn is designed to host Rack
20
+ # unicorn exposes very little of an user-visible API and most of its
21
+ # internals are subject to change. unicorn is designed to host Rack
16
22
  # applications, so applications should be written against the Rack SPEC
17
- # and not \Unicorn internals.
23
+ # and not unicorn internals.
18
24
  module Unicorn
19
25
 
20
26
  # Raised inside TeeInput when a client closes the socket inside the
21
27
  # application dispatch. This is always raised with an empty backtrace
22
28
  # since there is nothing in the application stack that is responsible
23
29
  # for client shutdowns/disconnects. This exception is visible to Rack
24
- # applications unless PrereadInput middleware is loaded.
25
- class ClientShutdown < EOFError
26
- end
30
+ # applications unless PrereadInput middleware is loaded. This
31
+ # is a subclass of the standard EOFError class and applications should
32
+ # not rescue it explicitly, but rescue EOFError instead.
33
+ ClientShutdown = Class.new(EOFError)
27
34
 
28
35
  # :stopdoc:
29
36
 
@@ -34,13 +41,12 @@ class ClientShutdown < EOFError
34
41
  def self.builder(ru, op)
35
42
  # allow Configurator to parse cli switches embedded in the ru file
36
43
  op = Unicorn::Configurator::RACKUP.merge!(:file => ru, :optparse => op)
37
-
38
- # Op is going to get cleared before the returned lambda is called, so
39
- # save this value so that it's still there when we need it:
40
- no_default_middleware = op[:no_default_middleware]
44
+ if ru =~ /\.ru$/ && !defined?(Rack::Builder)
45
+ abort "rack and Rack::Builder must be available for processing #{ru}"
46
+ end
41
47
 
42
48
  # always called after config file parsing, may be called after forking
43
- lambda do ||
49
+ lambda do |_, server|
44
50
  inner_app = case ru
45
51
  when /\.ru$/
46
52
  raw = File.read(ru)
@@ -51,9 +57,21 @@ def self.builder(ru, op)
51
57
  Object.const_get(File.basename(ru, '.rb').capitalize)
52
58
  end
53
59
 
54
- pp({ :inner_app => inner_app }) if $DEBUG
60
+ if $DEBUG
61
+ require 'pp'
62
+ pp({ :inner_app => inner_app })
63
+ end
64
+
65
+ return inner_app unless server.default_middleware
55
66
 
56
- return inner_app if no_default_middleware
67
+ middleware = { # order matters
68
+ ContentLength: nil,
69
+ Chunked: nil,
70
+ CommonLogger: [ $stderr ],
71
+ ShowExceptions: nil,
72
+ Lint: nil,
73
+ TempfileReaper: nil,
74
+ }
57
75
 
58
76
  # return value, matches rackup defaults based on env
59
77
  # Unicorn does not support persistent connections, but Rainbows!
@@ -61,32 +79,24 @@ def self.builder(ru, op)
61
79
  # middlewares will need ContentLength/Chunked middlewares.
62
80
  case ENV["RACK_ENV"]
63
81
  when "development"
64
- Rack::Builder.new do
65
- use Rack::ContentLength
66
- use Rack::Chunked
67
- use Rack::CommonLogger, $stderr
68
- use Rack::ShowExceptions
69
- use Rack::Lint
70
- use Rack::TempfileReaper if Rack.const_defined?(:TempfileReaper)
71
- run inner_app
72
- end.to_app
73
82
  when "deployment"
74
- Rack::Builder.new do
75
- use Rack::ContentLength
76
- use Rack::Chunked
77
- use Rack::CommonLogger, $stderr
78
- use Rack::TempfileReaper if Rack.const_defined?(:TempfileReaper)
79
- run inner_app
80
- end.to_app
83
+ middleware.delete(:ShowExceptions)
84
+ middleware.delete(:Lint)
81
85
  else
82
- inner_app
86
+ return inner_app
83
87
  end
88
+ Rack::Builder.new do
89
+ middleware.each do |m, args|
90
+ use(Rack.const_get(m), *args) if Rack.const_defined?(m)
91
+ end
92
+ run inner_app
93
+ end.to_app
84
94
  end
85
95
  end
86
96
 
87
97
  # returns an array of strings representing TCP listen socket addresses
88
98
  # and Unix domain socket paths. This is useful for use with
89
- # Raindrops::Middleware under Linux: http://raindrops.bogomips.org/
99
+ # Raindrops::Middleware under Linux: https://yhbt.net/raindrops/
90
100
  def self.listener_names
91
101
  Unicorn::HttpServer::LISTENERS.map do |io|
92
102
  Unicorn::SocketHelper.sock_name(io)
@@ -100,21 +110,31 @@ def self.log_error(logger, prefix, exc)
100
110
  exc.backtrace.each { |line| logger.error(line) }
101
111
  end
102
112
 
103
- # remove this when we only support Ruby >= 2.0
113
+ F_SETPIPE_SZ = 1031 if RUBY_PLATFORM =~ /linux/
114
+
104
115
  def self.pipe # :nodoc:
105
- Kgio::Pipe.new.each { |io| io.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) }
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
+ rescue Errno::EPERM
127
+ # resizes fail if Linux is close to the pipe limit for the user
128
+ # or if the user does not have permissions to resize
129
+ end
130
+ end
131
+ end
106
132
  end
107
133
  # :startdoc:
108
134
  end
109
135
  # :enddoc:
110
- require 'unicorn/const'
111
- require 'unicorn/socket_helper'
112
- require 'unicorn/stream_input'
113
- require 'unicorn/tee_input'
114
- require 'unicorn/http_request'
115
- require 'unicorn/configurator'
116
- require 'unicorn/tmpio'
117
- require 'unicorn/util'
118
- require 'unicorn/http_response'
119
- require 'unicorn/worker'
120
- require 'unicorn/http_server'
136
+
137
+ %w(const socket_helper stream_input tee_input http_request configurator
138
+ tmpio util http_response worker http_server).each do |s|
139
+ require_relative "unicorn/#{s}"
140
+ end
@@ -1,19 +1,17 @@
1
1
  # -*- encoding: binary -*-
2
2
  require 'logger'
3
- require 'unicorn/ssl_configurator'
4
3
 
5
- # Implements a simple DSL for configuring a \Unicorn server.
4
+ # Implements a simple DSL for configuring a unicorn server.
6
5
  #
7
- # See http://unicorn.bogomips.org/examples/unicorn.conf.rb and
8
- # http://unicorn.bogomips.org/examples/unicorn.conf.minimal.rb
6
+ # See https://yhbt.net/unicorn/examples/unicorn.conf.rb and
7
+ # https://yhbt.net/unicorn/examples/unicorn.conf.minimal.rb
9
8
  # example configuration files. An example config file for use with
10
9
  # nginx is also available at
11
- # http://unicorn.bogomips.org/examples/nginx.conf
10
+ # https://yhbt.net/unicorn/examples/nginx.conf
12
11
  #
13
12
  # See the link:/TUNING.html document for more information on tuning unicorn.
14
13
  class Unicorn::Configurator
15
14
  include Unicorn
16
- include Unicorn::SSLConfigurator
17
15
 
18
16
  # :stopdoc:
19
17
  attr_accessor :set, :config_file, :after_reload
@@ -43,12 +41,24 @@ class Unicorn::Configurator
43
41
  :before_exec => lambda { |server|
44
42
  server.logger.info("forked child re-executing...")
45
43
  },
44
+ :after_worker_exit => lambda { |server, worker, status|
45
+ m = "reaped #{status.inspect} worker=#{worker.nr rescue 'unknown'}"
46
+ if status.success?
47
+ server.logger.info(m)
48
+ else
49
+ server.logger.error(m)
50
+ end
51
+ },
52
+ :after_worker_ready => lambda { |server, worker|
53
+ server.logger.info("worker=#{worker.nr} ready")
54
+ },
46
55
  :pid => nil,
56
+ :early_hints => false,
57
+ :worker_exec => false,
47
58
  :preload_app => false,
48
59
  :check_client_connection => false,
49
- :rewindable_input => true, # for Rack 2.x: (Rack::VERSION[0] <= 1),
60
+ :rewindable_input => true,
50
61
  :client_body_buffer_size => Unicorn::Const::MAX_BODY,
51
- :trust_x_forwarded => true,
52
62
  }
53
63
  #:startdoc:
54
64
 
@@ -79,6 +89,9 @@ def reload(merge_defaults = true) #:nodoc:
79
89
  RACKUP[:set_listener] and
80
90
  set[:listeners] << "#{RACKUP[:host]}:#{RACKUP[:port]}"
81
91
 
92
+ RACKUP[:no_default_middleware] and
93
+ set[:default_middleware] = false
94
+
82
95
  # unicorn_rails creates dirs here after working_directory is bound
83
96
  after_reload.call if after_reload
84
97
 
@@ -154,6 +167,38 @@ def after_fork(*args, &block)
154
167
  set_hook(:after_fork, block_given? ? block : args[0])
155
168
  end
156
169
 
170
+ # sets after_worker_exit hook to a given block. This block will be called
171
+ # by the master process after a worker exits:
172
+ #
173
+ # after_worker_exit do |server,worker,status|
174
+ # # status is a Process::Status instance for the exited worker process
175
+ # unless status.success?
176
+ # server.logger.error("worker process failure: #{status.inspect}")
177
+ # end
178
+ # end
179
+ #
180
+ # after_worker_exit is only available in unicorn 5.3.0+
181
+ def after_worker_exit(*args, &block)
182
+ set_hook(:after_worker_exit, block_given? ? block : args[0], 3)
183
+ end
184
+
185
+ # sets after_worker_ready hook to a given block. This block will be called
186
+ # by a worker process after it has been fully loaded, directly before it
187
+ # starts responding to requests:
188
+ #
189
+ # after_worker_ready do |server,worker|
190
+ # server.logger.info("worker #{worker.nr} ready, dropping privileges")
191
+ # worker.user('username', 'groupname')
192
+ # end
193
+ #
194
+ # Do not use Configurator#user if you rely on changing users in the
195
+ # after_worker_ready hook.
196
+ #
197
+ # after_worker_ready is only available in unicorn 5.3.0+
198
+ def after_worker_ready(*args, &block)
199
+ set_hook(:after_worker_ready, block_given? ? block : args[0])
200
+ end
201
+
157
202
  # sets before_fork got be a given Proc object. This Proc
158
203
  # object will be called by the master process before forking
159
204
  # each worker.
@@ -184,8 +229,6 @@ def before_exec(*args, &block)
184
229
  # to have nginx always retry backends that may have had workers
185
230
  # SIGKILL-ed due to timeouts.
186
231
  #
187
- # # See http://wiki.nginx.org/NginxHttpUpstreamModule for more details
188
- # # on nginx upstream configuration:
189
232
  # upstream unicorn_backend {
190
233
  # # for UNIX domain socket setups:
191
234
  # server unix:/path/to/.unicorn.sock fail_timeout=0;
@@ -195,6 +238,9 @@ def before_exec(*args, &block)
195
238
  # server 192.168.0.8:8080 fail_timeout=0;
196
239
  # server 192.168.0.9:8080 fail_timeout=0;
197
240
  # }
241
+ #
242
+ # See https://nginx.org/en/docs/http/ngx_http_upstream_module.html
243
+ # for more details on nginx upstream configuration.
198
244
  def timeout(seconds)
199
245
  set_int(:timeout, seconds, 3)
200
246
  # POSIX says 31 days is the smallest allowed maximum timeout for select()
@@ -202,6 +248,17 @@ def timeout(seconds)
202
248
  set[:timeout] = seconds > max ? max : seconds
203
249
  end
204
250
 
251
+ # Whether to exec in each worker process after forking. This changes the
252
+ # memory layout of each worker process, which is a security feature designed
253
+ # to defeat possible address space discovery attacks. Note that using
254
+ # worker_exec only makes sense if you are not preloading the application,
255
+ # and will result in higher memory usage.
256
+ #
257
+ # worker_exec is only available in unicorn 5.3.0+
258
+ def worker_exec(bool)
259
+ set_bool(:worker_exec, bool)
260
+ end
261
+
205
262
  # sets the current number of worker_processes to +nr+. Each worker
206
263
  # process will serve exactly one client at a time. You can
207
264
  # increment or decrement this value at runtime by sending SIGTTIN
@@ -212,6 +269,23 @@ def worker_processes(nr)
212
269
  set_int(:worker_processes, nr, 1)
213
270
  end
214
271
 
272
+ # sets whether to add default middleware in the development and
273
+ # deployment RACK_ENVs.
274
+ #
275
+ # default_middleware is only available in unicorn 5.5.0+
276
+ def default_middleware(bool)
277
+ set_bool(:default_middleware, bool)
278
+ end
279
+
280
+ # sets whether to enable the proposed early hints Rack API.
281
+ # If enabled, Rails 5.2+ will automatically send a 103 Early Hint
282
+ # for all the `javascript_include_tag` and `stylesheet_link_tag`
283
+ # in your response. See: https://api.rubyonrails.org/v5.2/classes/ActionDispatch/Request.html#method-i-send_early_hints
284
+ # See also https://tools.ietf.org/html/rfc8297
285
+ def early_hints(bool)
286
+ set_bool(:early_hints, bool)
287
+ end
288
+
215
289
  # sets listeners to the given +addresses+, replacing or augmenting the
216
290
  # current set. This is for the global listener pool shared by all
217
291
  # worker processes. For per-worker listeners, see the after_fork example
@@ -257,6 +331,11 @@ def listeners(addresses) # :nodoc:
257
331
  #
258
332
  # Default: 1024
259
333
  #
334
+ # Note: with the Linux kernel, the net.core.somaxconn sysctl defaults
335
+ # to 128, capping this value to 128. Raising the sysctl allows a
336
+ # larger backlog (which may not be desirable with multiple,
337
+ # load-balanced machines).
338
+ #
260
339
  # [:rcvbuf => bytes, :sndbuf => bytes]
261
340
  #
262
341
  # Maximum receive and send buffer sizes (in bytes) of sockets.
@@ -280,20 +359,19 @@ def listeners(addresses) # :nodoc:
280
359
  # Setting this to +true+ can make streaming responses in Rails 3.1
281
360
  # appear more quickly at the cost of slightly higher bandwidth usage.
282
361
  # The effect of this option is most visible if nginx is not used,
283
- # but nginx remains highly recommended with \Unicorn.
362
+ # but nginx remains highly recommended with unicorn.
284
363
  #
285
364
  # This has no effect on UNIX sockets.
286
365
  #
287
- # Default: +true+ (Nagle's algorithm disabled) in \Unicorn,
288
- # +true+ in Rainbows! This defaulted to +false+ in \Unicorn
289
- # 3.x
366
+ # Default: +true+ (Nagle's algorithm disabled) in unicorn
367
+ # This defaulted to +false+ in unicorn 3.x
290
368
  #
291
369
  # [:tcp_nopush => true or false]
292
370
  #
293
371
  # Enables/disables TCP_CORK in Linux or TCP_NOPUSH in FreeBSD
294
372
  #
295
373
  # This prevents partial TCP frames from being sent out and reduces
296
- # wakeups in nginx if it is on a different machine. Since \Unicorn
374
+ # wakeups in nginx if it is on a different machine. Since unicorn
297
375
  # is only designed for applications that send the response body
298
376
  # quickly without keepalive, sockets will always be flushed on close
299
377
  # to prevent delays.
@@ -301,7 +379,7 @@ def listeners(addresses) # :nodoc:
301
379
  # This has no effect on UNIX sockets.
302
380
  #
303
381
  # Default: +false+
304
- # This defaulted to +true+ in \Unicorn 3.4 - 3.7
382
+ # This defaulted to +true+ in unicorn 3.4 - 3.7
305
383
  #
306
384
  # [:ipv6only => true or false]
307
385
  #
@@ -385,12 +463,10 @@ def listeners(addresses) # :nodoc:
385
463
  # and +false+ or +nil+ is synonymous for a value of zero.
386
464
  #
387
465
  # A value of +1+ is a good optimization for local networks
388
- # and trusted clients. For Rainbows! and Zbatery users, a higher
389
- # value (e.g. +60+) provides more protection against some
390
- # denial-of-service attacks. There is no good reason to ever
391
- # disable this with a +zero+ value when serving HTTP.
466
+ # and trusted clients. There is no good reason to ever
467
+ # disable this with a +zero+ value with unicorn.
392
468
  #
393
- # Default: 1 retransmit for \Unicorn, 60 for Rainbows! 0.95.0\+
469
+ # Default: 1
394
470
  #
395
471
  # [:accept_filter => String]
396
472
  #
@@ -399,8 +475,7 @@ def listeners(addresses) # :nodoc:
399
475
  # This enables either the "dataready" or (default) "httpready"
400
476
  # accept() filter under FreeBSD. This is intended as an
401
477
  # optimization to reduce context switches with common GET/HEAD
402
- # requests. For Rainbows! and Zbatery users, this provides
403
- # some protection against certain denial-of-service attacks, too.
478
+ # requests.
404
479
  #
405
480
  # There is no good reason to change from the default.
406
481
  #
@@ -467,13 +542,12 @@ def preload_app(bool)
467
542
  # Disabling rewindability can improve performance by lowering
468
543
  # I/O and memory usage for applications that accept uploads.
469
544
  # Keep in mind that the Rack 1.x spec requires
470
- # \env[\"rack.input\"] to be rewindable, so this allows
471
- # intentionally violating the current Rack 1.x spec.
545
+ # \env[\"rack.input\"] to be rewindable,
546
+ # but the Rack 2.x spec does not.
472
547
  #
473
- # +rewindable_input+ defaults to +true+ when used with Rack 1.x for
474
- # Rack conformance. When Rack 2.x is finalized, this will most
475
- # likely default to +false+ while still conforming to the newer
476
- # (less demanding) spec.
548
+ # +rewindable_input+ defaults to +true+ for compatibility.
549
+ # Setting it to +false+ may be safe for applications and
550
+ # frameworks developed for Rack 2.x and later.
477
551
  def rewindable_input(bool)
478
552
  set_bool(:rewindable_input, bool)
479
553
  end
@@ -534,7 +608,7 @@ def working_directory(path)
534
608
  # just let chdir raise errors
535
609
  path = File.expand_path(path)
536
610
  if config_file &&
537
- config_file[0] != ?/ &&
611
+ ! config_file.start_with?('/') &&
538
612
  ! File.readable?("#{path}/#{config_file}")
539
613
  raise ArgumentError,
540
614
  "config_file=#{config_file} would not be accessible in" \
@@ -549,6 +623,10 @@ def working_directory(path)
549
623
  # This switch will occur after calling the after_fork hook, and only
550
624
  # if the Worker#user method is not called in the after_fork hook
551
625
  # +group+ is optional and will not change if unspecified.
626
+ #
627
+ # Do not use Configurator#user if you rely on changing users in the
628
+ # after_worker_ready hook. Instead, you need to call Worker#user
629
+ # directly in after_worker_ready.
552
630
  def user(user, group = nil)
553
631
  # raises ArgumentError on invalid user/group
554
632
  Etc.getpwnam(user)
@@ -556,18 +634,6 @@ def user(user, group = nil)
556
634
  set[:user] = [ user, group ]
557
635
  end
558
636
 
559
- # Sets whether or not the parser will trust X-Forwarded-Proto and
560
- # X-Forwarded-SSL headers and set "rack.url_scheme" to "https" accordingly.
561
- # Rainbows!/Zbatery installations facing untrusted clients directly
562
- # should set this to +false+. This is +true+ by default as Unicorn
563
- # is designed to only sit behind trusted nginx proxies.
564
- #
565
- # This has never been publically documented and is subject to removal
566
- # in future releases.
567
- def trust_x_forwarded(bool) # :nodoc:
568
- set_bool(:trust_x_forwarded, bool)
569
- end
570
-
571
637
  # expands "unix:path/to/foo" to a socket relative to the current path
572
638
  # expands pathnames of sockets if relative to "~" or "~username"
573
639
  # expands "*:port and ":port" to "0.0.0.0:port"
@@ -601,7 +667,7 @@ def set_int(var, n, min) #:nodoc:
601
667
  def canonicalize_tcp(addr, port)
602
668
  packed = Socket.pack_sockaddr_in(port, addr)
603
669
  port, addr = Socket.unpack_sockaddr_in(packed)
604
- /:/ =~ addr ? "[#{addr}]:#{port}" : "#{addr}:#{port}"
670
+ addr.include?(':') ? "[#{addr}]:#{port}" : "#{addr}:#{port}"
605
671
  end
606
672
 
607
673
  def set_path(var, path) #:nodoc:
@@ -657,7 +723,7 @@ def parse_rackup_file # :nodoc:
657
723
  raise ArgumentError, "rackup file (#{ru}) not readable"
658
724
 
659
725
  # it could be a .rb file, too, we don't parse those manually
660
- ru =~ /\.ru\z/ or return
726
+ ru.end_with?('.ru') or return
661
727
 
662
728
  /^#\\(.*)/ =~ File.read(ru) or return
663
729
  RACKUP[:optparse].parse!($1.split(/\s+/))