puma 2.12.3 → 2.16.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of puma might be problematic. Click here for more details.

data/lib/puma/binder.rb CHANGED
@@ -128,6 +128,8 @@ module Puma
128
128
 
129
129
  @listeners << [str, io]
130
130
  when "ssl"
131
+ MiniSSL.check
132
+
131
133
  params = Util.parse_query uri.query
132
134
  require 'puma/minissl'
133
135
 
@@ -162,8 +164,9 @@ module Puma
162
164
  unless params['ca']
163
165
  @events.error "Please specify the SSL ca via 'ca='"
164
166
  end
165
- ctx.ca = params['ca']
166
167
  end
168
+
169
+ ctx.ca = params['ca'] if params['ca']
167
170
 
168
171
  if params['verify_mode']
169
172
  ctx.verify_mode = case params['verify_mode']
@@ -227,7 +230,7 @@ module Puma
227
230
  # allow to accumulate before returning connection refused.
228
231
  #
229
232
  def add_tcp_listener(host, port, optimize_for_latency=true, backlog=1024)
230
- host = host[1..-2] if host[0..0] == '['
233
+ host = host[1..-2] if host and host[0..0] == '['
231
234
  s = TCPServer.new(host, port)
232
235
  if optimize_for_latency
233
236
  s.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
@@ -253,6 +256,8 @@ module Puma
253
256
  optimize_for_latency=true, backlog=1024)
254
257
  require 'puma/minissl'
255
258
 
259
+ MiniSSL.check
260
+
256
261
  host = host[1..-2] if host[0..0] == '['
257
262
  s = TCPServer.new(host, port)
258
263
  if optimize_for_latency
@@ -272,6 +277,8 @@ module Puma
272
277
 
273
278
  def inherited_ssl_listener(fd, ctx)
274
279
  require 'puma/minissl'
280
+ MiniSSL.check
281
+
275
282
  s = TCPServer.for_fd(fd)
276
283
  ssl = MiniSSL::Server.new(s, ctx)
277
284
 
@@ -1,3 +1,5 @@
1
+ $stderr.puts "DEPRECATED: To manage puma with capistrano, use https://github.com/seuros/capistrano-puma"
2
+
1
3
  Capistrano::Configuration.instance.load do
2
4
 
3
5
  # Ensure the tmp/sockets directory is created by the deploy:setup task and
data/lib/puma/cli.rb CHANGED
@@ -25,6 +25,12 @@ module Puma
25
25
  # Handles invoke a Puma::Server in a command line style.
26
26
  #
27
27
  class CLI
28
+ KEYS_NOT_TO_PERSIST_IN_STATE = [
29
+ :logger, :lowlevel_error_handler,
30
+ :before_worker_shutdown, :before_worker_boot, :before_worker_fork,
31
+ :after_worker_boot, :before_fork, :on_restart
32
+ ]
33
+
28
34
  # Create a new CLI object using +argv+ as the command line
29
35
  # arguments.
30
36
  #
@@ -42,8 +48,6 @@ module Puma
42
48
 
43
49
  @config = nil
44
50
 
45
- ENV['NEWRELIC_DISPATCHER'] ||= "Puma"
46
-
47
51
  setup_options
48
52
  generate_restart_data
49
53
 
@@ -96,7 +100,7 @@ module Puma
96
100
  end
97
101
 
98
102
  def env
99
- @options[:environment] || ENV['RACK_ENV'] || 'development'
103
+ @options[:environment] || @cli_options[:environment] || ENV['RACK_ENV'] || 'development'
100
104
  end
101
105
 
102
106
  def write_state
@@ -108,12 +112,7 @@ module Puma
108
112
  state = { 'pid' => Process.pid }
109
113
  cfg = @config.dup
110
114
 
