unicorn 4.9.0 → 6.0.0

Sign up to get free protection for your applications and to get access to all the features.
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+/))