puma 4.2.0 → 4.3.1
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 +25 -1
- data/README.md +5 -23
- data/docs/plugins.md +20 -10
- data/docs/tcp_mode.md +96 -0
- data/ext/puma_http11/extconf.rb +5 -0
- data/ext/puma_http11/http11_parser.java.rl +21 -37
- data/ext/puma_http11/org/jruby/puma/Http11.java +106 -114
- data/ext/puma_http11/org/jruby/puma/Http11Parser.java +91 -106
- data/ext/puma_http11/puma_http11.c +2 -0
- data/lib/puma/binder.rb +7 -61
- data/lib/puma/cli.rb +1 -1
- data/lib/puma/client.rb +3 -3
- data/lib/puma/cluster.rb +0 -1
- data/lib/puma/const.rb +9 -2
- data/lib/puma/control_cli.rb +11 -3
- data/lib/puma/dsl.rb +5 -3
- data/lib/puma/launcher.rb +1 -4
- data/lib/puma/minissl/context_builder.rb +76 -0
- data/lib/puma/reactor.rb +2 -1
- data/lib/puma/runner.rb +7 -0
- data/lib/puma/server.rb +18 -7
- data/lib/puma/single.rb +0 -1
- data/lib/puma/thread_pool.rb +1 -1
- metadata +4 -4
- data/lib/puma/convenient.rb +0 -25
- data/lib/puma/delegation.rb +0 -13
data/lib/puma/cli.rb
CHANGED
@@ -162,7 +162,7 @@ module Puma
|
|
162
162
|
end
|
163
163
|
|
164
164
|
o.on "--extra-runtime-dependencies GEM1,GEM2", "Defines any extra needed gems when using --prune-bundler" do |arg|
|
165
|
-
|
165
|
+
user_config.extra_runtime_dependencies arg.split(',')
|
166
166
|
end
|
167
167
|
|
168
168
|
o.on "-q", "--quiet", "Do not log requests internally (default true)" do
|
data/lib/puma/client.rb
CHANGED
@@ -9,8 +9,8 @@ class IO
|
|
9
9
|
end
|
10
10
|
|
11
11
|
require 'puma/detect'
|
12
|
-
require 'puma/delegation'
|
13
12
|
require 'tempfile'
|
13
|
+
require 'forwardable'
|
14
14
|
|
15
15
|
if Puma::IS_JRUBY
|
16
16
|
# We have to work around some OpenSSL buffer/io-readiness bugs
|
@@ -41,7 +41,7 @@ module Puma
|
|
41
41
|
EmptyBody = NullIO.new
|
42
42
|
|
43
43
|
include Puma::Const
|
44
|
-
extend
|
44
|
+
extend Forwardable
|
45
45
|
|
46
46
|
def initialize(io, env=nil)
|
47
47
|
@io = io
|
@@ -83,7 +83,7 @@ module Puma
|
|
83
83
|
|
84
84
|
attr_accessor :remote_addr_header
|
85
85
|
|
86
|
-
|
86
|
+
def_delegators :@io, :closed?
|
87
87
|
|
88
88
|
def inspect
|
89
89
|
"#<Puma::Client:0x#{object_id.to_s(16)} @ready=#{@ready.inspect}>"
|
data/lib/puma/cluster.rb
CHANGED
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 = "4.
|
104
|
-
CODE_NAME = "
|
103
|
+
PUMA_VERSION = VERSION = "4.3.1".freeze
|
104
|
+
CODE_NAME = "Mysterious Traveller".freeze
|
105
105
|
PUMA_SERVER_STRING = ['puma', PUMA_VERSION, CODE_NAME].join(' ').freeze
|
106
106
|
|
107
107
|
FAST_TRACK_KA_TIMEOUT = 0.2
|
@@ -118,6 +118,13 @@ module Puma
|
|
118
118
|
# sending data back
|
119
119
|
WRITE_TIMEOUT = 10
|
120
120
|
|
121
|
+
# How many requests to attempt inline before sending a client back to
|
122
|
+
# the reactor to be subject to normal ordering. The idea here is that
|
123
|
+
# we amortize the cost of going back to the reactor for a well behaved
|
124
|
+
# but very "greedy" client across 10 requests. This prevents a not
|
125
|
+
# well behaved client from monopolizing the thread forever.
|
126
|
+
MAX_FAST_INLINE = 10
|
127
|
+
|
121
128
|
# The original URI requested by the client.
|
122
129
|
REQUEST_URI= 'REQUEST_URI'.freeze
|
123
130
|
REQUEST_PATH = 'REQUEST_PATH'.freeze
|
data/lib/puma/control_cli.rb
CHANGED
@@ -22,7 +22,7 @@ module Puma
|
|
22
22
|
@control_auth_token = nil
|
23
23
|
@config_file = nil
|
24
24
|
@command = nil
|
25
|
-
@environment = ENV['RACK_ENV']
|
25
|
+
@environment = ENV['RACK_ENV']
|
26
26
|
|
27
27
|
@argv = argv.dup
|
28
28
|
@stdout = stdout
|
@@ -82,8 +82,10 @@ module Puma
|
|
82
82
|
@command = argv.shift
|
83
83
|
|
84
84
|
unless @config_file == '-'
|
85
|
+
environment = @environment || 'development'
|
86
|
+
|
85
87
|
if @config_file.nil?
|
86
|
-
@config_file = %W(config/puma/#{
|
88
|
+
@config_file = %W(config/puma/#{environment}.rb config/puma.rb).find do |f|
|
87
89
|
File.exist?(f)
|
88
90
|
end
|
89
91
|
end
|
@@ -130,7 +132,7 @@ module Puma
|
|
130
132
|
@pid = sf.pid
|
131
133
|
elsif @pidfile
|
132
134
|
# get pid from pid_file
|
133
|
-
|
135
|
+
File.open(@pidfile) { |f| @pid = f.read.to_i }
|
134
136
|
end
|
135
137
|
end
|
136
138
|
|
@@ -139,6 +141,12 @@ module Puma
|
|
139
141
|
|
140
142
|
# create server object by scheme
|
141
143
|
server = case uri.scheme
|
144
|
+
when "ssl"
|
145
|
+
require 'openssl'
|
146
|
+
OpenSSL::SSL::SSLSocket.new(
|
147
|
+
TCPSocket.new(uri.host, uri.port),
|
148
|
+
OpenSSL::SSL::SSLContext.new
|
149
|
+
).tap(&:connect)
|
142
150
|
when "tcp"
|
143
151
|
TCPSocket.new uri.host, uri.port
|
144
152
|
when "unix"
|
data/lib/puma/dsl.rb
CHANGED
@@ -396,7 +396,7 @@ module Puma
|
|
396
396
|
# keystore_pass: password
|
397
397
|
# }
|
398
398
|
def ssl_bind(host, port, opts)
|
399
|
-
verify = opts.fetch(:verify_mode, 'none')
|
399
|
+
verify = opts.fetch(:verify_mode, 'none').to_s
|
400
400
|
no_tlsv1 = opts.fetch(:no_tlsv1, 'false')
|
401
401
|
no_tlsv1_1 = opts.fetch(:no_tlsv1_1, 'false')
|
402
402
|
ca_additions = "&ca=#{opts[:ca]}" if ['peer', 'force_peer'].include?(verify)
|
@@ -583,6 +583,8 @@ module Puma
|
|
583
583
|
# new Bundler context and thus can float around as the release
|
584
584
|
# dictates.
|
585
585
|
#
|
586
|
+
# See also: extra_runtime_dependencies
|
587
|
+
#
|
586
588
|
# @note This is incompatible with +preload_app!+.
|
587
589
|
# @note This is only supported for RubyGems 2.2+
|
588
590
|
def prune_bundler(answer=true)
|
@@ -603,7 +605,7 @@ module Puma
|
|
603
605
|
end
|
604
606
|
|
605
607
|
# When using prune_bundler, if extra runtime dependencies need to be loaded to
|
606
|
-
# initialize your app, then this setting can be used.
|
608
|
+
# initialize your app, then this setting can be used. This includes any Puma plugins.
|
607
609
|
#
|
608
610
|
# Before bundler is pruned, the gem names supplied will be looked up in the bundler
|
609
611
|
# context and then loaded again after bundler is pruned.
|
@@ -612,7 +614,7 @@ module Puma
|
|
612
614
|
# @example
|
613
615
|
# extra_runtime_dependencies ['gem_name_1', 'gem_name_2']
|
614
616
|
# @example
|
615
|
-
# extra_runtime_dependencies ['puma_worker_killer']
|
617
|
+
# extra_runtime_dependencies ['puma_worker_killer', 'puma-heroku']
|
616
618
|
def extra_runtime_dependencies(answer = [])
|
617
619
|
@options[:extra_runtime_dependencies] = Array(answer)
|
618
620
|
end
|
data/lib/puma/launcher.rb
CHANGED
@@ -184,6 +184,7 @@ module Puma
|
|
184
184
|
when :exit
|
185
185
|
# nothing
|
186
186
|
end
|
187
|
+
@binder.close_unix_paths
|
187
188
|
end
|
188
189
|
|
189
190
|
# Return which tcp port the launcher is using, if it's using TCP
|
@@ -204,10 +205,6 @@ module Puma
|
|
204
205
|
@binder.close_listeners
|
205
206
|
end
|
206
207
|
|
207
|
-
def close_binder_unix_paths
|
208
|
-
@binder.close_unix_paths
|
209
|
-
end
|
210
|
-
|
211
208
|
private
|
212
209
|
|
213
210
|
# If configured, write the pid of the current process out
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module Puma
|
2
|
+
module MiniSSL
|
3
|
+
class ContextBuilder
|
4
|
+
def initialize(params, events)
|
5
|
+
require 'puma/minissl'
|
6
|
+
MiniSSL.check
|
7
|
+
|
8
|
+
@params = params
|
9
|
+
@events = events
|
10
|
+
end
|
11
|
+
|
12
|
+
def context
|
13
|
+
ctx = MiniSSL::Context.new
|
14
|
+
|
15
|
+
if defined?(JRUBY_VERSION)
|
16
|
+
unless params['keystore']
|
17
|
+
events.error "Please specify the Java keystore via 'keystore='"
|
18
|
+
end
|
19
|
+
|
20
|
+
ctx.keystore = params['keystore']
|
21
|
+
|
22
|
+
unless params['keystore-pass']
|
23
|
+
events.error "Please specify the Java keystore password via 'keystore-pass='"
|
24
|
+
end
|
25
|
+
|
26
|
+
ctx.keystore_pass = params['keystore-pass']
|
27
|
+
ctx.ssl_cipher_list = params['ssl_cipher_list'] if params['ssl_cipher_list']
|
28
|
+
else
|
29
|
+
unless params['key']
|
30
|
+
events.error "Please specify the SSL key via 'key='"
|
31
|
+
end
|
32
|
+
|
33
|
+
ctx.key = params['key']
|
34
|
+
|
35
|
+
unless params['cert']
|
36
|
+
events.error "Please specify the SSL cert via 'cert='"
|
37
|
+
end
|
38
|
+
|
39
|
+
ctx.cert = params['cert']
|
40
|
+
|
41
|
+
if ['peer', 'force_peer'].include?(params['verify_mode'])
|
42
|
+
unless params['ca']
|
43
|
+
events.error "Please specify the SSL ca via 'ca='"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
ctx.ca = params['ca'] if params['ca']
|
48
|
+
ctx.ssl_cipher_filter = params['ssl_cipher_filter'] if params['ssl_cipher_filter']
|
49
|
+
end
|
50
|
+
|
51
|
+
ctx.no_tlsv1 = true if params['no_tlsv1'] == 'true'
|
52
|
+
ctx.no_tlsv1_1 = true if params['no_tlsv1_1'] == 'true'
|
53
|
+
|
54
|
+
if params['verify_mode']
|
55
|
+
ctx.verify_mode = case params['verify_mode']
|
56
|
+
when "peer"
|
57
|
+
MiniSSL::VERIFY_PEER
|
58
|
+
when "force_peer"
|
59
|
+
MiniSSL::VERIFY_PEER | MiniSSL::VERIFY_FAIL_IF_NO_PEER_CERT
|
60
|
+
when "none"
|
61
|
+
MiniSSL::VERIFY_NONE
|
62
|
+
else
|
63
|
+
events.error "Please specify a valid verify_mode="
|
64
|
+
MiniSSL::VERIFY_NONE
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
ctx
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
attr_reader :params, :events
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
data/lib/puma/reactor.rb
CHANGED
data/lib/puma/runner.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'puma/server'
|
4
4
|
require 'puma/const'
|
5
|
+
require 'puma/minissl/context_builder'
|
5
6
|
|
6
7
|
module Puma
|
7
8
|
# Generic class that is used by `Puma::Cluster` and `Puma::Single` to
|
@@ -64,6 +65,12 @@ module Puma
|
|
64
65
|
control.max_threads = 1
|
65
66
|
|
66
67
|
case uri.scheme
|
68
|
+
when "ssl"
|
69
|
+
log "* Starting control server on #{str}"
|
70
|
+
params = Util.parse_query uri.query
|
71
|
+
ctx = MiniSSL::ContextBuilder.new(params, @events).context
|
72
|
+
|
73
|
+
control.add_ssl_listener uri.host, uri.port, ctx
|
67
74
|
when "tcp"
|
68
75
|
log "* Starting control server on #{str}"
|
69
76
|
control.add_tcp_listener uri.host, uri.port
|
data/lib/puma/server.rb
CHANGED
@@ -9,13 +9,13 @@ require 'puma/null_io'
|
|
9
9
|
require 'puma/reactor'
|
10
10
|
require 'puma/client'
|
11
11
|
require 'puma/binder'
|
12
|
-
require 'puma/delegation'
|
13
12
|
require 'puma/accept_nonblock'
|
14
13
|
require 'puma/util'
|
15
14
|
|
16
15
|
require 'puma/puma_http11'
|
17
16
|
|
18
17
|
require 'socket'
|
18
|
+
require 'forwardable'
|
19
19
|
|
20
20
|
module Puma
|
21
21
|
|
@@ -32,7 +32,7 @@ module Puma
|
|
32
32
|
class Server
|
33
33
|
|
34
34
|
include Puma::Const
|
35
|
-
extend
|
35
|
+
extend Forwardable
|
36
36
|
|
37
37
|
attr_reader :thread
|
38
38
|
attr_reader :events
|
@@ -89,10 +89,7 @@ module Puma
|
|
89
89
|
|
90
90
|
attr_accessor :binder, :leak_stack_on_error, :early_hints
|
91
91
|
|
92
|
-
|
93
|
-
forward :add_ssl_listener, :@binder
|
94
|
-
forward :add_unix_listener, :@binder
|
95
|
-
forward :connected_port, :@binder
|
92
|
+
def_delegators :@binder, :add_tcp_listener, :add_ssl_listener, :add_unix_listener, :connected_port
|
96
93
|
|
97
94
|
def inherit_binder(bind)
|
98
95
|
@binder = bind
|
@@ -469,6 +466,8 @@ module Puma
|
|
469
466
|
clean_thread_locals = @options[:clean_thread_locals]
|
470
467
|
close_socket = true
|
471
468
|
|
469
|
+
requests = 0
|
470
|
+
|
472
471
|
while true
|
473
472
|
case handle_request(client, buffer)
|
474
473
|
when false
|
@@ -482,7 +481,19 @@ module Puma
|
|
482
481
|
|
483
482
|
ThreadPool.clean_thread_locals if clean_thread_locals
|
484
483
|
|
485
|
-
|
484
|
+
requests += 1
|
485
|
+
|
486
|
+
check_for_more_data = @status == :run
|
487
|
+
|
488
|
+
if requests >= MAX_FAST_INLINE
|
489
|
+
# This will mean that reset will only try to use the data it already
|
490
|
+
# has buffered and won't try to read more data. What this means is that
|
491
|
+
# every client, independent of their request speed, gets treated like a slow
|
492
|
+
# one once every MAX_FAST_INLINE requests.
|
493
|
+
check_for_more_data = false
|
494
|
+
end
|
495
|
+
|
496
|
+
unless client.reset(check_for_more_data)
|
486
497
|
close_socket = false
|
487
498
|
client.set_timeout @persistent_timeout
|
488
499
|
@reactor.add client
|
data/lib/puma/single.rb
CHANGED
data/lib/puma/thread_pool.rb
CHANGED
@@ -189,7 +189,7 @@ module Puma
|
|
189
189
|
# request, it might not be added to the `@todo` array right away.
|
190
190
|
# For example if a slow client has only sent a header, but not a body
|
191
191
|
# then the `@todo` array would stay the same size as the reactor works
|
192
|
-
# to try to buffer the request. In
|
192
|
+
# to try to buffer the request. In that scenario the next call to this
|
193
193
|
# method would not block and another request would be added into the reactor
|
194
194
|
# by the server. This would continue until a fully bufferend request
|
195
195
|
# makes it through the reactor and can then be processed by the thread pool.
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: puma
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Evan Phoenix
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-12-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nio4r
|
@@ -53,6 +53,7 @@ files:
|
|
53
53
|
- docs/restart.md
|
54
54
|
- docs/signals.md
|
55
55
|
- docs/systemd.md
|
56
|
+
- docs/tcp_mode.md
|
56
57
|
- ext/puma_http11/PumaHttp11Service.java
|
57
58
|
- ext/puma_http11/ext_help.h
|
58
59
|
- ext/puma_http11/extconf.rb
|
@@ -79,8 +80,6 @@ files:
|
|
79
80
|
- lib/puma/configuration.rb
|
80
81
|
- lib/puma/const.rb
|
81
82
|
- lib/puma/control_cli.rb
|
82
|
-
- lib/puma/convenient.rb
|
83
|
-
- lib/puma/delegation.rb
|
84
83
|
- lib/puma/detect.rb
|
85
84
|
- lib/puma/dsl.rb
|
86
85
|
- lib/puma/events.rb
|
@@ -88,6 +87,7 @@ files:
|
|
88
87
|
- lib/puma/jruby_restart.rb
|
89
88
|
- lib/puma/launcher.rb
|
90
89
|
- lib/puma/minissl.rb
|
90
|
+
- lib/puma/minissl/context_builder.rb
|
91
91
|
- lib/puma/null_io.rb
|
92
92
|
- lib/puma/plugin.rb
|
93
93
|
- lib/puma/plugin/tmp_restart.rb
|
data/lib/puma/convenient.rb
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'puma/launcher'
|
4
|
-
require 'puma/configuration'
|
5
|
-
|
6
|
-
module Puma
|
7
|
-
def self.run(opts={})
|
8
|
-
cfg = Puma::Configuration.new do |user_config|
|
9
|
-
if port = opts[:port]
|
10
|
-
user_config.port port
|
11
|
-
end
|
12
|
-
|
13
|
-
user_config.quiet
|
14
|
-
|
15
|
-
yield c
|
16
|
-
end
|
17
|
-
|
18
|
-
cfg.clamp
|
19
|
-
|
20
|
-
events = Puma::Events.null
|
21
|
-
|
22
|
-
launcher = Puma::Launcher.new cfg, :events => events
|
23
|
-
launcher.run
|
24
|
-
end
|
25
|
-
end
|