puma 6.0.2 → 6.4.2
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.
- checksums.yaml +4 -4
- data/History.md +213 -7
- data/LICENSE +0 -0
- data/README.md +59 -13
- data/bin/puma-wild +0 -0
- data/docs/architecture.md +0 -0
- data/docs/compile_options.md +0 -0
- data/docs/deployment.md +0 -0
- data/docs/fork_worker.md +0 -0
- data/docs/images/puma-connection-flow-no-reactor.png +0 -0
- data/docs/images/puma-connection-flow.png +0 -0
- data/docs/images/puma-general-arch.png +0 -0
- data/docs/jungle/README.md +0 -0
- data/docs/jungle/rc.d/README.md +0 -0
- data/docs/jungle/rc.d/puma.conf +0 -0
- data/docs/kubernetes.md +12 -0
- data/docs/nginx.md +0 -0
- data/docs/plugins.md +0 -0
- data/docs/rails_dev_mode.md +0 -0
- data/docs/restart.md +1 -0
- data/docs/signals.md +0 -0
- data/docs/stats.md +0 -0
- data/docs/systemd.md +3 -6
- data/docs/testing_benchmarks_local_files.md +0 -0
- data/docs/testing_test_rackup_ci_files.md +0 -0
- data/ext/puma_http11/PumaHttp11Service.java +0 -0
- data/ext/puma_http11/ext_help.h +0 -0
- data/ext/puma_http11/extconf.rb +5 -1
- data/ext/puma_http11/http11_parser.c +0 -0
- data/ext/puma_http11/http11_parser.h +0 -0
- data/ext/puma_http11/http11_parser.java.rl +0 -0
- data/ext/puma_http11/http11_parser.rl +0 -0
- data/ext/puma_http11/http11_parser_common.rl +0 -0
- data/ext/puma_http11/mini_ssl.c +96 -9
- data/ext/puma_http11/no_ssl/PumaHttp11Service.java +0 -0
- data/ext/puma_http11/org/jruby/puma/Http11.java +0 -0
- data/ext/puma_http11/org/jruby/puma/Http11Parser.java +0 -0
- data/ext/puma_http11/org/jruby/puma/MiniSSL.java +2 -1
- data/ext/puma_http11/puma_http11.c +0 -0
- data/lib/puma/app/status.rb +1 -1
- data/lib/puma/binder.rb +14 -11
- data/lib/puma/cli.rb +5 -1
- data/lib/puma/client.rb +77 -16
- data/lib/puma/cluster/worker.rb +5 -0
- data/lib/puma/cluster/worker_handle.rb +0 -0
- data/lib/puma/cluster.rb +71 -10
- data/lib/puma/commonlogger.rb +21 -14
- data/lib/puma/configuration.rb +6 -4
- data/lib/puma/const.rb +58 -9
- data/lib/puma/control_cli.rb +12 -5
- data/lib/puma/detect.rb +5 -4
- data/lib/puma/dsl.rb +157 -7
- data/lib/puma/error_logger.rb +2 -1
- data/lib/puma/events.rb +0 -0
- data/lib/puma/io_buffer.rb +0 -0
- data/lib/puma/jruby_restart.rb +0 -0
- data/lib/puma/json_serialization.rb +0 -0
- data/lib/puma/launcher/bundle_pruner.rb +0 -0
- data/lib/puma/launcher.rb +9 -22
- data/lib/puma/log_writer.rb +14 -4
- data/lib/puma/minissl/context_builder.rb +3 -0
- data/lib/puma/minissl.rb +22 -0
- data/lib/puma/null_io.rb +16 -2
- data/lib/puma/plugin/systemd.rb +90 -0
- data/lib/puma/plugin/tmp_restart.rb +0 -0
- data/lib/puma/plugin.rb +0 -0
- data/lib/puma/rack/builder.rb +2 -2
- data/lib/puma/rack/urlmap.rb +1 -1
- data/lib/puma/rack_default.rb +18 -3
- data/lib/puma/reactor.rb +16 -7
- data/lib/puma/request.rb +91 -64
- data/lib/puma/runner.rb +13 -2
- data/lib/puma/sd_notify.rb +149 -0
- data/lib/puma/server.rb +91 -27
- data/lib/puma/single.rb +2 -0
- data/lib/puma/state_file.rb +2 -2
- data/lib/puma/thread_pool.rb +41 -3
- data/lib/puma/util.rb +0 -0
- data/lib/puma.rb +0 -0
- data/lib/rack/handler/puma.rb +113 -86
- data/tools/Dockerfile +2 -2
- data/tools/trickletest.rb +0 -0
- metadata +5 -4
- data/lib/puma/systemd.rb +0 -47
data/lib/puma/cluster.rb
CHANGED
@@ -85,9 +85,7 @@ module Puma
|
|
85
85
|
@workers << WorkerHandle.new(idx, pid, @phase, @options)
|
86
86
|
end
|
87
87
|
|
88
|
-
if @options[:fork_worker] &&
|
89
|
-
@workers.all? {|x| x.phase == @phase}
|
90
|
-
|
88
|
+
if @options[:fork_worker] && all_workers_in_phase?
|
91
89
|
@fork_writer << "0\n"
|
92
90
|
end
|
93
91
|
end
|
@@ -148,10 +146,22 @@ module Puma
|
|
148
146
|
idx
|
149
147
|
end
|
150
148
|
|
149
|
+
def worker_at(idx)
|
150
|
+
@workers.find { |w| w.index == idx }
|
151
|
+
end
|
152
|
+
|
151
153
|
def all_workers_booted?
|
152
154
|
@workers.count { |w| !w.booted? } == 0
|
153
155
|
end
|
154
156
|
|
157
|
+
def all_workers_in_phase?
|
158
|
+
@workers.all? { |w| w.phase == @phase }
|
159
|
+
end
|
160
|
+
|
161
|
+
def all_workers_idle_timed_out?
|
162
|
+
(@workers.map(&:pid) - idle_timed_out_worker_pids).empty?
|
163
|
+
end
|
164
|
+
|
155
165
|
def check_workers
|
156
166
|
return if @next_check >= Time.now
|
157
167
|
|
@@ -276,7 +286,7 @@ module Puma
|
|
276
286
|
|
277
287
|
# @version 5.0.0
|
278
288
|
def fork_worker!
|
279
|
-
if (worker =
|
289
|
+
if (worker = worker_at 0)
|
280
290
|
worker.phase += 1
|
281
291
|
end
|
282
292
|
phased_restart(true)
|
@@ -338,6 +348,8 @@ module Puma
|
|
338
348
|
def run
|
339
349
|
@status = :run
|
340
350
|
|
351
|
+
@idle_workers = {}
|
352
|
+
|
341
353
|
output_header "cluster"
|
342
354
|
|
343
355
|
# This is aligned with the output from Runner, see Runner#output_header
|
@@ -411,6 +423,8 @@ module Puma
|
|
411
423
|
|
412
424
|
@master_read, @worker_write = read, @wakeup
|
413
425
|
|
426
|
+
@options[:worker_write] = @worker_write
|
427
|
+
|
414
428
|
@config.run_hooks(:before_fork, nil, @log_writer)
|
415
429
|
|
416
430
|
spawn_workers
|
@@ -426,6 +440,11 @@ module Puma
|
|
426
440
|
|
427
441
|
while @status == :run
|
428
442
|
begin
|
443
|
+
if all_workers_idle_timed_out?
|
444
|
+
log "- All workers reached idle timeout"
|
445
|
+
break
|
446
|
+
end
|
447
|
+
|
429
448
|
if @phased_restart
|
430
449
|
start_phased_restart
|
431
450
|
@phased_restart = false
|
@@ -446,7 +465,7 @@ module Puma
|
|
446
465
|
|
447
466
|
if req == "b" || req == "f"
|
448
467
|
pid, idx = result.split(':').map(&:to_i)
|
449
|
-
w =
|
468
|
+
w = worker_at idx
|
450
469
|
w.pid = pid if w.pid.nil?
|
451
470
|
end
|
452
471
|
|
@@ -463,22 +482,37 @@ module Puma
|
|
463
482
|
when "t"
|
464
483
|
w.term unless w.term?
|
465
484
|
when "p"
|
466
|
-
|
485
|
+
status = result.sub(/^\d+/,'').chomp
|
486
|
+
w.ping!(status)
|
467
487
|
@events.fire(:ping!, w)
|
488
|
+
|
489
|
+
if in_phased_restart && workers_not_booted.positive? && w0 = worker_at(0)
|
490
|
+
w0.ping!(status)
|
491
|
+
@events.fire(:ping!, w0)
|
492
|
+
end
|
493
|
+
|
468
494
|
if !booted && @workers.none? {|worker| worker.last_status.empty?}
|
469
495
|
@events.fire_on_booted!
|
496
|
+
debug_loaded_extensions("Loaded Extensions - master:") if @log_writer.debug?
|
470
497
|
booted = true
|
471
498
|
end
|
499
|
+
when "i"
|
500
|
+
if @idle_workers[pid]
|
501
|
+
@idle_workers.delete pid
|
502
|
+
else
|
503
|
+
@idle_workers[pid] = true
|
504
|
+
end
|
472
505
|
end
|
473
506
|
else
|
474
507
|
log "! Out-of-sync worker list, no #{pid} worker"
|
475
508
|
end
|
476
509
|
end
|
510
|
+
|
477
511
|
if in_phased_restart && workers_not_booted.zero?
|
478
512
|
@events.fire_on_booted!
|
513
|
+
debug_loaded_extensions("Loaded Extensions - master:") if @log_writer.debug?
|
479
514
|
in_phased_restart = false
|
480
515
|
end
|
481
|
-
|
482
516
|
rescue Interrupt
|
483
517
|
@status = :stop
|
484
518
|
end
|
@@ -507,10 +541,28 @@ module Puma
|
|
507
541
|
# loops thru @workers, removing workers that exited, and calling
|
508
542
|
# `#term` if needed
|
509
543
|
def wait_workers
|
544
|
+
# Reap all children, known workers or otherwise.
|
545
|
+
# If puma has PID 1, as it's common in containerized environments,
|
546
|
+
# then it's responsible for reaping orphaned processes, so we must reap
|
547
|
+
# all our dead children, regardless of whether they are workers we spawned
|
548
|
+
# or some reattached processes.
|
549
|
+
reaped_children = {}
|
550
|
+
loop do
|
551
|
+
begin
|
552
|
+
pid, status = Process.wait2(-1, Process::WNOHANG)
|
553
|
+
break unless pid
|
554
|
+
reaped_children[pid] = status
|
555
|
+
rescue Errno::ECHILD
|
556
|
+
break
|
557
|
+
end
|
558
|
+
end
|
559
|
+
|
510
560
|
@workers.reject! do |w|
|
511
561
|
next false if w.pid.nil?
|
512
562
|
begin
|
513
|
-
|
563
|
+
# When `fork_worker` is enabled, some worker may not be direct children, but grand children.
|
564
|
+
# Because of this they won't be reaped by `Process.wait2(-1)`, so we need to check them individually)
|
565
|
+
if reaped_children.delete(w.pid) || (@options[:fork_worker] && Process.wait(w.pid, Process::WNOHANG))
|
514
566
|
true
|
515
567
|
else
|
516
568
|
w.term if w.term?
|
@@ -527,6 +579,11 @@ module Puma
|
|
527
579
|
end
|
528
580
|
end
|
529
581
|
end
|
582
|
+
|
583
|
+
# Log unknown children
|
584
|
+
reaped_children.each do |pid, status|
|
585
|
+
log "! reaped unknown child process pid=#{pid} status=#{status}"
|
586
|
+
end
|
530
587
|
end
|
531
588
|
|
532
589
|
# @version 5.0.0
|
@@ -534,14 +591,18 @@ module Puma
|
|
534
591
|
@workers.each do |w|
|
535
592
|
if !w.term? && w.ping_timeout <= Time.now
|
536
593
|
details = if w.booted?
|
537
|
-
"(
|
594
|
+
"(Worker #{w.index} failed to check in within #{@options[:worker_timeout]} seconds)"
|
538
595
|
else
|
539
|
-
"(
|
596
|
+
"(Worker #{w.index} failed to boot within #{@options[:worker_boot_timeout]} seconds)"
|
540
597
|
end
|
541
598
|
log "! Terminating timed out worker #{details}: #{w.pid}"
|
542
599
|
w.kill
|
543
600
|
end
|
544
601
|
end
|
545
602
|
end
|
603
|
+
|
604
|
+
def idle_timed_out_worker_pids
|
605
|
+
@idle_workers.keys
|
606
|
+
end
|
546
607
|
end
|
547
608
|
end
|
data/lib/puma/commonlogger.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
module Puma
|
4
4
|
# Rack::CommonLogger forwards every request to the given +app+, and
|
5
5
|
# logs a line in the
|
6
|
-
# {Apache common log format}[https://httpd.apache.org/docs/
|
6
|
+
# {Apache common log format}[https://httpd.apache.org/docs/2.4/logs.html#common]
|
7
7
|
# to the +logger+.
|
8
8
|
#
|
9
9
|
# If +logger+ is nil, CommonLogger will fall back +rack.errors+, which is
|
@@ -16,7 +16,7 @@ module Puma
|
|
16
16
|
# (which is called without arguments in order to make the error appear for
|
17
17
|
# sure)
|
18
18
|
class CommonLogger
|
19
|
-
# Common Log Format: https://httpd.apache.org/docs/
|
19
|
+
# Common Log Format: https://httpd.apache.org/docs/2.4/logs.html#common
|
20
20
|
#
|
21
21
|
# lilith.local - - [07/Aug/2006 23:58:02 -0400] "GET / HTTP/1.1" 500 -
|
22
22
|
#
|
@@ -25,10 +25,17 @@ module Puma
|
|
25
25
|
|
26
26
|
HIJACK_FORMAT = %{%s - %s [%s] "%s %s%s %s" HIJACKED -1 %0.4f\n}
|
27
27
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
28
|
+
LOG_TIME_FORMAT = '%d/%b/%Y:%H:%M:%S %z'
|
29
|
+
|
30
|
+
CONTENT_LENGTH = 'Content-Length' # should be lower case from app,
|
31
|
+
# Util::HeaderHash allows mixed
|
32
|
+
HTTP_VERSION = Const::HTTP_VERSION
|
33
|
+
HTTP_X_FORWARDED_FOR = Const::HTTP_X_FORWARDED_FOR
|
34
|
+
PATH_INFO = Const::PATH_INFO
|
35
|
+
QUERY_STRING = Const::QUERY_STRING
|
36
|
+
REMOTE_ADDR = Const::REMOTE_ADDR
|
37
|
+
REMOTE_USER = 'REMOTE_USER'
|
38
|
+
REQUEST_METHOD = Const::REQUEST_METHOD
|
32
39
|
|
33
40
|
def initialize(app, logger=nil)
|
34
41
|
@app = app
|
@@ -57,13 +64,13 @@ module Puma
|
|
57
64
|
now = Time.now
|
58
65
|
|
59
66
|
msg = HIJACK_FORMAT % [
|
60
|
-
env[
|
61
|
-
env[
|
62
|
-
now.strftime(
|
67
|
+
env[HTTP_X_FORWARDED_FOR] || env[REMOTE_ADDR] || "-",
|
68
|
+
env[REMOTE_USER] || "-",
|
69
|
+
now.strftime(LOG_TIME_FORMAT),
|
63
70
|
env[REQUEST_METHOD],
|
64
71
|
env[PATH_INFO],
|
65
72
|
env[QUERY_STRING].empty? ? "" : "?#{env[QUERY_STRING]}",
|
66
|
-
env[
|
73
|
+
env[HTTP_VERSION],
|
67
74
|
now - began_at ]
|
68
75
|
|
69
76
|
write(msg)
|
@@ -74,13 +81,13 @@ module Puma
|
|
74
81
|
length = extract_content_length(header)
|
75
82
|
|
76
83
|
msg = FORMAT % [
|
77
|
-
env[
|
78
|
-
env[
|
79
|
-
now.strftime(
|
84
|
+
env[HTTP_X_FORWARDED_FOR] || env[REMOTE_ADDR] || "-",
|
85
|
+
env[REMOTE_USER] || "-",
|
86
|
+
now.strftime(LOG_TIME_FORMAT),
|
80
87
|
env[REQUEST_METHOD],
|
81
88
|
env[PATH_INFO],
|
82
89
|
env[QUERY_STRING].empty? ? "" : "?#{env[QUERY_STRING]}",
|
83
|
-
env[
|
90
|
+
env[HTTP_VERSION],
|
84
91
|
status.to_s[0..3],
|
85
92
|
length,
|
86
93
|
now - began_at ]
|
data/lib/puma/configuration.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
require_relative 'rack/builder'
|
4
4
|
require_relative 'plugin'
|
5
5
|
require_relative 'const'
|
6
|
-
|
6
|
+
require_relative 'dsl'
|
7
7
|
|
8
8
|
module Puma
|
9
9
|
# A class used for storing "leveled" configuration options.
|
@@ -133,8 +133,10 @@ module Puma
|
|
133
133
|
debug: false,
|
134
134
|
early_hints: nil,
|
135
135
|
environment: 'development'.freeze,
|
136
|
-
# Number of seconds to wait until we get the first data for the request
|
136
|
+
# Number of seconds to wait until we get the first data for the request.
|
137
137
|
first_data_timeout: 30,
|
138
|
+
# Number of seconds to wait until the next request before shutting down.
|
139
|
+
idle_timeout: nil,
|
138
140
|
io_selector_backend: :auto,
|
139
141
|
log_requests: false,
|
140
142
|
logger: STDOUT,
|
@@ -157,6 +159,7 @@ module Puma
|
|
157
159
|
reaping_time: 1,
|
158
160
|
remote_address: :socket,
|
159
161
|
silence_single_worker_warning: false,
|
162
|
+
silence_fork_callback_warning: false,
|
160
163
|
tag: File.basename(Dir.getwd),
|
161
164
|
tcp_host: '0.0.0.0'.freeze,
|
162
165
|
tcp_port: 9292,
|
@@ -167,6 +170,7 @@ module Puma
|
|
167
170
|
worker_shutdown_timeout: 30,
|
168
171
|
worker_timeout: 60,
|
169
172
|
workers: 0,
|
173
|
+
http_content_length_limit: nil
|
170
174
|
}
|
171
175
|
|
172
176
|
def initialize(user_options={}, default_options = {}, &block)
|
@@ -383,5 +387,3 @@ module Puma
|
|
383
387
|
end
|
384
388
|
end
|
385
389
|
end
|
386
|
-
|
387
|
-
require_relative 'dsl'
|
data/lib/puma/const.rb
CHANGED
@@ -18,6 +18,7 @@ module Puma
|
|
18
18
|
100 => 'Continue',
|
19
19
|
101 => 'Switching Protocols',
|
20
20
|
102 => 'Processing',
|
21
|
+
103 => 'Early Hints',
|
21
22
|
200 => 'OK',
|
22
23
|
201 => 'Created',
|
23
24
|
202 => 'Accepted',
|
@@ -49,16 +50,16 @@ module Puma
|
|
49
50
|
410 => 'Gone',
|
50
51
|
411 => 'Length Required',
|
51
52
|
412 => 'Precondition Failed',
|
52
|
-
413 => '
|
53
|
+
413 => 'Content Too Large',
|
53
54
|
414 => 'URI Too Long',
|
54
55
|
415 => 'Unsupported Media Type',
|
55
56
|
416 => 'Range Not Satisfiable',
|
56
57
|
417 => 'Expectation Failed',
|
57
|
-
418 => 'I\'m A Teapot',
|
58
58
|
421 => 'Misdirected Request',
|
59
|
-
422 => 'Unprocessable
|
59
|
+
422 => 'Unprocessable Content',
|
60
60
|
423 => 'Locked',
|
61
61
|
424 => 'Failed Dependency',
|
62
|
+
425 => 'Too Early',
|
62
63
|
426 => 'Upgrade Required',
|
63
64
|
428 => 'Precondition Required',
|
64
65
|
429 => 'Too Many Requests',
|
@@ -73,7 +74,7 @@ module Puma
|
|
73
74
|
506 => 'Variant Also Negotiates',
|
74
75
|
507 => 'Insufficient Storage',
|
75
76
|
508 => 'Loop Detected',
|
76
|
-
510 => 'Not Extended',
|
77
|
+
510 => 'Not Extended (OBSOLETED)',
|
77
78
|
511 => 'Network Authentication Required'
|
78
79
|
}.freeze
|
79
80
|
|
@@ -99,8 +100,8 @@ module Puma
|
|
99
100
|
# too taxing on performance.
|
100
101
|
module Const
|
101
102
|
|
102
|
-
PUMA_VERSION = VERSION = "6.
|
103
|
-
CODE_NAME = "
|
103
|
+
PUMA_VERSION = VERSION = "6.4.2"
|
104
|
+
CODE_NAME = "The Eagle of Durango"
|
104
105
|
|
105
106
|
PUMA_SERVER_STRING = ["puma", PUMA_VERSION, CODE_NAME].join(" ").freeze
|
106
107
|
|
@@ -124,15 +125,15 @@ module Puma
|
|
124
125
|
# Indicate that we couldn't parse the request
|
125
126
|
400 => "HTTP/1.1 400 Bad Request\r\n\r\n",
|
126
127
|
# The standard empty 404 response for bad requests. Use Error4040Handler for custom stuff.
|
127
|
-
404 => "HTTP/1.1 404 Not Found\r\nConnection: close\r\
|
128
|
+
404 => "HTTP/1.1 404 Not Found\r\nConnection: close\r\n\r\n",
|
128
129
|
# The standard empty 408 response for requests that timed out.
|
129
|
-
408 => "HTTP/1.1 408 Request Timeout\r\nConnection: close\r\
|
130
|
+
408 => "HTTP/1.1 408 Request Timeout\r\nConnection: close\r\n\r\n",
|
130
131
|
# Indicate that there was an internal error, obviously.
|
131
132
|
500 => "HTTP/1.1 500 Internal Server Error\r\n\r\n",
|
132
133
|
# Incorrect or invalid header value
|
133
134
|
501 => "HTTP/1.1 501 Not Implemented\r\n\r\n",
|
134
135
|
# A common header for indicating the server is too busy. Not used yet.
|
135
|
-
503 => "HTTP/1.1 503 Service Unavailable\r\n\r\
|
136
|
+
503 => "HTTP/1.1 503 Service Unavailable\r\n\r\n"
|
136
137
|
}.freeze
|
137
138
|
|
138
139
|
# The basic max request size we'll try to read.
|
@@ -147,7 +148,55 @@ module Puma
|
|
147
148
|
|
148
149
|
REQUEST_METHOD = "REQUEST_METHOD"
|
149
150
|
HEAD = "HEAD"
|
151
|
+
|
152
|
+
# based on https://www.rfc-editor.org/rfc/rfc9110.html#name-overview,
|
153
|
+
# with CONNECT removed, and PATCH added
|
150
154
|
SUPPORTED_HTTP_METHODS = %w[HEAD GET POST PUT DELETE OPTIONS TRACE PATCH].freeze
|
155
|
+
|
156
|
+
# list from https://www.iana.org/assignments/http-methods/http-methods.xhtml
|
157
|
+
# as of 04-May-23
|
158
|
+
IANA_HTTP_METHODS = %w[
|
159
|
+
ACL
|
160
|
+
BASELINE-CONTROL
|
161
|
+
BIND
|
162
|
+
CHECKIN
|
163
|
+
CHECKOUT
|
164
|
+
CONNECT
|
165
|
+
COPY
|
166
|
+
DELETE
|
167
|
+
GET
|
168
|
+
HEAD
|
169
|
+
LABEL
|
170
|
+
LINK
|
171
|
+
LOCK
|
172
|
+
MERGE
|
173
|
+
MKACTIVITY
|
174
|
+
MKCALENDAR
|
175
|
+
MKCOL
|
176
|
+
MKREDIRECTREF
|
177
|
+
MKWORKSPACE
|
178
|
+
MOVE
|
179
|
+
OPTIONS
|
180
|
+
ORDERPATCH
|
181
|
+
PATCH
|
182
|
+
POST
|
183
|
+
PRI
|
184
|
+
PROPFIND
|
185
|
+
PROPPATCH
|
186
|
+
PUT
|
187
|
+
REBIND
|
188
|
+
REPORT
|
189
|
+
SEARCH
|
190
|
+
TRACE
|
191
|
+
UNBIND
|
192
|
+
UNCHECKOUT
|
193
|
+
UNLINK
|
194
|
+
UNLOCK
|
195
|
+
UPDATE
|
196
|
+
UPDATEREDIRECTREF
|
197
|
+
VERSION-CONTROL
|
198
|
+
].freeze
|
199
|
+
|
151
200
|
# ETag is based on the apache standard of hex mtime-size-inode (inode is 0 on win32)
|
152
201
|
LINE_END = "\r\n"
|
153
202
|
REMOTE_ADDR = "REMOTE_ADDR"
|
data/lib/puma/control_cli.rb
CHANGED
@@ -1,10 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'optparse'
|
4
|
-
require_relative 'state_file'
|
5
4
|
require_relative 'const'
|
6
5
|
require_relative 'detect'
|
7
|
-
require_relative 'configuration'
|
8
6
|
require 'uri'
|
9
7
|
require 'socket'
|
10
8
|
|
@@ -126,6 +124,9 @@ module Puma
|
|
126
124
|
end
|
127
125
|
|
128
126
|
if @config_file
|
127
|
+
require_relative 'configuration'
|
128
|
+
require_relative 'log_writer'
|
129
|
+
|
129
130
|
config = Puma::Configuration.new({ config_files: [@config_file] }, {})
|
130
131
|
config.load
|
131
132
|
@state ||= config.options[:state]
|
@@ -149,6 +150,8 @@ module Puma
|
|
149
150
|
raise "State file not found: #{@state}"
|
150
151
|
end
|
151
152
|
|
153
|
+
require_relative 'state_file'
|
154
|
+
|
152
155
|
sf = Puma::StateFile.new
|
153
156
|
sf.load @state
|
154
157
|
|
@@ -164,22 +167,26 @@ module Puma
|
|
164
167
|
def send_request
|
165
168
|
uri = URI.parse @control_url
|
166
169
|
|
170
|
+
host = uri.host
|
171
|
+
|
167
172
|
# create server object by scheme
|
168
173
|
server =
|
169
174
|
case uri.scheme
|
170
175
|
when 'ssl'
|
171
176
|
require 'openssl'
|
177
|
+
host = host[1..-2] if host&.start_with? '['
|
172
178
|
OpenSSL::SSL::SSLSocket.new(
|
173
|
-
TCPSocket.new(
|
179
|
+
TCPSocket.new(host, uri.port),
|
174
180
|
OpenSSL::SSL::SSLContext.new)
|
175
181
|
.tap { |ssl| ssl.sync_close = true } # default is false
|
176
182
|
.tap(&:connect)
|
177
183
|
when 'tcp'
|
178
|
-
|
184
|
+
host = host[1..-2] if host&.start_with? '['
|
185
|
+
TCPSocket.new host, uri.port
|
179
186
|
when 'unix'
|
180
187
|
# check for abstract UNIXSocket
|
181
188
|
UNIXSocket.new(@control_url.start_with?('unix://@') ?
|
182
|
-
"\0#{
|
189
|
+
"\0#{host}#{uri.path}" : "#{host}#{uri.path}")
|
183
190
|
else
|
184
191
|
raise "Invalid scheme: #{uri.scheme}"
|
185
192
|
end
|
data/lib/puma/detect.rb
CHANGED
@@ -12,13 +12,14 @@ module Puma
|
|
12
12
|
|
13
13
|
IS_JRUBY = Object.const_defined? :JRUBY_VERSION
|
14
14
|
|
15
|
-
IS_OSX =
|
15
|
+
IS_OSX = RUBY_DESCRIPTION.include? 'darwin'
|
16
16
|
|
17
|
-
IS_WINDOWS =
|
18
|
-
|
17
|
+
IS_WINDOWS = RUBY_DESCRIPTION.match?(/mswin|ming|cygwin/)
|
18
|
+
|
19
|
+
IS_LINUX = !(IS_OSX || IS_WINDOWS)
|
19
20
|
|
20
21
|
# @version 5.2.0
|
21
|
-
IS_MRI =
|
22
|
+
IS_MRI = RUBY_ENGINE == 'ruby'
|
22
23
|
|
23
24
|
def self.jruby?
|
24
25
|
IS_JRUBY
|