111
- [
112
- :logger,
113
- :before_worker_shutdown, :before_worker_boot, :before_worker_fork,
114
- :after_worker_boot,
115
- :on_restart, :lowlevel_error_handler
116
- ].each { |k| cfg.options.delete(k) }
115
+ KEYS_NOT_TO_PERSIST_IN_STATE.each { |k| cfg.options.delete(k) }
117
116
  state['config'] = cfg
118
117
 
119
118
  require 'yaml'
@@ -266,7 +265,7 @@ module Puma
266
265
  private
267
266
  def title
268
267
  buffer = "puma #{Puma::Const::VERSION} (#{@options[:binds].join(',')})"
269
- buffer << " [#{@options[:tag]}]" if @options[:tag]
268
+ buffer << " [#{@options[:tag]}]" if @options[:tag] && !@options[:tag].empty?
270
269
  buffer
271
270
  end
272
271
 
@@ -289,43 +288,33 @@ module Puma
289
288
  end
290
289
 
291
290
  def find_config
292
- if @options[:config_file] == '-'
293
- @options[:config_file] = nil
291
+ if @cli_options[:config_file] == '-'
292
+ @cli_options[:config_file] = nil
294
293
  else
295
- @options[:config_file] ||= %W(config/puma/#{env}.rb config/puma.rb).find { |f| File.exist?(f) }
294
+ @cli_options[:config_file] ||= %W(config/puma/#{env}.rb config/puma.rb).find { |f| File.exist?(f) }
296
295
  end
297
296
  end
298
297
 
299
298
  # Build the OptionParser object to handle the available options.
300
299
  #
300
+
301
301
  def setup_options
302
- @options = {
303
- :min_threads => 0,
304
- :max_threads => 16,
305
- :quiet => false,
306
- :debug => false,
307
- :binds => [],
308
- :workers => 0,
309
- :daemon => false,
310
- :before_worker_shutdown => [],
311
- :before_worker_boot => [],
312
- :before_worker_fork => [],
313
- :after_worker_boot => []
314
- }
302
+ @cli_options = {}
303
+ @options = {}
315
304
 
316
305
  @parser = OptionParser.new do |o|
317
306
  o.on "-b", "--bind URI", "URI to bind to (tcp://, unix://, ssl://)" do |arg|
318
- @options[:binds] << arg
307
+ (@cli_options[:binds] ||= []) << arg
319
308
  end
320
309
 
321
310
  o.on "-C", "--config PATH", "Load PATH as a config file" do |arg|
322
- @options[:config_file] = arg
311
+ @cli_options[:config_file] = arg
323
312
  end
324
313
 
325
314
  o.on "--control URL", "The bind url to use for the control server",
326
315
  "Use 'auto' to use temp unix server" do |arg|
327
316
  if arg
328
- @options[:control_url] = arg
317
+ @cli_options[:control_url] = arg
329
318
  elsif jruby?
330
319
  unsupported "No default url available on JRuby"
331
320
  end
@@ -333,26 +322,26 @@ module Puma
333
322
 
334
323
  o.on "--control-token TOKEN",
335
324
  "The token to use as authentication for the control server" do |arg|
336
- @options[:control_auth_token] = arg
325
+ @cli_options[:control_auth_token] = arg
337
326
  end
338
327
 
339
328
  o.on "-d", "--daemon", "Daemonize the server into the background" do
340
- @options[:daemon] = true
341
- @options[:quiet] = true
329
+ @cli_options[:daemon] = true
330
+ @cli_options[:quiet] = true
342
331
  end
343
332
 
344
333
  o.on "--debug", "Log lowlevel debugging information" do
345
- @options[:debug] = true
334
+ @cli_options[:debug] = true
346
335
  end
347
336
 
348
337
  o.on "--dir DIR", "Change to DIR before starting" do |d|
349
- @options[:directory] = d.to_s
350
- @options[:worker_directory] = d.to_s
338
+ @cli_options[:directory] = d.to_s
339
+ @cli_options[:worker_directory] = d.to_s
351
340
  end
352
341
 
353
342
  o.on "-e", "--environment ENVIRONMENT",
354
343
  "The environment to run the Rack app on (default development)" do |arg|
355
- @options[:environment] = arg
344
+ @cli_options[:environment] = arg
356
345
  end
357
346
 
358
347
  o.on "-I", "--include PATH", "Specify $LOAD_PATH directories" do |arg|
@@ -361,48 +350,49 @@ module Puma
361
350
 
362
351
  o.on "-p", "--port PORT", "Define the TCP port to bind to",
363
352
  "Use -b for more advanced options" do |arg|
364
- @options[:binds] << "tcp://#{Configuration::DefaultTCPHost}:#{arg}"
353
+ binds = (@cli_options[:binds] ||= [])
354
+ binds << "tcp://#{Configuration::DefaultTCPHost}:#{arg}"
365
355
  end
366
356
 
367
357
  o.on "--pidfile PATH", "Use PATH as a pidfile" do |arg|
368
- @options[:pidfile] = arg
358
+ @cli_options[:pidfile] = arg
369
359
  end
370
360
 
371
361
  o.on "--preload", "Preload the app. Cluster mode only" do
372
- @options[:preload_app] = true
362
+ @cli_options[:preload_app] = true
373
363
  end
374
364
 
375
365
  o.on "--prune-bundler", "Prune out the bundler env if possible" do
376
- @options[:prune_bundler] = true
366
+ @cli_options[:prune_bundler] = true
377
367
  end
378
368
 
379
369
  o.on "-q", "--quiet", "Quiet down the output" do
380
- @options[:quiet] = true
370
+ @cli_options[:quiet] = true
381
371
  end
382
372
 
383
373
  o.on "-R", "--restart-cmd CMD",
384
374
  "The puma command to run during a hot restart",
385
375
  "Default: inferred" do |cmd|
386
- @options[:restart_cmd] = cmd
376
+ @cli_options[:restart_cmd] = cmd
387
377
  end
388
378
 
389
379
  o.on "-S", "--state PATH", "Where to store the state details" do |arg|
390
- @options[:state] = arg
380
+ @cli_options[:state] = arg
391
381
  end
392
382
 
393
383
  o.on '-t', '--threads INT', "min:max threads to use (default 0:16)" do |arg|
394
384
  min, max = arg.split(":")
395
385
  if max
396
- @options[:min_threads] = min
397
- @options[:max_threads] = max
386
+ @cli_options[:min_threads] = min
387
+ @cli_options[:max_threads] = max
398
388
  else
399
- @options[:min_threads] = 0
400
- @options[:max_threads] = arg
389
+ @cli_options[:min_threads] = 0
390
+ @cli_options[:max_threads] = arg
401
391
  end
402
392
  end
403
393
 
404
394
  o.on "--tcp-mode", "Run the app in raw TCP mode instead of HTTP mode" do
405
- @options[:mode] = :tcp
395
+ @cli_options[:mode] = :tcp
406
396
  end
407
397
 
408
398
  o.on "-V", "--version", "Print the version information" do
@@ -412,11 +402,23 @@ module Puma
412
402
 
413
403
  o.on "-w", "--workers COUNT",
414
404
  "Activate cluster mode: How many worker processes to create" do |arg|
415
- @options[:workers] = arg.to_i
405
+ @cli_options[:workers] = arg.to_i
416
406
  end
417
407
 
418
408
  o.on "--tag NAME", "Additional text to display in process listing" do |arg|
419
- @options[:tag] = arg
409
+ @cli_options[:tag] = arg
410
+ end
411
+
412
+ o.on "--redirect-stdout FILE", "Redirect STDOUT to a specific file" do |arg|
413
+ @cli_options[:redirect_stdout] = arg
414
+ end
415
+
416
+ o.on "--redirect-stderr FILE", "Redirect STDERR to a specific file" do |arg|
417
+ @cli_options[:redirect_stderr] = arg
418
+ end
419
+
420
+ o.on "--[no-]redirect-append", "Append to redirected files" do |val|
421
+ @cli_options[:redirect_append] = val
420
422
  end
421
423
 
422
424
  o.banner = "puma <options> <rackup file>"
@@ -528,17 +530,19 @@ module Puma
528
530
  def parse_options
529
531
  @parser.parse! @argv
530
532
 
531
- @options[:rackup] = @argv.shift if @argv.last
533
+ @cli_options[:rackup] = @argv.shift if @argv.last
532
534
 
533
535
  find_config
534
536
 
535
- @config = Puma::Configuration.new @options
537
+ @config = Puma::Configuration.new @cli_options
536
538
 
537
539
  # Advertise the Configuration
538
540
  Puma.cli_config = @config
539
541
 
540
542
  @config.load
541
543
 
544
+ @options = @config.options
545
+
542
546
  if clustered? && (jruby? || windows?)
543
547
  unsupported 'worker mode not supported on JRuby or Windows'
544
548
  end
@@ -568,6 +572,7 @@ module Puma
568
572
  home = ENV['GEM_HOME']
569
573
  Bundler.with_clean_env do
570
574
  ENV['GEM_HOME'] = home
575
+ ENV['PUMA_BUNDLER_PRUNED'] = '1'
571
576
  wild = File.expand_path(File.join(puma_lib_dir, "../bin/puma-wild"))
572
577
  args = [Gem.ruby, wild, '-I', dirs.join(':'), deps.join(',')] + @original_argv
573
578
  Kernel.exec(*args)
data/lib/puma/client.rb CHANGED
@@ -45,11 +45,18 @@ module Puma
45
45
 
46
46
  @requests_served = 0
47
47
  @hijacked = false
48
+
49
+ @peerip = nil
50
+ @remote_addr_header = nil
48
51
  end
49
52
 
50
53
  attr_reader :env, :to_io, :body, :io, :timeout_at, :ready, :hijacked,
51
54
  :tempfile
52
55
 
56
+ attr_writer :peerip
57
+
58
+ attr_accessor :remote_addr_header
59
+
53
60
  def inspect
54
61
  "#<Puma::Client:0x#{object_id.to_s(16)} @ready=#{@ready.inspect}>"
55
62
  end
@@ -297,5 +304,17 @@ module Puma
297
304
  rescue StandardError
298
305
  end
299
306
  end
307
+
308
+ def peerip
309
+ return @peerip if @peerip
310
+
311
+ if @remote_addr_header
312
+ hdr = (@env[@remote_addr_header] || LOCALHOST_ADDR).split(/[\s,]/).first
313
+ @peerip = hdr
314
+ return hdr
315
+ end
316
+
317
+ @peerip ||= @io.peeraddr.last
318
+ end
300
319
  end
301
320
  end
data/lib/puma/cluster.rb CHANGED
@@ -65,6 +65,14 @@ module Puma
65
65
  @stage = :booted
66
66
  end
67
67
 
68
+ def dead?
69
+ @dead
70
+ end
71
+
72
+ def dead!
73
+ @dead = true
74
+ end
75
+
68
76
  def ping!
69
77
  @last_checkin = Time.now
70
78
  end
@@ -136,6 +144,7 @@ module Puma
136
144
  any = false
137
145
 
138
146
  @workers.each do |w|
147
+ next if !w.booted? && !w.ping_timeout?(@options[:worker_boot_timeout])
139
148
  if w.ping_timeout?(@options[:worker_timeout])
140
149
  log "! Terminating timed out worker: #{w.pid}"
141
150
  w.kill
@@ -154,6 +163,8 @@ module Puma
154
163
  @workers.delete_if { |w| w.pid == pid }
155
164
  end
156
165
 
166
+ @workers.delete_if(&:dead?)
167
+
157
168
  spawn_workers
158
169
 
159
170
  if all_workers_booted?
@@ -186,7 +197,7 @@ module Puma
186
197
 
187
198
  def worker(index, master)
188
199
  title = "puma: cluster worker #{index}: #{master}"
189
- title << " [#{@options[:tag]}]" if @options[:tag]
200
+ title << " [#{@options[:tag]}]" if @options[:tag] && !@options[:tag].empty?
190
201
  $0 = title
191
202
 
192
203
  Signal.trap "SIGINT", "IGNORE"
@@ -221,7 +232,7 @@ module Puma
221
232
  begin
222
233
  @worker_write << "b#{Process.pid}\n"
223
234
  rescue SystemCallError, IOError
224
- STDERR.puts "Master seems to have exitted, exitting."
235
+ STDERR.puts "Master seems to have exited, exiting."
225
236
  return
226
237
  end
227
238
 
@@ -241,6 +252,7 @@ module Puma
241
252
  hooks = @options[:before_worker_shutdown]
242
253
  hooks.each { |h| h.call(index) }
243
254
  ensure
255
+ @worker_write << "t#{Process.pid}\n" rescue nil
244
256
  @worker_write.close
245
257
  end
246
258
 
@@ -283,7 +295,9 @@ module Puma
283
295
  end
284
296
 
285
297
  def stats
286
- %Q!{ "workers": #{@workers.size}, "phase": #{@phase}, "booted_workers": #{@workers.count{|w| w.booted?}} }!
298
+ old_worker_count = @workers.count { |w| w.phase != @phase }
299
+ booted_worker_count = @workers.count { |w| w.booted? }
300
+ %Q!{ "workers": #{@workers.size}, "phase": #{@phase}, "booted_workers": #{booted_worker_count}, "old_workers": #{old_worker_count} }!
287
301
  end
288
302
 
289
303
  def preload?
@@ -379,6 +393,10 @@ module Puma
379
393
  @cli.write_state
380
394
 
381
395
  @master_read, @worker_write = read, @wakeup
396
+
397
+ hooks = @options[:before_fork]
398
+ hooks.each { |h| h.call }
399
+
382
400
  spawn_workers
383
401
 
384
402
  Signal.trap "SIGINT" do
@@ -407,6 +425,9 @@ module Puma
407
425
  w.boot!
408
426
  log "- Worker #{w.index} (pid: #{pid}) booted, phase: #{w.phase}"
409
427
  force_check = true
428
+ when "t"
429
+ w.dead!
430
+ force_check = true
410
431
  when "p"
411
432
  w.ping!
412
433
  end
@@ -15,26 +15,54 @@ module Puma
15
15
  include ConfigDefault
16
16
 
17
17
  def initialize(options)
18
- @options = options
19
- @options[:mode] ||= :http
20
- @options[:binds] ||= []
21
- @options[:on_restart] ||= []
22
- @options[:before_worker_shutdown] ||= []
23
- @options[:before_worker_boot] ||= []
24
- @options[:before_worker_fork] ||= []
25
- @options[:after_worker_boot] ||= []
26
- @options[:worker_timeout] ||= DefaultWorkerTimeout
27
- @options[:worker_shutdown_timeout] ||= DefaultWorkerShutdownTimeout
18
+ @cli_options = options
19
+
20
+ @conf = {}
21
+ @conf[:mode] ||= :http
22
+ @conf[:binds] ||= []
23
+ @conf[:on_restart] ||= []
24
+ @conf[:before_fork] ||= []
25
+ @conf[:before_worker_shutdown] ||= []
26
+ @conf[:before_worker_boot] ||= []
27
+ @conf[:before_worker_fork] ||= []
28
+ @conf[:after_worker_boot] ||= []
29
+ @conf[:worker_timeout] ||= DefaultWorkerTimeout
30
+ @conf[:worker_boot_timeout] ||= @conf[:worker_timeout]
31
+ @conf[:worker_shutdown_timeout] ||= DefaultWorkerShutdownTimeout
32
+ @conf[:remote_address] ||= :socket
33
+
34
+ @options = {}
28
35
  end
29
36
 
30
37
  attr_reader :options
31
38
 
32
39
  def initialize_copy(other)
40
+ @conf = nil
41
+ @cli_options = nil
33
42
  @options = @options.dup
34
43
  end
35
44
 
45
+ def default_options
46
+ {
47
+ :min_threads => 0,
48
+ :max_threads => 16,
49
+ :quiet => false,
50
+ :debug => false,
51
+ :binds => [],
52
+ :workers => 0,
53
+ :daemon => false,
54
+ }
55
+ end
56
+
36
57
  def load
37
- DSL.load(@options, @options[:config_file])
58
+ @conf.merge! @cli_options
59
+ DSL.load(@conf, @cli_options[:config_file])
60
+
61
+ # Load the options in the right priority
62
+ #
63
+ @options.merge! default_options
64
+ @options.merge! @conf
65
+ @options.merge! @cli_options
38
66
 
39
67
  setup_binds
40
68
  setup_control
@@ -98,10 +126,33 @@ module Puma
98
126
  File.basename(Dir.getwd)
99
127
  end
100
128
 
129
+ # Load and use the normal Rack builder if we can, otherwise
130
+ # fallback to our minimal version.
131
+ def rack_builder
132
+ # Load bundler now if we can so that we can pickup rack from
133
+ # a Gemfile
134
+ if ENV.key? 'PUMA_BUNDLER_PRUNED'
135
+ begin
136
+ require 'bundler/setup'
137
+ rescue LoadError
138
+ end
139
+ end
140
+
141
+ begin
142
+ require 'rack'
143
+ require 'rack/builder'
144
+ rescue LoadError
145
+ # ok, use builtin version
146
+ return Puma::Rack::Builder
147
+ else
148
+ return ::Rack::Builder
149
+ end
150
+ end
151
+
101
152
  def load_rackup
102
153
  raise "Missing rackup file '#{rackup}'" unless File.exist?(rackup)
103
154
 
104
- rack_app, rack_options = Puma::Rack::Builder.parse_file(rackup)
155
+ rack_app, rack_options = rack_builder.parse_file(rackup)
105
156
  @options.merge!(rack_options)
106
157
 
107
158
  config_ru_binds = []
data/lib/puma/const.rb CHANGED
@@ -99,8 +99,8 @@ module Puma
99
99
  # too taxing on performance.
100
100
  module Const
101
101
 
102
- PUMA_VERSION = VERSION = "2.12.3".freeze
103
- CODE_NAME = "Plutonian Photo Shoot".freeze
102
+ PUMA_VERSION = VERSION = "2.16.0".freeze
103
+ CODE_NAME = "Midwinter Nights Trance".freeze
104
104
 
105
105
  FAST_TRACK_KA_TIMEOUT = 0.2
106
106
 
@@ -183,6 +183,7 @@ module Puma
183
183
  PORT_443 = "443".freeze
184
184
  LOCALHOST = "localhost".freeze
185
185
  LOCALHOST_IP = "127.0.0.1".freeze
186
+ LOCALHOST_ADDR = "127.0.0.1:0".freeze
186
187
 
187
188
  SERVER_PROTOCOL = "SERVER_PROTOCOL".freeze
188
189
  HTTP_11 = "HTTP/1.1".freeze
@@ -215,11 +216,11 @@ module Puma
215
216
  HTTP_10_200 = "HTTP/1.0 200 OK\r\n".freeze
216
217
 
217
218
  CLOSE = "close".freeze
218
- KEEP_ALIVE = "Keep-Alive".freeze
219
+ KEEP_ALIVE = "keep-alive".freeze
219
220
 
220
- CONTENT_LENGTH2 = "Content-Length".freeze
221
+ CONTENT_LENGTH2 = "content-length".freeze
221
222
  CONTENT_LENGTH_S = "Content-Length: ".freeze
222
- TRANSFER_ENCODING = "Transfer-Encoding".freeze
223
+ TRANSFER_ENCODING = "transfer-encoding".freeze
223
224
 
224
225
  CONNECTION_CLOSE = "Connection: close\r\n".freeze
225
226
  CONNECTION_KEEP_ALIVE = "Connection: Keep-Alive\r\n".freeze
@@ -17,37 +17,37 @@ module Puma
17
17
  @argv = argv
18
18
  @stdout = stdout
19
19
  @stderr = stderr
20
- @options = {}
20
+ @cli_options = {}
21
21
 
22
22
  opts = OptionParser.new do |o|
23
23
  o.banner = "Usage: pumactl (-p PID | -P pidfile | -S status_file | -C url -T token | -F config.rb) (#{COMMANDS.join("|")})"
24
24
 
25
25
  o.on "-S", "--state PATH", "Where the state file to use is" do |arg|
26
- @options[:state] = arg
26
+ @cli_options[:state] = arg
27
27
  end
28
28
 
29
29
  o.on "-Q", "--quiet", "Not display messages" do |arg|
30
- @options[:quiet_flag] = true
30
+ @cli_options[:quiet_flag] = true
31
31
  end
32
32
 
33
33
  o.on "-P", "--pidfile PATH", "Pid file" do |arg|
34
- @options[:pidfile] = arg
34
+ @cli_options[:pidfile] = arg
35
35
  end
36
36
 
37
37
  o.on "-p", "--pid PID", "Pid" do |arg|
38
- @options[:pid] = arg.to_i
38
+ @cli_options[:pid] = arg.to_i
39
39
  end
40
40
 
41
41
  o.on "-C", "--control-url URL", "The bind url to use for the control server" do |arg|
42
- @options[:control_url] = arg
42
+ @cli_options[:control_url] = arg
43
43
  end
44
44
 
45
45
  o.on "-T", "--control-token TOKEN", "The token to use as authentication for the control server" do |arg|
46
- @options[:control_auth_token] = arg
46
+ @cli_options[:control_auth_token] = arg
47
47
  end
48
48
 
49
49
  o.on "-F", "--config-file PATH", "Puma config script" do |arg|
50
- @options[:config_file] = arg
50
+ @cli_options[:config_file] = arg
51
51
  end
52
52
 
53
53
  o.on_tail("-H", "--help", "Show this message") do
@@ -64,18 +64,24 @@ module Puma
64
64
  opts.order!(argv) { |a| opts.terminate a }
65
65
 
66
66
  command = argv.shift
67
- @options[:command] = command if command
67
+ @cli_options[:command] = command if command
68
68
 
69
- unless @options[:config_file] == '-'
70
- if @options[:config_file].nil? and File.exist?('config/puma.rb')
71
- @options[:config_file] = 'config/puma.rb'
69
+ @options = nil
70
+
71
+ unless @cli_options[:config_file] == '-'
72
+ if @cli_options[:config_file].nil? and File.exist?('config/puma.rb')
73
+ @cli_options[:config_file] = 'config/puma.rb'
72
74
  end
73
75
 
74
- if @options[:config_file]
75
- Puma::Configuration.new(@options).load
76
+ if @cli_options[:config_file]
77
+ config = Puma::Configuration.new(@cli_options)
78
+ config.load
79
+ @options = config.options
76
80
  end
77
81
  end
78
82
 
83
+ @options ||= @cli_options
84
+
79
85
  # check present of command
80
86
  unless @options[:command]
81
87
  raise "Available commands: #{COMMANDS.join(", ")}"
@@ -256,6 +262,10 @@ module Puma
256
262
 
257
263
  events = Puma::Events.new @stdout, @stderr
258
264
 
265
+ # replace $0 because puma use it to generate restart command
266
+ puma_cmd = $0.gsub(/pumactl$/, 'puma')
267
+ $0 = puma_cmd if File.exist?(puma_cmd)
268
+
259
269
  cli = Puma::CLI.new run_args, events
260
270
  cli.run
261
271
  end