puma 5.0.0.beta2-java → 5.0.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 +8 -0
- data/README.md +8 -1
- data/docs/signals.md +3 -3
- data/ext/puma_http11/mini_ssl.c +3 -0
- data/ext/puma_http11/no_ssl/PumaHttp11Service.java +15 -0
- data/ext/puma_http11/org/jruby/puma/MiniSSL.java +40 -12
- data/ext/puma_http11/puma_http11.c +4 -0
- data/lib/puma.rb +12 -0
- data/lib/puma/binder.rb +25 -8
- data/lib/puma/client.rb +3 -0
- data/lib/puma/cluster.rb +8 -0
- data/lib/puma/configuration.rb +1 -0
- data/lib/puma/const.rb +2 -1
- data/lib/puma/control_cli.rb +2 -0
- data/lib/puma/detect.rb +9 -0
- data/lib/puma/dsl.rb +74 -36
- data/lib/puma/error_logger.rb +1 -0
- data/lib/puma/events.rb +2 -0
- data/lib/puma/launcher.rb +3 -0
- data/lib/puma/minissl.rb +20 -15
- data/lib/puma/minissl/context_builder.rb +0 -3
- data/lib/puma/puma_http11.jar +0 -0
- data/lib/puma/reactor.rb +1 -1
- data/lib/puma/runner.rb +2 -1
- data/lib/puma/server.rb +5 -6
- data/lib/puma/thread_pool.rb +5 -1
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 57175cfb98319685a496220e92303e6c7827421de8569d0c1128b2f7d04d7a2a
|
4
|
+
data.tar.gz: 29c2a8c29628ca7732999005bad47ebcf071f1758dbf604a4bfa9ac5c063669d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 402feb9a877783c892bf9d1c441f7486961061c9de7182965ac50b60bc93de91ccb3e99bae102a3d0f337dd228017c69542d7812edad79515557ea2266ddb3bb
|
7
|
+
data.tar.gz: 2499c2971fd885aa8121076f1f4f8079add4eeed8dbb4157ac789747dc68794ef83f98222b8cc645542bfaa51379bee038bff64a514d1b1bfe1df4c7c3078e06
|
data/History.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
## 5.0.0
|
2
2
|
|
3
3
|
* Features
|
4
|
+
* Allow compiling without OpenSSL and dynamically load files needed for SSL, add 'no ssl' CI (#2305)
|
4
5
|
* EXPERIMENTAL: Add `fork_worker` option and `refork` command for reduced memory usage by forking from a worker process instead of the master process. (#2099)
|
5
6
|
* EXPERIMENTAL: Added `wait_for_less_busy_worker` config. This may reduce latency on MRI through inserting a small delay before re-listening on the socket if worker is busy (#2079).
|
6
7
|
* EXPERIMENTAL: Added `nakayoshi_fork` option. Reduce memory usage in preloaded cluster-mode apps by GCing before fork and compacting, where available. (#2093, #2256)
|
@@ -58,6 +59,7 @@
|
|
58
59
|
* Fix recursive `prune_bundler` (#2319).
|
59
60
|
* Ensure that TCP_CORK is usable
|
60
61
|
* Fix corner case when request body is chunked (#2326)
|
62
|
+
* Fix filehandle leak in MiniSSL (#2299)
|
61
63
|
|
62
64
|
* Refactor
|
63
65
|
* Remove unused loader argument from Plugin initializer (#2095)
|
@@ -70,6 +72,12 @@
|
|
70
72
|
* Support parallel tests in verbose progress reporting (#2223)
|
71
73
|
* Refactor error handling in server accept loop (#2239)
|
72
74
|
|
75
|
+
## 4.3.6 / 2020-09-05
|
76
|
+
|
77
|
+
* Bugfixes
|
78
|
+
* Explicitly include ctype.h to fix compilation warning and build error on macOS with Xcode 12 (#2304)
|
79
|
+
* Don't require json at boot (#2269)
|
80
|
+
|
73
81
|
## 4.3.4/4.3.5 and 3.12.5/3.12.6 / 2020-05-22
|
74
82
|
|
75
83
|
Each patchlevel release contains a separate security fix. We recommend simply upgrading to 4.3.5/3.12.6.
|
data/README.md
CHANGED
@@ -5,7 +5,6 @@
|
|
5
5
|
# Puma: A Ruby Web Server Built For Concurrency
|
6
6
|
|
7
7
|
[![Actions Build Status](https://github.com/puma/puma/workflows/CI/badge.svg?branch=master)](https://github.com/puma/puma/actions)
|
8
|
-
|
9
8
|
[![Code Climate](https://codeclimate.com/github/puma/puma.svg)](https://codeclimate.com/github/puma/puma)
|
10
9
|
[![SemVer](https://api.dependabot.com/badges/compatibility_score?dependency-name=puma&package-manager=bundler&version-scheme=semver)](https://dependabot.com/compatibility-score.html?dependency-name=puma&package-manager=bundler&version-scheme=semver)
|
11
10
|
[![StackOverflow](https://img.shields.io/badge/stackoverflow-Puma-blue.svg)]( https://stackoverflow.com/questions/tagged/puma )
|
@@ -30,6 +29,14 @@ $ puma
|
|
30
29
|
Without arguments, puma will look for a rackup (.ru) file in
|
31
30
|
working directory called `config.ru`.
|
32
31
|
|
32
|
+
## SSL Connection Support
|
33
|
+
|
34
|
+
Puma will install/compile with support for ssl sockets, assuming OpenSSL
|
35
|
+
development files are installed on the system.
|
36
|
+
|
37
|
+
If the system does not have OpenSSL development files installed, Puma will
|
38
|
+
install/compile, but it will not allow ssl connections.
|
39
|
+
|
33
40
|
## Frameworks
|
34
41
|
|
35
42
|
### Rails
|
data/docs/signals.md
CHANGED
@@ -38,10 +38,10 @@ Puma cluster responds to these signals:
|
|
38
38
|
- `TERM` send `TERM` to worker. Worker will attempt to finish then exit.
|
39
39
|
- `USR2` restart workers. This also reloads puma configuration file, if there is one.
|
40
40
|
- `USR1` restart workers in phases, a rolling restart. This will not reload configuration file.
|
41
|
-
- `HUP`
|
42
|
-
- `INT` equivalent of sending Ctrl-C to cluster. Will attempt to finish then exit.
|
41
|
+
- `HUP ` reopen log files defined in stdout_redirect configuration parameter. If there is no stdout_redirect option provided it will behave like `INT`
|
42
|
+
- `INT ` equivalent of sending Ctrl-C to cluster. Will attempt to finish then exit.
|
43
43
|
- `CHLD`
|
44
|
-
- `URG` refork workers in phases from worker 0, if `fork_workers` option is enabled.
|
44
|
+
- `URG ` refork workers in phases from worker 0, if `fork_workers` option is enabled.
|
45
45
|
|
46
46
|
## Callbacks order in case of different signals
|
47
47
|
|
data/ext/puma_http11/mini_ssl.c
CHANGED
@@ -0,0 +1,15 @@
|
|
1
|
+
package puma;
|
2
|
+
|
3
|
+
import java.io.IOException;
|
4
|
+
|
5
|
+
import org.jruby.Ruby;
|
6
|
+
import org.jruby.runtime.load.BasicLibraryService;
|
7
|
+
|
8
|
+
import org.jruby.puma.Http11;
|
9
|
+
|
10
|
+
public class PumaHttp11Service implements BasicLibraryService {
|
11
|
+
public boolean basicLoad(final Ruby runtime) throws IOException {
|
12
|
+
Http11.createHttp11(runtime);
|
13
|
+
return true;
|
14
|
+
}
|
15
|
+
}
|
@@ -22,6 +22,7 @@ import javax.net.ssl.SSLException;
|
|
22
22
|
import javax.net.ssl.SSLPeerUnverifiedException;
|
23
23
|
import javax.net.ssl.SSLSession;
|
24
24
|
import java.io.FileInputStream;
|
25
|
+
import java.io.InputStream;
|
25
26
|
import java.io.IOException;
|
26
27
|
import java.nio.Buffer;
|
27
28
|
import java.nio.ByteBuffer;
|
@@ -32,6 +33,8 @@ import java.security.NoSuchAlgorithmException;
|
|
32
33
|
import java.security.UnrecoverableKeyException;
|
33
34
|
import java.security.cert.CertificateEncodingException;
|
34
35
|
import java.security.cert.CertificateException;
|
36
|
+
import java.util.concurrent.ConcurrentHashMap;
|
37
|
+
import java.util.Map;
|
35
38
|
|
36
39
|
import static javax.net.ssl.SSLEngineResult.Status;
|
37
40
|
import static javax.net.ssl.SSLEngineResult.HandshakeStatus;
|
@@ -130,10 +133,39 @@ public class MiniSSL extends RubyObject {
|
|
130
133
|
super(runtime, klass);
|
131
134
|
}
|
132
135
|
|
136
|
+
private static Map<String, KeyManagerFactory> keyManagerFactoryMap = new ConcurrentHashMap<String, KeyManagerFactory>();
|
137
|
+
private static Map<String, TrustManagerFactory> trustManagerFactoryMap = new ConcurrentHashMap<String, TrustManagerFactory>();
|
138
|
+
|
133
139
|
@JRubyMethod(meta = true)
|
134
|
-
public static IRubyObject server(ThreadContext context, IRubyObject recv, IRubyObject miniSSLContext)
|
135
|
-
|
140
|
+
public static synchronized IRubyObject server(ThreadContext context, IRubyObject recv, IRubyObject miniSSLContext)
|
141
|
+
throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException, UnrecoverableKeyException {
|
142
|
+
// Create the KeyManagerFactory and TrustManagerFactory for this server
|
143
|
+
String keystoreFile = miniSSLContext.callMethod(context, "keystore").convertToString().asJavaString();
|
144
|
+
char[] password = miniSSLContext.callMethod(context, "keystore_pass").convertToString().asJavaString().toCharArray();
|
145
|
+
|
146
|
+
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
|
147
|
+
InputStream is = new FileInputStream(keystoreFile);
|
148
|
+
try {
|
149
|
+
ks.load(is, password);
|
150
|
+
} finally {
|
151
|
+
is.close();
|
152
|
+
}
|
153
|
+
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
|
154
|
+
kmf.init(ks, password);
|
155
|
+
keyManagerFactoryMap.put(keystoreFile, kmf);
|
156
|
+
|
157
|
+
KeyStore ts = KeyStore.getInstance(KeyStore.getDefaultType());
|
158
|
+
is = new FileInputStream(keystoreFile);
|
159
|
+
try {
|
160
|
+
ts.load(is, password);
|
161
|
+
} finally {
|
162
|
+
is.close();
|
163
|
+
}
|
164
|
+
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
|
165
|
+
tmf.init(ts);
|
166
|
+
trustManagerFactoryMap.put(keystoreFile, tmf);
|
136
167
|
|
168
|
+
RubyClass klass = (RubyClass) recv;
|
137
169
|
return klass.newInstance(context,
|
138
170
|
new IRubyObject[] { miniSSLContext },
|
139
171
|
Block.NULL_BLOCK);
|
@@ -141,20 +173,16 @@ public class MiniSSL extends RubyObject {
|
|
141
173
|
|
142
174
|
@JRubyMethod
|
143
175
|
public IRubyObject initialize(ThreadContext threadContext, IRubyObject miniSSLContext)
|
144
|
-
throws KeyStoreException,
|
176
|
+
throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
|
145
177
|
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
|
146
178
|
KeyStore ts = KeyStore.getInstance(KeyStore.getDefaultType());
|
147
179
|
|
148
|
-
char[] password = miniSSLContext.callMethod(threadContext, "keystore_pass").convertToString().asJavaString().toCharArray();
|
149
180
|
String keystoreFile = miniSSLContext.callMethod(threadContext, "keystore").convertToString().asJavaString();
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
|
157
|
-
tmf.init(ts);
|
181
|
+
KeyManagerFactory kmf = keyManagerFactoryMap.get(keystoreFile);
|
182
|
+
TrustManagerFactory tmf = trustManagerFactoryMap.get(keystoreFile);
|
183
|
+
if(kmf == null || tmf == null) {
|
184
|
+
throw new KeyStoreException("Could not find KeyManagerFactory/TrustManagerFactory for keystore: " + keystoreFile);
|
185
|
+
}
|
158
186
|
|
159
187
|
SSLContext sslCtx = SSLContext.getInstance("TLS");
|
160
188
|
|
@@ -434,7 +434,9 @@ VALUE HttpParser_body(VALUE self) {
|
|
434
434
|
return http->body;
|
435
435
|
}
|
436
436
|
|
437
|
+
#ifdef HAVE_OPENSSL_BIO_H
|
437
438
|
void Init_mini_ssl(VALUE mod);
|
439
|
+
#endif
|
438
440
|
|
439
441
|
void Init_puma_http11()
|
440
442
|
{
|
@@ -463,5 +465,7 @@ void Init_puma_http11()
|
|
463
465
|
rb_define_method(cHttpParser, "body", HttpParser_body, 0);
|
464
466
|
init_common_fields();
|
465
467
|
|
468
|
+
#ifdef HAVE_OPENSSL_BIO_H
|
466
469
|
Init_mini_ssl(mPuma);
|
470
|
+
#endif
|
467
471
|
}
|
data/lib/puma.rb
CHANGED
@@ -10,6 +10,9 @@ require 'stringio'
|
|
10
10
|
|
11
11
|
require 'thread'
|
12
12
|
|
13
|
+
require_relative 'puma/puma_http11'
|
14
|
+
require_relative 'puma/detect'
|
15
|
+
|
13
16
|
module Puma
|
14
17
|
autoload :Const, 'puma/const'
|
15
18
|
autoload :Server, 'puma/server'
|
@@ -24,6 +27,7 @@ module Puma
|
|
24
27
|
@get_stats.stats.to_json
|
25
28
|
end
|
26
29
|
|
30
|
+
# @version 5.0.0
|
27
31
|
def self.stats_hash
|
28
32
|
@get_stats.stats
|
29
33
|
end
|
@@ -33,4 +37,12 @@ module Puma
|
|
33
37
|
return unless Thread.current.respond_to?(:name=)
|
34
38
|
Thread.current.name = "puma #{name}"
|
35
39
|
end
|
40
|
+
|
41
|
+
unless HAS_SSL
|
42
|
+
module MiniSSL
|
43
|
+
# this class is defined so that it exists when Puma is compiled
|
44
|
+
# without ssl support, as Server and Reactor use it in rescue statements.
|
45
|
+
class SSLError < StandardError ; end
|
46
|
+
end
|
47
|
+
end
|
36
48
|
end
|
data/lib/puma/binder.rb
CHANGED
@@ -5,10 +5,16 @@ require 'socket'
|
|
5
5
|
|
6
6
|
require 'puma/const'
|
7
7
|
require 'puma/util'
|
8
|
-
require 'puma/minissl/context_builder'
|
9
8
|
require 'puma/configuration'
|
10
9
|
|
11
10
|
module Puma
|
11
|
+
|
12
|
+
if HAS_SSL
|
13
|
+
require 'puma/minissl'
|
14
|
+
require 'puma/minissl/context_builder'
|
15
|
+
require 'puma/accept_nonblock'
|
16
|
+
end
|
17
|
+
|
12
18
|
class Binder
|
13
19
|
include Puma::Const
|
14
20
|
|
@@ -44,7 +50,12 @@ module Puma
|
|
44
50
|
@ios = []
|
45
51
|
end
|
46
52
|
|
47
|
-
attr_reader :ios
|
53
|
+
attr_reader :ios
|
54
|
+
|
55
|
+
# @version 5.0.0
|
56
|
+
attr_reader :activated_sockets, :envs, :inherited_fds, :listeners, :proto_env, :unix_paths
|
57
|
+
|
58
|
+
# @version 5.0.0
|
48
59
|
attr_writer :ios, :listeners
|
49
60
|
|
50
61
|
def env(sock)
|
@@ -55,10 +66,12 @@ module Puma
|
|
55
66
|
@ios.each { |i| i.close }
|
56
67
|
end
|
57
68
|
|
69
|
+
# @version 5.0.0
|
58
70
|
def connected_ports
|
59
71
|
ios.map { |io| io.addr[1] }.uniq
|
60
72
|
end
|
61
73
|
|
74
|
+
# @version 5.0.0
|
62
75
|
def create_inherited_fds(env_hash)
|
63
76
|
env_hash.select {|k,v| k =~ /PUMA_INHERIT_\d+/}.each do |_k, v|
|
64
77
|
fd, url = v.split(":", 2)
|
@@ -69,7 +82,9 @@ module Puma
|
|
69
82
|
# systemd socket activation.
|
70
83
|
# LISTEN_FDS = number of listening sockets. e.g. 2 means accept on 2 sockets w/descriptors 3 and 4.
|
71
84
|
# LISTEN_PID = PID of the service process, aka us
|
72
|
-
# see https://www.freedesktop.org/software/systemd/man/systemd-socket-activate.html
|
85
|
+
# @see https://www.freedesktop.org/software/systemd/man/systemd-socket-activate.html
|
86
|
+
# @version 5.0.0
|
87
|
+
#
|
73
88
|
def create_activated_fds(env_hash)
|
74
89
|
return [] unless env_hash['LISTEN_FDS'] && env_hash['LISTEN_PID'].to_i == $$
|
75
90
|
env_hash['LISTEN_FDS'].to_i.times do |index|
|
@@ -155,6 +170,9 @@ module Puma
|
|
155
170
|
|
156
171
|
@listeners << [str, io]
|
157
172
|
when "ssl"
|
173
|
+
|
174
|
+
raise "Puma compiled without SSL support" unless HAS_SSL
|
175
|
+
|
158
176
|
params = Util.parse_query uri.query
|
159
177
|
ctx = MiniSSL::ContextBuilder.new(params, @events).context
|
160
178
|
|
@@ -245,9 +263,8 @@ module Puma
|
|
245
263
|
|
246
264
|
def add_ssl_listener(host, port, ctx,
|
247
265
|
optimize_for_latency=true, backlog=1024)
|
248
|
-
require 'puma/minissl'
|
249
266
|
|
250
|
-
|
267
|
+
raise "Puma compiled without SSL support" unless HAS_SSL
|
251
268
|
|
252
269
|
if host == "localhost"
|
253
270
|
loopback_addresses.each do |addr|
|
@@ -264,7 +281,6 @@ module Puma
|
|
264
281
|
s.setsockopt(Socket::SOL_SOCKET,Socket::SO_REUSEADDR, true)
|
265
282
|
s.listen backlog
|
266
283
|
|
267
|
-
|
268
284
|
ssl = MiniSSL::Server.new s, ctx
|
269
285
|
env = @proto_env.dup
|
270
286
|
env[HTTPS_KEY] = HTTPS
|
@@ -275,8 +291,7 @@ module Puma
|
|
275
291
|
end
|
276
292
|
|
277
293
|
def inherit_ssl_listener(fd, ctx)
|
278
|
-
|
279
|
-
MiniSSL.check
|
294
|
+
raise "Puma compiled without SSL support" unless HAS_SSL
|
280
295
|
|
281
296
|
if fd.kind_of? TCPServer
|
282
297
|
s = fd
|
@@ -367,6 +382,7 @@ module Puma
|
|
367
382
|
redirects
|
368
383
|
end
|
369
384
|
|
385
|
+
# @version 5.0.0
|
370
386
|
def redirects_for_restart_env
|
371
387
|
listeners.each_with_object({}).with_index do |(listen, memo), i|
|
372
388
|
memo["PUMA_INHERIT_#{i}"] = "#{listen[1].to_i}:#{listen[0]}"
|
@@ -381,6 +397,7 @@ module Puma
|
|
381
397
|
end.map { |addrinfo| addrinfo.ip_address }.uniq
|
382
398
|
end
|
383
399
|
|
400
|
+
# @version 5.0.0
|
384
401
|
def socket_activation_fd(int)
|
385
402
|
int + 3 # 3 is the magic number you add to follow the SA protocol
|
386
403
|
end
|
data/lib/puma/client.rb
CHANGED
@@ -280,6 +280,8 @@ module Puma
|
|
280
280
|
|
281
281
|
# Returns true if the persistent connection can be closed immediately
|
282
282
|
# without waiting for the configured idle/shutdown timeout.
|
283
|
+
# @version 5.0.0
|
284
|
+
#
|
283
285
|
def can_close?
|
284
286
|
# Allow connection to close if it's received at least one full request
|
285
287
|
# and hasn't received any data for a future request.
|
@@ -443,6 +445,7 @@ module Puma
|
|
443
445
|
end
|
444
446
|
end
|
445
447
|
|
448
|
+
# @version 5.0.0
|
446
449
|
def write_chunk(str)
|
447
450
|
@chunked_content_length += @body.write(str)
|
448
451
|
end
|
data/lib/puma/cluster.rb
CHANGED
@@ -77,6 +77,8 @@ module Puma
|
|
77
77
|
end
|
78
78
|
|
79
79
|
attr_reader :index, :pid, :phase, :signal, :last_checkin, :last_status, :started_at
|
80
|
+
|
81
|
+
# @version 5.0.0
|
80
82
|
attr_writer :pid, :phase
|
81
83
|
|
82
84
|
def booted?
|
@@ -98,6 +100,8 @@ module Puma
|
|
98
100
|
@last_status = JSON.parse(status, symbolize_names: true)
|
99
101
|
end
|
100
102
|
|
103
|
+
# @see Puma::Cluster#check_workers
|
104
|
+
# @version 5.0.0
|
101
105
|
def ping_timeout
|
102
106
|
@last_checkin +
|
103
107
|
(booted? ?
|
@@ -160,6 +164,7 @@ module Puma
|
|
160
164
|
end
|
161
165
|
end
|
162
166
|
|
167
|
+
# @version 5.0.0
|
163
168
|
def spawn_worker(idx, master)
|
164
169
|
@launcher.config.run_hooks :before_worker_fork, idx, @launcher.events
|
165
170
|
|
@@ -419,6 +424,7 @@ module Puma
|
|
419
424
|
@options[:preload_app]
|
420
425
|
end
|
421
426
|
|
427
|
+
# @version 5.0.0
|
422
428
|
def fork_worker!
|
423
429
|
if (worker = @workers.find { |w| w.index == 0 })
|
424
430
|
worker.phase += 1
|
@@ -640,6 +646,7 @@ module Puma
|
|
640
646
|
end
|
641
647
|
end
|
642
648
|
|
649
|
+
# @version 5.0.0
|
643
650
|
def timeout_workers
|
644
651
|
@workers.each do |w|
|
645
652
|
if !w.term? && w.ping_timeout <= Time.now
|
@@ -649,6 +656,7 @@ module Puma
|
|
649
656
|
end
|
650
657
|
end
|
651
658
|
|
659
|
+
# @version 5.0.0
|
652
660
|
def nakayoshi_gc
|
653
661
|
return unless @options[:nakayoshi_fork]
|
654
662
|
log "! Promoting existing objects to old generation..."
|
data/lib/puma/configuration.rb
CHANGED
data/lib/puma/const.rb
CHANGED
@@ -100,8 +100,9 @@ module Puma
|
|
100
100
|
# too taxing on performance.
|
101
101
|
module Const
|
102
102
|
|
103
|
-
PUMA_VERSION = VERSION = "5.0.0
|
103
|
+
PUMA_VERSION = VERSION = "5.0.0".freeze
|
104
104
|
CODE_NAME = "Spoony Bard".freeze
|
105
|
+
|
105
106
|
PUMA_SERVER_STRING = ['puma', PUMA_VERSION, CODE_NAME].join(' ').freeze
|
106
107
|
|
107
108
|
FAST_TRACK_KA_TIMEOUT = 0.2
|
data/lib/puma/control_cli.rb
CHANGED
@@ -12,6 +12,8 @@ module Puma
|
|
12
12
|
class ControlCLI
|
13
13
|
|
14
14
|
COMMANDS = %w{halt restart phased-restart start stats status stop reload-worker-directory gc gc-stats thread-backtraces refork}
|
15
|
+
|
16
|
+
# @version 5.0.0
|
15
17
|
PRINTABLE_COMMANDS = %w{gc-stats stats thread-backtraces}
|
16
18
|
|
17
19
|
def initialize(argv, stdout=STDOUT, stderr=STDERR)
|
data/lib/puma/detect.rb
CHANGED
@@ -1,6 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Puma
|
4
|
+
# at present, MiniSSL::Engine is only defined in extension code, not in minissl.rb
|
5
|
+
HAS_SSL = const_defined?(:MiniSSL, false) && MiniSSL.const_defined?(:Engine, false)
|
6
|
+
|
7
|
+
def self.ssl?
|
8
|
+
HAS_SSL
|
9
|
+
end
|
10
|
+
|
4
11
|
IS_JRUBY = defined?(JRUBY_VERSION)
|
5
12
|
|
6
13
|
def self.jruby?
|
@@ -13,10 +20,12 @@ module Puma
|
|
13
20
|
IS_WINDOWS
|
14
21
|
end
|
15
22
|
|
23
|
+
# @version 5.0.0
|
16
24
|
def self.mri?
|
17
25
|
RUBY_ENGINE == 'ruby' || RUBY_ENGINE.nil?
|
18
26
|
end
|
19
27
|
|
28
|
+
# @version 5.0.0
|
20
29
|
def self.forkable?
|
21
30
|
::Process.respond_to?(:fork)
|
22
31
|
end
|
data/lib/puma/dsl.rb
CHANGED
@@ -14,22 +14,23 @@ module Puma
|
|
14
14
|
# end
|
15
15
|
# config.load
|
16
16
|
#
|
17
|
-
# puts config.options[:binds]
|
18
|
-
# "tcp://127.0.0.1:3001"
|
17
|
+
# puts config.options[:binds] # => "tcp://127.0.0.1:3001"
|
19
18
|
#
|
20
19
|
# Used to load file:
|
21
20
|
#
|
22
21
|
# $ cat puma_config.rb
|
23
|
-
#
|
22
|
+
# port 3002
|
23
|
+
#
|
24
|
+
# Resulting configuration:
|
24
25
|
#
|
25
26
|
# config = Configuration.new(config_file: "puma_config.rb")
|
26
27
|
# config.load
|
27
28
|
#
|
28
|
-
# puts config.options[:binds]
|
29
|
-
# # => "tcp://127.0.0.1:3002"
|
29
|
+
# puts config.options[:binds] # => "tcp://127.0.0.1:3002"
|
30
30
|
#
|
31
31
|
# You can also find many examples being used by the test suite in
|
32
32
|
# +test/config+.
|
33
|
+
#
|
33
34
|
class DSL
|
34
35
|
include ConfigDefault
|
35
36
|
|
@@ -98,6 +99,9 @@ module Puma
|
|
98
99
|
# [body]
|
99
100
|
# ]
|
100
101
|
# end
|
102
|
+
#
|
103
|
+
# @see Puma::Configuration#app
|
104
|
+
#
|
101
105
|
def app(obj=nil, &block)
|
102
106
|
obj ||= block
|
103
107
|
|
@@ -160,12 +164,12 @@ module Puma
|
|
160
164
|
#
|
161
165
|
# You can use query parameters within the url to specify options:
|
162
166
|
#
|
163
|
-
#
|
164
|
-
#
|
165
|
-
#
|
166
|
-
#
|
167
|
-
#
|
168
|
-
#
|
167
|
+
# * Set the socket backlog depth with +backlog+, default is 1024.
|
168
|
+
# * Set up an SSL certificate with +key+ & +cert+.
|
169
|
+
# * Set whether to optimize for low latency instead of throughput with
|
170
|
+
# +low_latency+, default is to optimize for low latency. This is done
|
171
|
+
# via +Socket::TCP_NODELAY+.
|
172
|
+
# * Set socket permissions with +umask+.
|
169
173
|
#
|
170
174
|
# @example Backlog depth
|
171
175
|
# bind 'unix:///var/run/puma.sock?backlog=512'
|
@@ -175,6 +179,9 @@ module Puma
|
|
175
179
|
# bind 'tcp://0.0.0.0:9292?low_latency=false'
|
176
180
|
# @example Socket permissions
|
177
181
|
# bind 'unix:///var/run/puma.sock?umask=0111'
|
182
|
+
# @see Puma::Runner#load_and_bind
|
183
|
+
# @see Puma::Cluster#run
|
184
|
+
#
|
178
185
|
def bind(url)
|
179
186
|
@options[:binds] ||= []
|
180
187
|
@options[:binds] << url
|
@@ -193,13 +200,14 @@ module Puma
|
|
193
200
|
bind "tcp://#{host}:#{port}"
|
194
201
|
end
|
195
202
|
|
196
|
-
# Define how long persistent connections can be idle before Puma closes
|
197
|
-
#
|
203
|
+
# Define how long persistent connections can be idle before Puma closes them.
|
204
|
+
# @see Puma::Server.new
|
198
205
|
def persistent_timeout(seconds)
|
199
206
|
@options[:persistent_timeout] = Integer(seconds)
|
200
207
|
end
|
201
208
|
|
202
209
|
# Define how long the tcp socket stays open, if no data has been received.
|
210
|
+
# @see Puma::Server.new
|
203
211
|
def first_data_timeout(seconds)
|
204
212
|
@options[:first_data_timeout] = Integer(seconds)
|
205
213
|
end
|
@@ -210,10 +218,11 @@ module Puma
|
|
210
218
|
@options[:clean_thread_locals] = which
|
211
219
|
end
|
212
220
|
|
213
|
-
# When shutting down, drain the accept socket of pending
|
214
|
-
#
|
215
|
-
#
|
216
|
-
#
|
221
|
+
# When shutting down, drain the accept socket of pending connections and
|
222
|
+
# process them. This loops over the accept socket until there are no more
|
223
|
+
# read events and then stops looking and waits for the requests to finish.
|
224
|
+
# @see Puma::Server#graceful_shutdown
|
225
|
+
#
|
217
226
|
def drain_on_shutdown(which=true)
|
218
227
|
@options[:drain_on_shutdown] = which
|
219
228
|
end
|
@@ -236,6 +245,7 @@ module Puma
|
|
236
245
|
#
|
237
246
|
# Puma always waits a few seconds after killing a thread for it to try
|
238
247
|
# to finish up it's work, even in :immediately mode.
|
248
|
+
# @see Puma::Server#graceful_shutdown
|
239
249
|
def force_shutdown_after(val=:forever)
|
240
250
|
i = case val
|
241
251
|
when :forever
|
@@ -315,7 +325,7 @@ module Puma
|
|
315
325
|
@options[:early_hints] = answer
|
316
326
|
end
|
317
327
|
|
318
|
-
# Redirect STDOUT and STDERR to files specified. The +append+ parameter
|
328
|
+
# Redirect +STDOUT+ and +STDERR+ to files specified. The +append+ parameter
|
319
329
|
# specifies whether the output is appended, the default is +false+.
|
320
330
|
#
|
321
331
|
# @example
|
@@ -356,8 +366,8 @@ module Puma
|
|
356
366
|
@options[:max_threads] = max
|
357
367
|
end
|
358
368
|
|
359
|
-
# Instead of
|
360
|
-
# can also use the
|
369
|
+
# Instead of `bind 'ssl://127.0.0.1:9292?key=key_path&cert=cert_path'` you
|
370
|
+
# can also use the this method.
|
361
371
|
#
|
362
372
|
# @example
|
363
373
|
# ssl_bind '127.0.0.1', '9292', {
|
@@ -403,6 +413,8 @@ module Puma
|
|
403
413
|
#
|
404
414
|
# @example
|
405
415
|
# state_permission 0600
|
416
|
+
# @version 5.0.0
|
417
|
+
#
|
406
418
|
def state_permission(permission)
|
407
419
|
@options[:state_permission] = permission
|
408
420
|
end
|
@@ -413,6 +425,7 @@ module Puma
|
|
413
425
|
# The default is 0.
|
414
426
|
#
|
415
427
|
# @note Cluster mode only.
|
428
|
+
# @see Puma::Cluster
|
416
429
|
def workers(count)
|
417
430
|
@options[:workers] = count.to_i
|
418
431
|
end
|
@@ -516,7 +529,8 @@ module Puma
|
|
516
529
|
# on_refork do
|
517
530
|
# 3.times {GC.start}
|
518
531
|
# end
|
519
|
-
|
532
|
+
# @version 5.0.0
|
533
|
+
#
|
520
534
|
def on_refork(&block)
|
521
535
|
@options[:before_refork] ||= []
|
522
536
|
@options[:before_refork] << block
|
@@ -582,7 +596,7 @@ module Puma
|
|
582
596
|
# new Bundler context and thus can float around as the release
|
583
597
|
# dictates.
|
584
598
|
#
|
585
|
-
#
|
599
|
+
# @see extra_runtime_dependencies
|
586
600
|
#
|
587
601
|
# @note This is incompatible with +preload_app!+.
|
588
602
|
# @note This is only supported for RubyGems 2.2+
|
@@ -599,6 +613,9 @@ module Puma
|
|
599
613
|
#
|
600
614
|
# @example
|
601
615
|
# raise_exception_on_sigterm false
|
616
|
+
# @see Puma::Launcher#setup_signals
|
617
|
+
# @see Puma::Cluster#setup_signals
|
618
|
+
#
|
602
619
|
def raise_exception_on_sigterm(answer=true)
|
603
620
|
@options[:raise_exception_on_sigterm] = answer
|
604
621
|
end
|
@@ -614,6 +631,8 @@ module Puma
|
|
614
631
|
# extra_runtime_dependencies ['gem_name_1', 'gem_name_2']
|
615
632
|
# @example
|
616
633
|
# extra_runtime_dependencies ['puma_worker_killer', 'puma-heroku']
|
634
|
+
# @see Puma::Launcher#extra_runtime_deps_directories
|
635
|
+
#
|
617
636
|
def extra_runtime_dependencies(answer = [])
|
618
637
|
@options[:extra_runtime_dependencies] = Array(answer)
|
619
638
|
end
|
@@ -641,6 +660,8 @@ module Puma
|
|
641
660
|
# @note Cluster mode only.
|
642
661
|
# @example
|
643
662
|
# worker_timeout 60
|
663
|
+
# @see Puma::Cluster::Worker#ping_timeout
|
664
|
+
#
|
644
665
|
def worker_timeout(timeout)
|
645
666
|
timeout = Integer(timeout)
|
646
667
|
min = Const::WORKER_CHECK_INTERVAL
|
@@ -657,15 +678,20 @@ module Puma
|
|
657
678
|
# If unspecified, this defaults to the value of worker_timeout.
|
658
679
|
#
|
659
680
|
# @note Cluster mode only.
|
660
|
-
#
|
681
|
+
#
|
682
|
+
# @example
|
661
683
|
# worker_boot_timeout 60
|
684
|
+
# @see Puma::Cluster::Worker#ping_timeout
|
685
|
+
#
|
662
686
|
def worker_boot_timeout(timeout)
|
663
687
|
@options[:worker_boot_timeout] = Integer(timeout)
|
664
688
|
end
|
665
689
|
|
666
|
-
# Set the timeout for worker shutdown
|
690
|
+
# Set the timeout for worker shutdown.
|
667
691
|
#
|
668
692
|
# @note Cluster mode only.
|
693
|
+
# @see Puma::Cluster::Worker#term
|
694
|
+
#
|
669
695
|
def worker_shutdown_timeout(timeout)
|
670
696
|
@options[:worker_shutdown_timeout] = Integer(timeout)
|
671
697
|
end
|
@@ -683,6 +709,7 @@ module Puma
|
|
683
709
|
# slow clients will occupy a handler thread while the request
|
684
710
|
# is being sent. A reverse proxy, such as nginx, can handle
|
685
711
|
# slow clients and queue requests before they reach Puma.
|
712
|
+
# @see Puma::Server
|
686
713
|
def queue_requests(answer=true)
|
687
714
|
@options[:queue_requests] = answer
|
688
715
|
end
|
@@ -690,6 +717,7 @@ module Puma
|
|
690
717
|
# When a shutdown is requested, the backtraces of all the
|
691
718
|
# threads will be written to $stdout. This can help figure
|
692
719
|
# out why shutdown is hanging.
|
720
|
+
#
|
693
721
|
def shutdown_debug(val=true)
|
694
722
|
@options[:shutdown_debug] = val
|
695
723
|
end
|
@@ -700,6 +728,10 @@ module Puma
|
|
700
728
|
# requests to pick up new requests first.
|
701
729
|
#
|
702
730
|
# Only works on MRI. For all other interpreters, this setting does nothing.
|
731
|
+
# @see Puma::Server#handle_servers
|
732
|
+
# @see Puma::ThreadPool#wait_for_less_busy_worker
|
733
|
+
# @version 5.0.0
|
734
|
+
#
|
703
735
|
def wait_for_less_busy_worker(val=0.005)
|
704
736
|
@options[:wait_for_less_busy_worker] = val.to_f
|
705
737
|
end
|
@@ -711,18 +743,18 @@ module Puma
|
|
711
743
|
#
|
712
744
|
# There are 4 possible values:
|
713
745
|
#
|
714
|
-
#
|
715
|
-
#
|
716
|
-
#
|
717
|
-
#
|
718
|
-
#
|
719
|
-
#
|
720
|
-
#
|
721
|
-
#
|
722
|
-
#
|
723
|
-
#
|
724
|
-
#
|
725
|
-
#
|
746
|
+
# 1. **:socket** (the default) - read the peername from the socket using the
|
747
|
+
# syscall. This is the normal behavior.
|
748
|
+
# 2. **:localhost** - set the remote address to "127.0.0.1"
|
749
|
+
# 3. **header: <http_header>**- set the remote address to the value of the
|
750
|
+
# provided http header. For instance:
|
751
|
+
# `set_remote_address header: "X-Real-IP"`.
|
752
|
+
# Only the first word (as separated by spaces or comma) is used, allowing
|
753
|
+
# headers such as X-Forwarded-For to be used as well.
|
754
|
+
# 4. **\<Any string\>** - this allows you to hardcode remote address to any value
|
755
|
+
# you wish. Because Puma never uses this field anyway, it's format is
|
756
|
+
# entirely in your hands.
|
757
|
+
#
|
726
758
|
def set_remote_address(val=:socket)
|
727
759
|
case val
|
728
760
|
when :socket
|
@@ -756,6 +788,8 @@ module Puma
|
|
756
788
|
# (default 1000), or pass 0 to disable auto refork.
|
757
789
|
#
|
758
790
|
# @note Cluster mode only.
|
791
|
+
# @version 5.0.0
|
792
|
+
#
|
759
793
|
def fork_worker(after_requests=1000)
|
760
794
|
@options[:fork_worker] = Integer(after_requests)
|
761
795
|
end
|
@@ -769,6 +803,10 @@ module Puma
|
|
769
803
|
# also increase time to boot and fork. See your logs for details on how much
|
770
804
|
# time this adds to your boot process. For most apps, it will be less than one
|
771
805
|
# second.
|
806
|
+
#
|
807
|
+
# @see Puma::Cluster#nakayoshi_gc
|
808
|
+
# @version 5.0.0
|
809
|
+
#
|
772
810
|
def nakayoshi_fork(enabled=true)
|
773
811
|
@options[:nakayoshi_fork] = enabled
|
774
812
|
end
|
data/lib/puma/error_logger.rb
CHANGED
data/lib/puma/events.rb
CHANGED
@@ -91,6 +91,7 @@ module Puma
|
|
91
91
|
# An HTTP connection error has occurred.
|
92
92
|
# +error+ a connection exception, +req+ the request,
|
93
93
|
# and +text+ additional info
|
94
|
+
# @version 5.0.0
|
94
95
|
#
|
95
96
|
def connection_error(error, req, text="HTTP connection error")
|
96
97
|
@error_logger.info(error: error, req: req, text: text)
|
@@ -124,6 +125,7 @@ module Puma
|
|
124
125
|
# Log occurred error debug dump.
|
125
126
|
# +error+ an exception object, +req+ the request,
|
126
127
|
# and +text+ additional info
|
128
|
+
# @version 5.0.0
|
127
129
|
#
|
128
130
|
def debug_error(error, req=nil, text="")
|
129
131
|
@error_logger.debug(error: error, req: req, text: text)
|
data/lib/puma/launcher.rb
CHANGED
@@ -188,6 +188,7 @@ module Puma
|
|
188
188
|
end
|
189
189
|
|
190
190
|
# Return all tcp ports the launcher may be using, TCP or SSL
|
191
|
+
# @version 5.0.0
|
191
192
|
def connected_ports
|
192
193
|
@binder.connected_ports
|
193
194
|
end
|
@@ -206,6 +207,7 @@ module Puma
|
|
206
207
|
@binder.close_listeners
|
207
208
|
end
|
208
209
|
|
210
|
+
# @version 5.0.0
|
209
211
|
def thread_status
|
210
212
|
Thread.list.each do |thread|
|
211
213
|
name = "Thread: TID-#{thread.object_id.to_s(36)}"
|
@@ -478,6 +480,7 @@ module Puma
|
|
478
480
|
"You must have RubyGems #{min_version}+ to use this feature."
|
479
481
|
end
|
480
482
|
|
483
|
+
# @version 5.0.0
|
481
484
|
def with_unbundled_env
|
482
485
|
bundler_ver = Gem::Version.new(Bundler::VERSION)
|
483
486
|
if bundler_ver < Gem::Version.new('2.1.0')
|
data/lib/puma/minissl.rb
CHANGED
@@ -10,9 +10,9 @@ require 'puma/puma_http11'
|
|
10
10
|
|
11
11
|
module Puma
|
12
12
|
module MiniSSL
|
13
|
-
|
14
|
-
# define constant at runtime, as it's easy to determine at built time,
|
13
|
+
# Define constant at runtime, as it's easy to determine at built time,
|
15
14
|
# but Puma could (it shouldn't) be loaded with an older OpenSSL version
|
15
|
+
# @version 5.0.0
|
16
16
|
HAS_TLS1_3 = !IS_JRUBY &&
|
17
17
|
(OPENSSL_VERSION[/ \d+\.\d+\.\d+/].split('.').map(&:to_i) <=> [1,1,1]) != -1 &&
|
18
18
|
(OPENSSL_LIBRARY_VERSION[/ \d+\.\d+\.\d+/].split('.').map(&:to_i) <=> [1,1,1]) !=-1
|
@@ -32,19 +32,21 @@ module Puma
|
|
32
32
|
@socket.closed?
|
33
33
|
end
|
34
34
|
|
35
|
-
#
|
36
|
-
# first is protocol version (SSL_get_version)
|
35
|
+
# Returns a two element array,
|
36
|
+
# first is protocol version (SSL_get_version),
|
37
37
|
# second is 'handshake' state (SSL_state_string)
|
38
38
|
#
|
39
|
-
#
|
40
|
-
#
|
39
|
+
# Used for dropping tcp connections to ssl.
|
40
|
+
# See OpenSSL ssl/ssl_stat.c SSL_state_string for info
|
41
|
+
# @version 5.0.0
|
41
42
|
#
|
42
43
|
def ssl_version_state
|
43
44
|
IS_JRUBY ? [nil, nil] : @engine.ssl_vers_st
|
44
45
|
end
|
45
46
|
|
46
|
-
#
|
47
|
+
# Used to check the handshake status, in particular when a TCP connection
|
47
48
|
# is made with TLSv1.3 as an available protocol
|
49
|
+
# @version 5.0.0
|
48
50
|
def bad_tlsv1_3?
|
49
51
|
HAS_TLS1_3 && @engine.ssl_vers_st == ['TLSv1.3', 'SSLERR']
|
50
52
|
end
|
@@ -136,14 +138,18 @@ module Puma
|
|
136
138
|
alias_method :<<, :write
|
137
139
|
|
138
140
|
# This is a temporary fix to deal with websockets code using
|
139
|
-
# write_nonblock.
|
141
|
+
# write_nonblock.
|
142
|
+
|
143
|
+
# The problem with implementing it properly
|
140
144
|
# is that it means we'd have to have the ability to rewind
|
141
145
|
# an engine because after we write+extract, the socket
|
142
146
|
# write_nonblock call might raise an exception and later
|
143
147
|
# code would pass the same data in, but the engine would think
|
144
|
-
# it had already written the data in.
|
145
|
-
#
|
146
|
-
#
|
148
|
+
# it had already written the data in.
|
149
|
+
#
|
150
|
+
# So for the time being (and since write blocking is quite rare),
|
151
|
+
# go ahead and actually block in write_nonblock.
|
152
|
+
#
|
147
153
|
def write_nonblock(data, *_)
|
148
154
|
write data
|
149
155
|
end
|
@@ -203,8 +209,6 @@ module Puma
|
|
203
209
|
class SSLError < StandardError
|
204
210
|
# Define this for jruby even though it isn't used.
|
205
211
|
end
|
206
|
-
|
207
|
-
def self.check; end
|
208
212
|
end
|
209
213
|
|
210
214
|
class Context
|
@@ -261,13 +265,13 @@ module Puma
|
|
261
265
|
|
262
266
|
# disables TLSv1
|
263
267
|
def no_tlsv1=(tlsv1)
|
264
|
-
raise ArgumentError, "Invalid value of no_tlsv1" unless ['true', 'false', true, false].include?(tlsv1)
|
268
|
+
raise ArgumentError, "Invalid value of no_tlsv1=" unless ['true', 'false', true, false].include?(tlsv1)
|
265
269
|
@no_tlsv1 = tlsv1
|
266
270
|
end
|
267
271
|
|
268
272
|
# disables TLSv1 and TLSv1.1. Overrides `#no_tlsv1=`
|
269
273
|
def no_tlsv1_1=(tlsv1_1)
|
270
|
-
raise ArgumentError, "Invalid value of
|
274
|
+
raise ArgumentError, "Invalid value of no_tlsv1_1=" unless ['true', 'false', true, false].include?(tlsv1_1)
|
271
275
|
@no_tlsv1_1 = tlsv1_1
|
272
276
|
end
|
273
277
|
|
@@ -303,6 +307,7 @@ module Puma
|
|
303
307
|
Socket.new io, engine
|
304
308
|
end
|
305
309
|
|
310
|
+
# @version 5.0.0
|
306
311
|
def addr
|
307
312
|
@socket.addr
|
308
313
|
end
|
data/lib/puma/puma_http11.jar
CHANGED
Binary file
|
data/lib/puma/reactor.rb
CHANGED
data/lib/puma/runner.rb
CHANGED
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
require 'puma/server'
|
4
4
|
require 'puma/const'
|
5
|
-
require 'puma/minissl/context_builder'
|
6
5
|
|
7
6
|
module Puma
|
8
7
|
# Generic class that is used by `Puma::Cluster` and `Puma::Single` to
|
@@ -30,6 +29,7 @@ module Puma
|
|
30
29
|
@events.log str
|
31
30
|
end
|
32
31
|
|
32
|
+
# @version 5.0.0
|
33
33
|
def stop_control
|
34
34
|
@control.stop(true) if @control
|
35
35
|
end
|
@@ -64,6 +64,7 @@ module Puma
|
|
64
64
|
@control = control
|
65
65
|
end
|
66
66
|
|
67
|
+
# @version 5.0.0
|
67
68
|
def close_control_listeners
|
68
69
|
@control.binder.close_listeners if @control
|
69
70
|
end
|
data/lib/puma/server.rb
CHANGED
@@ -9,12 +9,9 @@ require 'puma/null_io'
|
|
9
9
|
require 'puma/reactor'
|
10
10
|
require 'puma/client'
|
11
11
|
require 'puma/binder'
|
12
|
-
require 'puma/accept_nonblock'
|
13
12
|
require 'puma/util'
|
14
13
|
require 'puma/io_buffer'
|
15
14
|
|
16
|
-
require 'puma/puma_http11'
|
17
|
-
|
18
15
|
require 'socket'
|
19
16
|
require 'forwardable'
|
20
17
|
|
@@ -37,7 +34,7 @@ module Puma
|
|
37
34
|
|
38
35
|
attr_reader :thread
|
39
36
|
attr_reader :events
|
40
|
-
attr_reader :requests_count
|
37
|
+
attr_reader :requests_count # @version 5.0.0
|
41
38
|
attr_accessor :app
|
42
39
|
|
43
40
|
attr_accessor :min_threads
|
@@ -100,11 +97,11 @@ module Puma
|
|
100
97
|
|
101
98
|
class << self
|
102
99
|
# :nodoc:
|
100
|
+
# @version 5.0.0
|
103
101
|
def tcp_cork_supported?
|
104
102
|
RbConfig::CONFIG['host_os'] =~ /linux/ &&
|
105
103
|
Socket.const_defined?(:IPPROTO_TCP) &&
|
106
104
|
Socket.const_defined?(:TCP_CORK) &&
|
107
|
-
Socket.const_defined?(:SOL_TCP) &&
|
108
105
|
Socket.const_defined?(:TCP_INFO)
|
109
106
|
end
|
110
107
|
private :tcp_cork_supported?
|
@@ -140,7 +137,7 @@ module Puma
|
|
140
137
|
return false unless @precheck_closing
|
141
138
|
|
142
139
|
begin
|
143
|
-
tcp_info = socket.getsockopt(Socket::
|
140
|
+
tcp_info = socket.getsockopt(Socket::IPPROTO_TCP, Socket::TCP_INFO)
|
144
141
|
rescue IOError, SystemCallError
|
145
142
|
Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
|
146
143
|
@precheck_closing = false
|
@@ -998,9 +995,11 @@ module Puma
|
|
998
995
|
private :possible_header_injection?
|
999
996
|
|
1000
997
|
# List of methods invoked by #stats.
|
998
|
+
# @version 5.0.0
|
1001
999
|
STAT_METHODS = [:backlog, :running, :pool_capacity, :max_threads, :requests_count].freeze
|
1002
1000
|
|
1003
1001
|
# Returns a hash of stats about the running server for reporting purposes.
|
1002
|
+
# @version 5.0.0
|
1004
1003
|
def stats
|
1005
1004
|
STAT_METHODS.map {|name| [name, send(name) || 0]}.to_h
|
1006
1005
|
end
|
data/lib/puma/thread_pool.rb
CHANGED
@@ -66,7 +66,7 @@ module Puma
|
|
66
66
|
|
67
67
|
attr_reader :spawned, :trim_requested, :waiting
|
68
68
|
attr_accessor :clean_thread_locals
|
69
|
-
attr_accessor :out_of_band_hook
|
69
|
+
attr_accessor :out_of_band_hook # @version 5.0.0
|
70
70
|
|
71
71
|
def self.clean_thread_locals
|
72
72
|
Thread.current.keys.each do |key| # rubocop: disable Performance/HashEachMethods
|
@@ -84,6 +84,7 @@ module Puma
|
|
84
84
|
waiting + (@max - spawned)
|
85
85
|
end
|
86
86
|
|
87
|
+
# @version 5.0.0
|
87
88
|
def busy_threads
|
88
89
|
with_mutex { @spawned - @waiting + @todo.size }
|
89
90
|
end
|
@@ -151,6 +152,7 @@ module Puma
|
|
151
152
|
|
152
153
|
private :spawn_thread
|
153
154
|
|
155
|
+
# @version 5.0.0
|
154
156
|
def trigger_out_of_band_hook
|
155
157
|
return false unless out_of_band_hook && out_of_band_hook.any?
|
156
158
|
|
@@ -166,6 +168,7 @@ module Puma
|
|
166
168
|
|
167
169
|
private :trigger_out_of_band_hook
|
168
170
|
|
171
|
+
# @version 5.0.0
|
169
172
|
def with_mutex(&block)
|
170
173
|
@mutex.owned? ?
|
171
174
|
yield :
|
@@ -231,6 +234,7 @@ module Puma
|
|
231
234
|
end
|
232
235
|
end
|
233
236
|
|
237
|
+
# @version 5.0.0
|
234
238
|
def wait_for_less_busy_worker(delay_s)
|
235
239
|
# Ruby MRI does GVL, this can result
|
236
240
|
# in processing contention when multiple threads
|
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: 5.0.0
|
4
|
+
version: 5.0.0
|
5
5
|
platform: java
|
6
6
|
authors:
|
7
7
|
- Evan Phoenix
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-09-
|
11
|
+
date: 2020-09-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
@@ -69,6 +69,7 @@ files:
|
|
69
69
|
- ext/puma_http11/http11_parser.rl
|
70
70
|
- ext/puma_http11/http11_parser_common.rl
|
71
71
|
- ext/puma_http11/mini_ssl.c
|
72
|
+
- ext/puma_http11/no_ssl/PumaHttp11Service.java
|
72
73
|
- ext/puma_http11/org/jruby/puma/Http11.java
|
73
74
|
- ext/puma_http11/org/jruby/puma/Http11Parser.java
|
74
75
|
- ext/puma_http11/org/jruby/puma/MiniSSL.java
|
@@ -129,9 +130,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
129
130
|
version: '2.2'
|
130
131
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
131
132
|
requirements:
|
132
|
-
- - "
|
133
|
+
- - ">="
|
133
134
|
- !ruby/object:Gem::Version
|
134
|
-
version:
|
135
|
+
version: '0'
|
135
136
|
requirements: []
|
136
137
|
rubygems_version: 3.0.6
|
137
138
|
signing_key:
|