puma 5.5.2-java → 5.6.0-java
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 +51 -0
- data/LICENSE +0 -0
- data/README.md +5 -0
- data/bin/puma-wild +0 -0
- data/docs/architecture.md +4 -4
- 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 +0 -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 +0 -0
- data/docs/signals.md +1 -0
- data/docs/stats.md +0 -0
- data/docs/systemd.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 +12 -6
- 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 +54 -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 +28 -43
- data/ext/puma_http11/puma_http11.c +1 -1
- data/lib/puma/app/status.rb +0 -0
- data/lib/puma/binder.rb +19 -5
- data/lib/puma/cli.rb +9 -4
- data/lib/puma/client.rb +1 -1
- data/lib/puma/cluster/worker.rb +5 -5
- data/lib/puma/cluster/worker_handle.rb +4 -0
- data/lib/puma/cluster.rb +29 -11
- data/lib/puma/commonlogger.rb +0 -0
- data/lib/puma/configuration.rb +3 -0
- data/lib/puma/const.rb +2 -5
- data/lib/puma/control_cli.rb +0 -0
- data/lib/puma/detect.rb +8 -2
- data/lib/puma/dsl.rb +85 -8
- data/lib/puma/error_logger.rb +0 -0
- 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.rb +2 -1
- data/lib/puma/minissl/context_builder.rb +8 -6
- data/lib/puma/minissl.rb +18 -2
- data/lib/puma/null_io.rb +0 -0
- data/lib/puma/plugin/tmp_restart.rb +0 -0
- data/lib/puma/plugin.rb +1 -1
- data/lib/puma/puma_http11.jar +0 -0
- data/lib/puma/queue_close.rb +0 -0
- data/lib/puma/rack/builder.rb +0 -0
- data/lib/puma/rack/urlmap.rb +0 -0
- data/lib/puma/rack_default.rb +0 -0
- data/lib/puma/reactor.rb +0 -0
- data/lib/puma/request.rb +47 -29
- data/lib/puma/runner.rb +3 -2
- data/lib/puma/server.rb +29 -33
- data/lib/puma/single.rb +0 -0
- data/lib/puma/state_file.rb +41 -7
- data/lib/puma/systemd.rb +0 -0
- data/lib/puma/thread_pool.rb +2 -2
- data/lib/puma/util.rb +0 -0
- data/lib/puma.rb +0 -0
- data/lib/rack/handler/puma.rb +0 -0
- data/tools/Dockerfile +1 -1
- data/tools/trickletest.rb +0 -0
- metadata +3 -3
data/lib/puma/cluster/worker.rb
CHANGED
@@ -33,8 +33,8 @@ module Puma
|
|
33
33
|
Signal.trap "SIGINT", "IGNORE"
|
34
34
|
Signal.trap "SIGCHLD", "DEFAULT"
|
35
35
|
|
36
|
-
|
37
|
-
Puma.set_thread_name "
|
36
|
+
Thread.new do
|
37
|
+
Puma.set_thread_name "wrkr check"
|
38
38
|
@check_pipe.wait_readable
|
39
39
|
log "! Detected parent died, dying"
|
40
40
|
exit! 1
|
@@ -76,7 +76,7 @@ module Puma
|
|
76
76
|
end
|
77
77
|
|
78
78
|
Thread.new do
|
79
|
-
Puma.set_thread_name "
|
79
|
+
Puma.set_thread_name "wrkr fork"
|
80
80
|
while (idx = @fork_pipe.gets)
|
81
81
|
idx = idx.to_i
|
82
82
|
if idx == -1 # stop server
|
@@ -114,7 +114,7 @@ module Puma
|
|
114
114
|
while restart_server.pop
|
115
115
|
server_thread = server.run
|
116
116
|
stat_thread ||= Thread.new(@worker_write) do |io|
|
117
|
-
Puma.set_thread_name "stat
|
117
|
+
Puma.set_thread_name "stat pld"
|
118
118
|
base_payload = "p#{Process.pid}"
|
119
119
|
|
120
120
|
while true
|
@@ -130,7 +130,7 @@ module Puma
|
|
130
130
|
Puma::Util.purge_interrupt_queue
|
131
131
|
break
|
132
132
|
end
|
133
|
-
sleep
|
133
|
+
sleep @options[:worker_check_interval]
|
134
134
|
end
|
135
135
|
end
|
136
136
|
server_thread.join
|
data/lib/puma/cluster.rb
CHANGED
@@ -108,24 +108,42 @@ module Puma
|
|
108
108
|
def cull_workers
|
109
109
|
diff = @workers.size - @options[:workers]
|
110
110
|
return if diff < 1
|
111
|
+
debug "Culling #{diff} workers"
|
111
112
|
|
112
|
-
|
113
|
+
workers = workers_to_cull(diff)
|
114
|
+
debug "Workers to cull: #{workers.inspect}"
|
113
115
|
|
114
|
-
|
115
|
-
debug "Workers to cull: #{workers_to_cull.inspect}"
|
116
|
-
|
117
|
-
workers_to_cull.each do |worker|
|
116
|
+
workers.each do |worker|
|
118
117
|
log "- Worker #{worker.index} (PID: #{worker.pid}) terminating"
|
119
118
|
worker.term
|
120
119
|
end
|
121
120
|
end
|
122
121
|
|
122
|
+
def workers_to_cull(diff)
|
123
|
+
workers = @workers.sort_by(&:started_at)
|
124
|
+
|
125
|
+
# In fork_worker mode, worker 0 acts as our master process.
|
126
|
+
# We should avoid culling it to preserve copy-on-write memory gains.
|
127
|
+
workers.reject! { |w| w.index == 0 } if @options[:fork_worker]
|
128
|
+
|
129
|
+
workers[cull_start_index(diff), diff]
|
130
|
+
end
|
131
|
+
|
132
|
+
def cull_start_index(diff)
|
133
|
+
case @options[:worker_culling_strategy]
|
134
|
+
when :oldest
|
135
|
+
0
|
136
|
+
else # :youngest
|
137
|
+
-diff
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
123
141
|
# @!attribute [r] next_worker_index
|
124
142
|
def next_worker_index
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
143
|
+
occupied_positions = @workers.map(&:index)
|
144
|
+
idx = 0
|
145
|
+
idx += 1 until !occupied_positions.include?(idx)
|
146
|
+
idx
|
129
147
|
end
|
130
148
|
|
131
149
|
def all_workers_booted?
|
@@ -135,7 +153,7 @@ module Puma
|
|
135
153
|
def check_workers
|
136
154
|
return if @next_check >= Time.now
|
137
155
|
|
138
|
-
@next_check = Time.now +
|
156
|
+
@next_check = Time.now + @options[:worker_check_interval]
|
139
157
|
|
140
158
|
timeout_workers
|
141
159
|
wait_workers
|
@@ -440,7 +458,7 @@ module Puma
|
|
440
458
|
workers_not_booted -= 1
|
441
459
|
when "e"
|
442
460
|
# external term, see worker method, Signal.trap "SIGTERM"
|
443
|
-
w.
|
461
|
+
w.term!
|
444
462
|
when "t"
|
445
463
|
w.term unless w.term?
|
446
464
|
when "p"
|
data/lib/puma/commonlogger.rb
CHANGED
File without changes
|
data/lib/puma/configuration.rb
CHANGED
@@ -11,6 +11,7 @@ module Puma
|
|
11
11
|
|
12
12
|
DefaultTCPHost = "0.0.0.0"
|
13
13
|
DefaultTCPPort = 9292
|
14
|
+
DefaultWorkerCheckInterval = 5
|
14
15
|
DefaultWorkerTimeout = 60
|
15
16
|
DefaultWorkerShutdownTimeout = 30
|
16
17
|
end
|
@@ -195,9 +196,11 @@ module Puma
|
|
195
196
|
:workers => Integer(ENV['WEB_CONCURRENCY'] || 0),
|
196
197
|
:silence_single_worker_warning => false,
|
197
198
|
:mode => :http,
|
199
|
+
:worker_check_interval => DefaultWorkerCheckInterval,
|
198
200
|
:worker_timeout => DefaultWorkerTimeout,
|
199
201
|
:worker_boot_timeout => DefaultWorkerTimeout,
|
200
202
|
:worker_shutdown_timeout => DefaultWorkerShutdownTimeout,
|
203
|
+
:worker_culling_strategy => :youngest,
|
201
204
|
:remote_address => :socket,
|
202
205
|
:tag => method(:infer_tag),
|
203
206
|
:environment => -> { ENV['APP_ENV'] || ENV['RACK_ENV'] || ENV['RAILS_ENV'] || 'development' },
|
data/lib/puma/const.rb
CHANGED
@@ -100,8 +100,8 @@ module Puma
|
|
100
100
|
# too taxing on performance.
|
101
101
|
module Const
|
102
102
|
|
103
|
-
PUMA_VERSION = VERSION = "5.
|
104
|
-
CODE_NAME = "
|
103
|
+
PUMA_VERSION = VERSION = "5.6.0".freeze
|
104
|
+
CODE_NAME = "Birdie's Version".freeze
|
105
105
|
|
106
106
|
PUMA_SERVER_STRING = ['puma', PUMA_VERSION, CODE_NAME].join(' ').freeze
|
107
107
|
|
@@ -235,9 +235,6 @@ module Puma
|
|
235
235
|
|
236
236
|
EARLY_HINTS = "rack.early_hints".freeze
|
237
237
|
|
238
|
-
# Minimum interval to checks worker health
|
239
|
-
WORKER_CHECK_INTERVAL = 5
|
240
|
-
|
241
238
|
# Illegal character in the key or value of response header
|
242
239
|
DQUOTE = "\"".freeze
|
243
240
|
HTTP_HEADER_DELIMITER = Regexp.escape("(),/:;<=>?@[]{}\\").freeze
|
data/lib/puma/control_cli.rb
CHANGED
File without changes
|
data/lib/puma/detect.rb
CHANGED
@@ -10,8 +10,10 @@ module Puma
|
|
10
10
|
|
11
11
|
IS_JRUBY = Object.const_defined? :JRUBY_VERSION
|
12
12
|
|
13
|
-
|
14
|
-
|
13
|
+
IS_OSX = RUBY_PLATFORM.include? 'darwin'
|
14
|
+
|
15
|
+
IS_WINDOWS = !!(RUBY_PLATFORM =~ /mswin|ming|cygwin/) ||
|
16
|
+
IS_JRUBY && RUBY_DESCRIPTION.include?('mswin')
|
15
17
|
|
16
18
|
# @version 5.2.0
|
17
19
|
IS_MRI = (RUBY_ENGINE == 'ruby' || RUBY_ENGINE.nil?)
|
@@ -20,6 +22,10 @@ module Puma
|
|
20
22
|
IS_JRUBY
|
21
23
|
end
|
22
24
|
|
25
|
+
def self.osx?
|
26
|
+
IS_OSX
|
27
|
+
end
|
28
|
+
|
23
29
|
def self.windows?
|
24
30
|
IS_WINDOWS
|
25
31
|
end
|
data/lib/puma/dsl.rb
CHANGED
@@ -48,6 +48,8 @@ module Puma
|
|
48
48
|
|
49
49
|
ca_additions = "&ca=#{opts[:ca]}" if ['peer', 'force_peer'].include?(verify)
|
50
50
|
|
51
|
+
backlog_str = opts[:backlog] ? "&backlog=#{Integer(opts[:backlog])}" : ''
|
52
|
+
|
51
53
|
if defined?(JRUBY_VERSION)
|
52
54
|
ssl_cipher_list = opts[:ssl_cipher_list] ?
|
53
55
|
"&ssl_cipher_list=#{opts[:ssl_cipher_list]}" : nil
|
@@ -55,7 +57,7 @@ module Puma
|
|
55
57
|
keystore_additions = "keystore=#{opts[:keystore]}&keystore-pass=#{opts[:keystore_pass]}"
|
56
58
|
|
57
59
|
"ssl://#{host}:#{port}?#{keystore_additions}#{ssl_cipher_list}" \
|
58
|
-
"&verify_mode=#{verify}#{tls_str}#{ca_additions}"
|
60
|
+
"&verify_mode=#{verify}#{tls_str}#{ca_additions}#{backlog_str}"
|
59
61
|
else
|
60
62
|
ssl_cipher_filter = opts[:ssl_cipher_filter] ?
|
61
63
|
"&ssl_cipher_filter=#{opts[:ssl_cipher_filter]}" : nil
|
@@ -64,7 +66,7 @@ module Puma
|
|
64
66
|
"&verification_flags=#{Array(ary).join ','}" : nil
|
65
67
|
|
66
68
|
"ssl://#{host}:#{port}?cert=#{opts[:cert]}&key=#{opts[:key]}" \
|
67
|
-
"#{ssl_cipher_filter}&verify_mode=#{verify}#{tls_str}#{ca_additions}#{v_flags}"
|
69
|
+
"#{ssl_cipher_filter}&verify_mode=#{verify}#{tls_str}#{ca_additions}#{v_flags}#{backlog_str}"
|
68
70
|
end
|
69
71
|
end
|
70
72
|
|
@@ -191,7 +193,7 @@ module Puma
|
|
191
193
|
end
|
192
194
|
|
193
195
|
# Bind the server to +url+. "tcp://", "unix://" and "ssl://" are the only
|
194
|
-
# accepted protocols. Multiple urls can be bound to, calling
|
196
|
+
# accepted protocols. Multiple urls can be bound to, calling +bind+ does
|
195
197
|
# not overwrite previous bindings.
|
196
198
|
#
|
197
199
|
# The default is "tcp://0.0.0.0:9292".
|
@@ -436,8 +438,15 @@ module Puma
|
|
436
438
|
@options[:max_threads] = max
|
437
439
|
end
|
438
440
|
|
439
|
-
# Instead of
|
440
|
-
#
|
441
|
+
# Instead of using +bind+ and manually constructing a URI like:
|
442
|
+
#
|
443
|
+
# bind 'ssl://127.0.0.1:9292?key=key_path&cert=cert_path'
|
444
|
+
#
|
445
|
+
# you can use the this method.
|
446
|
+
#
|
447
|
+
# When binding on localhost you don't need to specify +cert+ and +key+,
|
448
|
+
# Puma will assume you are using the +localhost+ gem and try to load the
|
449
|
+
# appropriate files.
|
441
450
|
#
|
442
451
|
# @example
|
443
452
|
# ssl_bind '127.0.0.1', '9292', {
|
@@ -447,14 +456,25 @@ module Puma
|
|
447
456
|
# verify_mode: verify_mode, # default 'none'
|
448
457
|
# verification_flags: flags, # optional, not supported by JRuby
|
449
458
|
# }
|
450
|
-
#
|
459
|
+
#
|
460
|
+
# @example Using self-signed certificate with the +localhost+ gem:
|
461
|
+
# ssl_bind '127.0.0.1', '9292'
|
462
|
+
#
|
463
|
+
# @example Alternatively, you can provide +cert_pem+ and +key_pem+:
|
464
|
+
# ssl_bind '127.0.0.1', '9292', {
|
465
|
+
# cert_pem: File.read(path_to_cert),
|
466
|
+
# key_pem: File.read(path_to_key),
|
467
|
+
# }
|
468
|
+
#
|
469
|
+
# @example For JRuby, two keys are required: +keystore+ & +keystore_pass+
|
451
470
|
# ssl_bind '127.0.0.1', '9292', {
|
452
471
|
# keystore: path_to_keystore,
|
453
472
|
# keystore_pass: password,
|
454
473
|
# ssl_cipher_list: cipher_list, # optional
|
455
474
|
# verify_mode: verify_mode # default 'none'
|
456
475
|
# }
|
457
|
-
def ssl_bind(host, port, opts)
|
476
|
+
def ssl_bind(host, port, opts = {})
|
477
|
+
add_pem_values_to_options_store(opts)
|
458
478
|
bind self.class.ssl_bind_str(host, port, opts)
|
459
479
|
end
|
460
480
|
|
@@ -727,6 +747,19 @@ module Puma
|
|
727
747
|
@options[:tag] = string.to_s
|
728
748
|
end
|
729
749
|
|
750
|
+
# Change the default interval for checking workers.
|
751
|
+
#
|
752
|
+
# The default value is 5 seconds.
|
753
|
+
#
|
754
|
+
# @note Cluster mode only.
|
755
|
+
# @example
|
756
|
+
# worker_check_interval 5
|
757
|
+
# @see Puma::Cluster#check_workers
|
758
|
+
#
|
759
|
+
def worker_check_interval(interval)
|
760
|
+
@options[:worker_check_interval] = Integer(interval)
|
761
|
+
end
|
762
|
+
|
730
763
|
# Verifies that all workers have checked in to the master process within
|
731
764
|
# the given timeout. If not the worker process will be restarted. This is
|
732
765
|
# not a request timeout, it is to protect against a hung or dead process.
|
@@ -741,7 +774,7 @@ module Puma
|
|
741
774
|
#
|
742
775
|
def worker_timeout(timeout)
|
743
776
|
timeout = Integer(timeout)
|
744
|
-
min =
|
777
|
+
min = @options.fetch(:worker_check_interval, Puma::ConfigDefault::DefaultWorkerCheckInterval)
|
745
778
|
|
746
779
|
if timeout <= min
|
747
780
|
raise "The minimum worker_timeout must be greater than the worker reporting interval (#{min})"
|
@@ -773,6 +806,30 @@ module Puma
|
|
773
806
|
@options[:worker_shutdown_timeout] = Integer(timeout)
|
774
807
|
end
|
775
808
|
|
809
|
+
# Set the strategy for worker culling.
|
810
|
+
#
|
811
|
+
# There are two possible values:
|
812
|
+
#
|
813
|
+
# 1. **:youngest** - the youngest workers (i.e. the workers that were
|
814
|
+
# the most recently started) will be culled.
|
815
|
+
# 2. **:oldest** - the oldest workers (i.e. the workers that were started
|
816
|
+
# the longest time ago) will be culled.
|
817
|
+
#
|
818
|
+
# @note Cluster mode only.
|
819
|
+
# @example
|
820
|
+
# worker_culling_strategy :oldest
|
821
|
+
# @see Puma::Cluster#cull_workers
|
822
|
+
#
|
823
|
+
def worker_culling_strategy(strategy)
|
824
|
+
stategy = strategy.to_sym
|
825
|
+
|
826
|
+
if ![:youngest, :oldest].include?(strategy)
|
827
|
+
raise "Invalid value for worker_culling_strategy - #{stategy}"
|
828
|
+
end
|
829
|
+
|
830
|
+
@options[:worker_culling_strategy] = strategy
|
831
|
+
end
|
832
|
+
|
776
833
|
# When set to true (the default), workers accept all requests
|
777
834
|
# and queue them before passing them to the handlers.
|
778
835
|
# When set to false, each worker process accepts exactly as
|
@@ -927,5 +984,25 @@ module Puma
|
|
927
984
|
def mutate_stdout_and_stderr_to_sync_on_write(enabled=true)
|
928
985
|
@options[:mutate_stdout_and_stderr_to_sync_on_write] = enabled
|
929
986
|
end
|
987
|
+
|
988
|
+
private
|
989
|
+
|
990
|
+
# To avoid adding cert_pem and key_pem as URI params, we store them on the
|
991
|
+
# options[:store] from where Puma binder knows how to find and extract them.
|
992
|
+
def add_pem_values_to_options_store(opts)
|
993
|
+
return if defined?(JRUBY_VERSION)
|
994
|
+
|
995
|
+
@options[:store] ||= []
|
996
|
+
|
997
|
+
# Store cert_pem and key_pem to options[:store] if present
|
998
|
+
[:cert, :key].each do |v|
|
999
|
+
opt_key = :"#{v}_pem"
|
1000
|
+
if opts[opt_key]
|
1001
|
+
index = @options[:store].length
|
1002
|
+
@options[:store] << opts[opt_key]
|
1003
|
+
opts[v] = "store:#{index}"
|
1004
|
+
end
|
1005
|
+
end
|
1006
|
+
end
|
930
1007
|
end
|
931
1008
|
end
|
data/lib/puma/error_logger.rb
CHANGED
File without changes
|
data/lib/puma/events.rb
CHANGED
File without changes
|
data/lib/puma/io_buffer.rb
CHANGED
File without changes
|
data/lib/puma/jruby_restart.rb
CHANGED
File without changes
|
File without changes
|
data/lib/puma/launcher.rb
CHANGED
@@ -15,6 +15,7 @@ module Puma
|
|
15
15
|
# It is responsible for either launching a cluster of Puma workers or a single
|
16
16
|
# puma server.
|
17
17
|
class Launcher
|
18
|
+
# @deprecated 6.0.0
|
18
19
|
KEYS_NOT_TO_PERSIST_IN_STATE = [
|
19
20
|
:logger, :lowlevel_error_handler,
|
20
21
|
:before_worker_shutdown, :before_worker_boot, :before_worker_fork,
|
@@ -73,7 +74,7 @@ module Puma
|
|
73
74
|
|
74
75
|
generate_restart_data
|
75
76
|
|
76
|
-
if clustered? && !
|
77
|
+
if clustered? && !Puma.forkable?
|
77
78
|
unsupported "worker mode not supported on #{RUBY_ENGINE} on this platform"
|
78
79
|
end
|
79
80
|
|
@@ -23,17 +23,19 @@ module Puma
|
|
23
23
|
ctx.keystore_pass = params['keystore-pass']
|
24
24
|
ctx.ssl_cipher_list = params['ssl_cipher_list'] if params['ssl_cipher_list']
|
25
25
|
else
|
26
|
-
|
27
|
-
events.error "Please specify the SSL key via 'key='"
|
26
|
+
if params['key'].nil? && params['key_pem'].nil?
|
27
|
+
events.error "Please specify the SSL key via 'key=' or 'key_pem='"
|
28
28
|
end
|
29
29
|
|
30
|
-
ctx.key = params['key']
|
30
|
+
ctx.key = params['key'] if params['key']
|
31
|
+
ctx.key_pem = params['key_pem'] if params['key_pem']
|
31
32
|
|
32
|
-
|
33
|
-
events.error "Please specify the SSL cert via 'cert='"
|
33
|
+
if params['cert'].nil? && params['cert_pem'].nil?
|
34
|
+
events.error "Please specify the SSL cert via 'cert=' or 'cert_pem='"
|
34
35
|
end
|
35
36
|
|
36
|
-
ctx.cert = params['cert']
|
37
|
+
ctx.cert = params['cert'] if params['cert']
|
38
|
+
ctx.cert_pem = params['cert_pem'] if params['cert_pem']
|
37
39
|
|
38
40
|
if ['peer', 'force_peer'].include?(params['verify_mode'])
|
39
41
|
unless params['ca']
|
data/lib/puma/minissl.rb
CHANGED
@@ -208,6 +208,10 @@ module Puma
|
|
208
208
|
def initialize
|
209
209
|
@no_tlsv1 = false
|
210
210
|
@no_tlsv1_1 = false
|
211
|
+
@key = nil
|
212
|
+
@cert = nil
|
213
|
+
@key_pem = nil
|
214
|
+
@cert_pem = nil
|
211
215
|
end
|
212
216
|
|
213
217
|
if IS_JRUBY
|
@@ -230,6 +234,8 @@ module Puma
|
|
230
234
|
attr_reader :key
|
231
235
|
attr_reader :cert
|
232
236
|
attr_reader :ca
|
237
|
+
attr_reader :cert_pem
|
238
|
+
attr_reader :key_pem
|
233
239
|
attr_accessor :ssl_cipher_filter
|
234
240
|
attr_accessor :verification_flags
|
235
241
|
|
@@ -248,9 +254,19 @@ module Puma
|
|
248
254
|
@ca = ca
|
249
255
|
end
|
250
256
|
|
257
|
+
def cert_pem=(cert_pem)
|
258
|
+
raise ArgumentError, "'cert_pem' is not a String" unless cert_pem.is_a? String
|
259
|
+
@cert_pem = cert_pem
|
260
|
+
end
|
261
|
+
|
262
|
+
def key_pem=(key_pem)
|
263
|
+
raise ArgumentError, "'key_pem' is not a String" unless key_pem.is_a? String
|
264
|
+
@key_pem = key_pem
|
265
|
+
end
|
266
|
+
|
251
267
|
def check
|
252
|
-
raise "Key not configured"
|
253
|
-
raise "Cert not configured"
|
268
|
+
raise "Key not configured" if @key.nil? && @key_pem.nil?
|
269
|
+
raise "Cert not configured" if @cert.nil? && @cert_pem.nil?
|
254
270
|
end
|
255
271
|
end
|
256
272
|
|
data/lib/puma/null_io.rb
CHANGED
File without changes
|
File without changes
|
data/lib/puma/plugin.rb
CHANGED
data/lib/puma/puma_http11.jar
CHANGED
Binary file
|
data/lib/puma/queue_close.rb
CHANGED
File without changes
|
data/lib/puma/rack/builder.rb
CHANGED
File without changes
|
data/lib/puma/rack/urlmap.rb
CHANGED
File without changes
|
data/lib/puma/rack_default.rb
CHANGED
File without changes
|
data/lib/puma/reactor.rb
CHANGED
File without changes
|
data/lib/puma/request.rb
CHANGED
@@ -46,11 +46,7 @@ module Puma
|
|
46
46
|
env[HIJACK_P] = true
|
47
47
|
env[HIJACK] = client
|
48
48
|
|
49
|
-
|
50
|
-
|
51
|
-
head = env[REQUEST_METHOD] == HEAD
|
52
|
-
|
53
|
-
env[RACK_INPUT] = body
|
49
|
+
env[RACK_INPUT] = client.body
|
54
50
|
env[RACK_URL_SCHEME] ||= default_server_port(env) == PORT_443 ? HTTPS : HTTP
|
55
51
|
|
56
52
|
if @early_hints
|
@@ -69,36 +65,58 @@ module Puma
|
|
69
65
|
# A rack extension. If the app writes #call'ables to this
|
70
66
|
# array, we will invoke them when the request is done.
|
71
67
|
#
|
72
|
-
|
68
|
+
env[RACK_AFTER_REPLY] = []
|
73
69
|
|
74
70
|
begin
|
75
|
-
|
76
|
-
|
77
|
-
|
71
|
+
status, headers, res_body = @thread_pool.with_force_shutdown do
|
72
|
+
@app.call(env)
|
73
|
+
end
|
74
|
+
|
75
|
+
return :async if client.hijacked
|
76
|
+
|
77
|
+
status = status.to_i
|
78
|
+
|
79
|
+
if status == -1
|
80
|
+
unless headers.empty? and res_body == []
|
81
|
+
raise "async response must have empty headers and body"
|
78
82
|
end
|
79
83
|
|
80
|
-
return :async
|
84
|
+
return :async
|
85
|
+
end
|
86
|
+
rescue ThreadPool::ForceShutdown => e
|
87
|
+
@events.unknown_error e, client, "Rack app"
|
88
|
+
@events.log "Detected force shutdown of a thread"
|
81
89
|
|
82
|
-
|
90
|
+
status, headers, res_body = lowlevel_error(e, env, 503)
|
91
|
+
rescue Exception => e
|
92
|
+
@events.unknown_error e, client, "Rack app"
|
83
93
|
|
84
|
-
|
85
|
-
|
86
|
-
raise "async response must have empty headers and body"
|
87
|
-
end
|
94
|
+
status, headers, res_body = lowlevel_error(e, env, 500)
|
95
|
+
end
|
88
96
|
|
89
|
-
|
90
|
-
|
91
|
-
rescue ThreadPool::ForceShutdown => e
|
92
|
-
@events.unknown_error e, client, "Rack app"
|
93
|
-
@events.log "Detected force shutdown of a thread"
|
97
|
+
write_response(status, headers, res_body, lines, requests, client)
|
98
|
+
end
|
94
99
|
|
95
|
-
|
96
|
-
|
97
|
-
|
100
|
+
# Does the actual response writing for Request#handle_request and Server#client_error
|
101
|
+
#
|
102
|
+
# @param status [Integer] the status returned by the Rack application
|
103
|
+
# @param headers [Hash] the headers returned by the Rack application
|
104
|
+
# @param res_body [Array] the body returned by the Rack application
|
105
|
+
# @param lines [Puma::IOBuffer] modified in place
|
106
|
+
# @param requests [Integer] number of inline requests handled
|
107
|
+
# @param client [Puma::Client]
|
108
|
+
# @return [Boolean,:async]
|
109
|
+
def write_response(status, headers, res_body, lines, requests, client)
|
110
|
+
env = client.env
|
111
|
+
io = client.io
|
98
112
|
|
99
|
-
|
100
|
-
|
113
|
+
return false if closed_socket?(io)
|
114
|
+
lines.clear
|
101
115
|
|
116
|
+
head = env[REQUEST_METHOD] == HEAD
|
117
|
+
after_reply = env[RACK_AFTER_REPLY] || []
|
118
|
+
|
119
|
+
begin
|
102
120
|
res_info = {}
|
103
121
|
res_info[:content_length] = nil
|
104
122
|
res_info[:no_body] = head
|
@@ -149,9 +167,9 @@ module Puma
|
|
149
167
|
res_body.each do |part|
|
150
168
|
next if part.bytesize.zero?
|
151
169
|
if chunked
|
152
|
-
|
153
|
-
|
154
|
-
|
170
|
+
fast_write io, (part.bytesize.to_s(16) << line_ending)
|
171
|
+
fast_write io, part # part may have different encoding
|
172
|
+
fast_write io, line_ending
|
155
173
|
else
|
156
174
|
fast_write io, part
|
157
175
|
end
|
@@ -169,7 +187,7 @@ module Puma
|
|
169
187
|
ensure
|
170
188
|
uncork_socket io
|
171
189
|
|
172
|
-
body.close
|
190
|
+
client.body.close if client.body
|
173
191
|
client.tempfile.unlink if client.tempfile
|
174
192
|
res_body.close if res_body.respond_to? :close
|
175
193
|
|
data/lib/puma/runner.rb
CHANGED
@@ -69,7 +69,7 @@ module Puma
|
|
69
69
|
|
70
70
|
control.binder.parse [str], self, 'Starting control server'
|
71
71
|
|
72
|
-
control.run thread_name: '
|
72
|
+
control.run thread_name: 'ctl'
|
73
73
|
@control = control
|
74
74
|
end
|
75
75
|
|
@@ -94,12 +94,13 @@ module Puma
|
|
94
94
|
def output_header(mode)
|
95
95
|
min_t = @options[:min_threads]
|
96
96
|
max_t = @options[:max_threads]
|
97
|
+
environment = @options[:environment]
|
97
98
|
|
98
99
|
log "Puma starting in #{mode} mode..."
|
99
100
|
log "* Puma version: #{Puma::Const::PUMA_VERSION} (#{ruby_engine}) (\"#{Puma::Const::CODE_NAME}\")"
|
100
101
|
log "* Min threads: #{min_t}"
|
101
102
|
log "* Max threads: #{max_t}"
|
102
|
-
log "* Environment: #{
|
103
|
+
log "* Environment: #{environment}"
|
103
104
|
|
104
105
|
if mode == "cluster"
|
105
106
|
log "* Master PID: #{Process.pid}"
|