puma 3.11.3 → 3.12.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 +5 -5
- data/History.md +40 -0
- data/README.md +15 -5
- data/docs/architecture.md +1 -1
- data/docs/restart.md +1 -1
- data/docs/systemd.md +10 -0
- data/ext/puma_http11/mini_ssl.c +22 -1
- data/ext/puma_http11/org/jruby/puma/MiniSSL.java +6 -0
- data/lib/puma/binder.rb +13 -9
- data/lib/puma/cli.rb +18 -7
- data/lib/puma/client.rb +14 -0
- data/lib/puma/cluster.rb +16 -1
- data/lib/puma/commonlogger.rb +2 -0
- data/lib/puma/configuration.rb +2 -0
- data/lib/puma/const.rb +4 -2
- data/lib/puma/control_cli.rb +13 -11
- data/lib/puma/convenient.rb +2 -0
- data/lib/puma/daemon_ext.rb +2 -0
- data/lib/puma/delegation.rb +2 -0
- data/lib/puma/detect.rb +2 -0
- data/lib/puma/dsl.rb +18 -8
- data/lib/puma/events.rb +2 -0
- data/lib/puma/io_buffer.rb +2 -0
- data/lib/puma/java_io_buffer.rb +2 -0
- data/lib/puma/jruby_restart.rb +2 -0
- data/lib/puma/launcher.rb +5 -2
- data/lib/puma/minissl.rb +7 -3
- data/lib/puma/null_io.rb +2 -0
- data/lib/puma/plugin.rb +2 -0
- data/lib/puma/rack/builder.rb +2 -1
- data/lib/puma/reactor.rb +134 -0
- data/lib/puma/runner.rb +10 -1
- data/lib/puma/server.rb +40 -4
- data/lib/puma/single.rb +12 -1
- data/lib/puma/state_file.rb +2 -0
- data/lib/puma/tcp_logger.rb +2 -0
- data/lib/puma/thread_pool.rb +46 -5
- data/lib/puma/util.rb +1 -0
- data/lib/puma.rb +8 -0
- data/lib/rack/handler/puma.rb +4 -0
- data/tools/jungle/README.md +10 -4
- data/tools/jungle/init.d/README.md +2 -0
- data/tools/jungle/init.d/puma +2 -2
- data/tools/jungle/init.d/run-puma +1 -1
- data/tools/jungle/rc.d/README.md +74 -0
- data/tools/jungle/rc.d/puma +61 -0
- data/tools/jungle/rc.d/puma.conf +10 -0
- metadata +11 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 5d0e3b5d74ced5d332fa04832c60b4b8b9c16514f3441cefea046d6ca4948025
|
4
|
+
data.tar.gz: 9462d0f9e3357c2b245f194b43281e5f8e5ebf0ee981e7658a938d880e3e4404
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 19ffe686429f3271d947e8fbc73c1e55113a0ad22eea2a194c80abac60cf675ea4162675f99d641e18e91d1d4270eae80644ccab5667ad263dfb32eb0b3075f2
|
7
|
+
data.tar.gz: 40876e43164a6103bcfc560a6034f4fb2215d0da39d84cb5d53f961da64a8d8e41e3f239f1a7886a0f13c6e6a1357608a54efc009517e1b3b2afc72c4a570b8d
|
data/History.md
CHANGED
@@ -1,3 +1,43 @@
|
|
1
|
+
## Master
|
2
|
+
|
3
|
+
* x features
|
4
|
+
|
5
|
+
* x bugfixes
|
6
|
+
|
7
|
+
## 3.12.1 / 2019-01-08
|
8
|
+
|
9
|
+
* 1 features
|
10
|
+
* Internal strings are frozen (#1649)
|
11
|
+
* 3 bugfixes
|
12
|
+
* Fix chunked ending check (#1607)
|
13
|
+
* Rack handler should use provided default host (#1700)
|
14
|
+
* Better support for detecting runtimes that support `fork` (#1630)
|
15
|
+
|
16
|
+
## 3.12.0 / 2018-07-13
|
17
|
+
|
18
|
+
* 5 features:
|
19
|
+
* You can now specify which SSL ciphers the server should support, default is unchanged (#1478)
|
20
|
+
* The setting for Puma's `max_threads` is now in `Puma.stats` (#1604)
|
21
|
+
* Pool capacity is now in `Puma.stats` (#1579)
|
22
|
+
* Installs restricted to Ruby 2.2+ (#1506)
|
23
|
+
* `--control` is now deprecated in favor of `--control-url` (#1487)
|
24
|
+
|
25
|
+
* 2 bugfixes:
|
26
|
+
* Workers will no longer accept more web requests than they have capacity to process. This prevents an issue where one worker would accept lots of requests while starving other workers (#1563)
|
27
|
+
* In a test env puma now emits the stack on an exception (#1557)
|
28
|
+
|
29
|
+
## 3.11.4 / 2018-04-12
|
30
|
+
|
31
|
+
* 2 features:
|
32
|
+
* Manage puma as a service using rc.d (#1529)
|
33
|
+
* Server stats are now available from a top level method (#1532)
|
34
|
+
* 5 bugfixes:
|
35
|
+
* Fix parsing CLI options (#1482)
|
36
|
+
* Order of stderr and stdout is made before redirecting to a log file (#1511)
|
37
|
+
* Init.d fix of `ps -p` to check if pid exists (#1545)
|
38
|
+
* Early hints bugfix (#1550)
|
39
|
+
* Purge interrupt queue when closing socket fails (#1553)
|
40
|
+
|
1
41
|
## 3.11.3 / 2018-03-05
|
2
42
|
|
3
43
|
* 3 bugfixes:
|
data/README.md
CHANGED
@@ -157,17 +157,27 @@ $ puma -b 'unix:///var/run/puma.sock?umask=0111'
|
|
157
157
|
```
|
158
158
|
|
159
159
|
Need a bit of security? Use SSL sockets:
|
160
|
-
|
161
160
|
```
|
162
161
|
$ puma -b 'ssl://127.0.0.1:9292?key=path_to_key&cert=path_to_cert'
|
163
162
|
```
|
163
|
+
#### Controlling SSL Cipher Suites
|
164
|
+
Need to use or avoid specific SSL cipher suites? Use ssl_cipher_filter or ssl_cipher_list options.
|
165
|
+
#####Ruby:
|
166
|
+
```
|
167
|
+
$ puma -b 'ssl://127.0.0.1:9292?key=path_to_key&cert=path_to_cert&ssl_cipher_filter=!aNULL:AES+SHA'
|
168
|
+
```
|
169
|
+
#####JRuby:
|
170
|
+
```
|
171
|
+
$ puma -b 'ssl://127.0.0.1:9292?keystore=path_to_keystore&keystore-pass=keystore_password&ssl_cipher_list=TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA'
|
172
|
+
```
|
173
|
+
See https://www.openssl.org/docs/man1.0.2/apps/ciphers.html for cipher filter format and full list of cipher suites.
|
164
174
|
|
165
175
|
### Control/Status Server
|
166
176
|
|
167
177
|
Puma has a built-in status/control app that can be used to query and control Puma itself.
|
168
178
|
|
169
179
|
```
|
170
|
-
$ puma --control tcp://127.0.0.1:9293 --control-token foo
|
180
|
+
$ puma --control-url tcp://127.0.0.1:9293 --control-token foo
|
171
181
|
```
|
172
182
|
|
173
183
|
Puma will start the control server on localhost port 9293. All requests to the control server will need to include `token=foo` as a query parameter. This allows for simple authentication. Check out [status.rb](https://github.com/puma/puma/blob/master/lib/puma/app/status.rb) to see what the app has available.
|
@@ -175,7 +185,7 @@ Puma will start the control server on localhost port 9293. All requests to the c
|
|
175
185
|
You can also interact with the control server via `pumactl`. This command will restart Puma:
|
176
186
|
|
177
187
|
```
|
178
|
-
$ pumactl -
|
188
|
+
$ pumactl --control-url 'tcp://127.0.0.1:9293' --control-token foo restart
|
179
189
|
```
|
180
190
|
|
181
191
|
To see a list of `pumactl` options, use `pumactl --help`.
|
@@ -217,10 +227,10 @@ Some platforms do not support all Puma features.
|
|
217
227
|
|
218
228
|
## Known Bugs
|
219
229
|
|
220
|
-
For MRI versions 2.2.7, 2.2.8, 2.3.4 and 2.4.1, you may see ```stream closed in another thread (IOError)```. It may be caused by a [Ruby bug](https://bugs.ruby-lang.org/issues/13632). It can be fixed with the gem https://rubygems.org/gems/stopgap_13632:
|
230
|
+
For MRI versions 2.2.7, 2.2.8, 2.2.9, 2.2.10 2.3.4 and 2.4.1, you may see ```stream closed in another thread (IOError)```. It may be caused by a [Ruby bug](https://bugs.ruby-lang.org/issues/13632). It can be fixed with the gem https://rubygems.org/gems/stopgap_13632:
|
221
231
|
|
222
232
|
```ruby
|
223
|
-
if %w(2.2.7 2.2.8 2.3.4 2.4.1).include? RUBY_VERSION
|
233
|
+
if %w(2.2.7 2.2.8 2.2.9 2.2.10 2.3.4 2.4.1).include? RUBY_VERSION
|
224
234
|
begin
|
225
235
|
require 'stopgap_13632'
|
226
236
|
rescue LoadError
|
data/docs/architecture.md
CHANGED
@@ -33,4 +33,4 @@ Clustered mode is shown/discussed here. Single mode is analogous to having a sin
|
|
33
33
|
The `queue_requests` option is `true` by default, enabling the separate thread used to buffer requests as described above.
|
34
34
|
|
35
35
|
If set to `false`, this buffer will not be used for connections while waiting for the request to arrive.
|
36
|
-
In this mode, when a connection is accepted, it is added to the "todo" queue immediately, and a worker will
|
36
|
+
In this mode, when a connection is accepted, it is added to the "todo" queue immediately, and a worker will synchronously do any waiting necessary to read the HTTP request from the socket.
|
data/docs/restart.md
CHANGED
@@ -20,7 +20,7 @@ When you run pumactl phased-restart, Puma kills workers one-by-one, meaning that
|
|
20
20
|
|
21
21
|
But again beware, upgrading an application sometimes involves upgrading the database schema. With phased restart, there may be a moment during the deployment where processes belonging to the previous version and processes belonging to the new version both exist at the same time. Any database schema upgrades you perform must therefore be backwards-compatible with the old application version.
|
22
22
|
|
23
|
-
If you perform a lot of database migrations, you probably should not use phased restart and use a normal/hot restart instead (pumactl restart). That way, no code is shared while deploying (in that case, preload_app might help for quicker deployment, see
|
23
|
+
If you perform a lot of database migrations, you probably should not use phased restart and use a normal/hot restart instead (`pumactl restart`). That way, no code is shared while deploying (in that case, `preload_app!` might help for quicker deployment, see ["Clustered Mode" in the README](../README.md#clustered-mode)).
|
24
24
|
|
25
25
|
### Release Directory
|
26
26
|
|
data/docs/systemd.md
CHANGED
@@ -102,6 +102,16 @@ for additional configuration details.
|
|
102
102
|
Note that the above configurations will work with Puma in either
|
103
103
|
single process or cluster mode.
|
104
104
|
|
105
|
+
### Sockets and symlinks
|
106
|
+
|
107
|
+
When using releases folders, you should set the socket path using the
|
108
|
+
shared folder path (ex. `/srv/projet/shared/tmp/puma.sock`), not the
|
109
|
+
release folder path (`/srv/projet/releases/1234/tmp/puma.sock`).
|
110
|
+
|
111
|
+
Puma will detect the release path socket as different than the one provided by
|
112
|
+
systemd and attempt to bind it again, resulting in the exception
|
113
|
+
`There is already a server bound to:`.
|
114
|
+
|
105
115
|
## Usage
|
106
116
|
|
107
117
|
Without socket activation, use `systemctl` as root (e.g. via `sudo`) as
|
data/ext/puma_http11/mini_ssl.c
CHANGED
@@ -161,6 +161,9 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
|
|
161
161
|
ID sym_verify_mode = rb_intern("verify_mode");
|
162
162
|
VALUE verify_mode = rb_funcall(mini_ssl_ctx, sym_verify_mode, 0);
|
163
163
|
|
164
|
+
ID sym_ssl_cipher_filter = rb_intern("ssl_cipher_filter");
|
165
|
+
VALUE ssl_cipher_filter = rb_funcall(mini_ssl_ctx, sym_ssl_cipher_filter, 0);
|
166
|
+
|
164
167
|
ctx = SSL_CTX_new(SSLv23_server_method());
|
165
168
|
conn->ctx = ctx;
|
166
169
|
|
@@ -175,7 +178,13 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
|
|
175
178
|
SSL_CTX_set_options(ctx, SSL_OP_CIPHER_SERVER_PREFERENCE | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_SINGLE_DH_USE | SSL_OP_SINGLE_ECDH_USE | SSL_OP_NO_COMPRESSION);
|
176
179
|
SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
|
177
180
|
|
178
|
-
|
181
|
+
if (!NIL_P(ssl_cipher_filter)) {
|
182
|
+
StringValue(ssl_cipher_filter);
|
183
|
+
SSL_CTX_set_cipher_list(ctx, RSTRING_PTR(ssl_cipher_filter));
|
184
|
+
}
|
185
|
+
else {
|
186
|
+
SSL_CTX_set_cipher_list(ctx, "HIGH:!aNULL@STRENGTH");
|
187
|
+
}
|
179
188
|
|
180
189
|
DH *dh = get_dh1024();
|
181
190
|
SSL_CTX_set_tmp_dh(ctx, dh);
|
@@ -424,6 +433,18 @@ void Init_mini_ssl(VALUE puma) {
|
|
424
433
|
mod = rb_define_module_under(puma, "MiniSSL");
|
425
434
|
eng = rb_define_class_under(mod, "Engine", rb_cObject);
|
426
435
|
|
436
|
+
// OpenSSL Build / Runtime/Load versions
|
437
|
+
|
438
|
+
/* Version of OpenSSL that Puma was compiled with */
|
439
|
+
rb_define_const(mod, "OPENSSL_VERSION", rb_str_new2(OPENSSL_VERSION_TEXT));
|
440
|
+
|
441
|
+
#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000
|
442
|
+
/* Version of OpenSSL that Puma loaded with */
|
443
|
+
rb_define_const(mod, "OPENSSL_LIBRARY_VERSION", rb_str_new2(OpenSSL_version(OPENSSL_VERSION)));
|
444
|
+
#else
|
445
|
+
rb_define_const(mod, "OPENSSL_LIBRARY_VERSION", rb_str_new2(SSLeay_version(SSLEAY_VERSION)));
|
446
|
+
#endif
|
447
|
+
|
427
448
|
rb_define_singleton_method(mod, "check", noop, 0);
|
428
449
|
|
429
450
|
eError = rb_define_class_under(mod, "SSLError", rb_eStandardError);
|
@@ -170,6 +170,12 @@ public class MiniSSL extends RubyObject {
|
|
170
170
|
engine.setNeedClientAuth(true);
|
171
171
|
}
|
172
172
|
|
173
|
+
IRubyObject sslCipherListObject = miniSSLContext.callMethod(threadContext, "ssl_cipher_list");
|
174
|
+
if (!sslCipherListObject.isNil()) {
|
175
|
+
String[] sslCipherList = sslCipherListObject.convertToString().asJavaString().split(",");
|
176
|
+
engine.setEnabledCipherSuites(sslCipherList);
|
177
|
+
}
|
178
|
+
|
173
179
|
SSLSession session = engine.getSession();
|
174
180
|
inboundNetData = new MiniSSLBuffer(session.getPacketBufferSize());
|
175
181
|
outboundAppData = new MiniSSLBuffer(session.getApplicationBufferSize());
|
data/lib/puma/binder.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'uri'
|
2
4
|
require 'socket'
|
3
5
|
|
@@ -90,19 +92,19 @@ module Puma
|
|
90
92
|
case uri.scheme
|
91
93
|
when "tcp"
|
92
94
|
if fd = @inherited_fds.delete(str)
|
93
|
-
logger.log "* Inherited #{str}"
|
94
95
|
io = inherit_tcp_listener uri.host, uri.port, fd
|
96
|
+
logger.log "* Inherited #{str}"
|
95
97
|
elsif sock = @activated_sockets.delete([ :tcp, uri.host, uri.port ])
|
96
|
-
logger.log "* Activated #{str}"
|
97
98
|
io = inherit_tcp_listener uri.host, uri.port, sock
|
99
|
+
logger.log "* Activated #{str}"
|
98
100
|
else
|
99
101
|
params = Util.parse_query uri.query
|
100
102
|
|
101
103
|
opt = params.key?('low_latency')
|
102
104
|
bak = params.fetch('backlog', 1024).to_i
|
103
105
|
|
104
|
-
logger.log "* Listening on #{str}"
|
105
106
|
io = add_tcp_listener uri.host, uri.port, opt, bak
|
107
|
+
logger.log "* Listening on #{str}"
|
106
108
|
end
|
107
109
|
|
108
110
|
@listeners << [str, io] if io
|
@@ -110,14 +112,12 @@ module Puma
|
|
110
112
|
path = "#{uri.host}#{uri.path}".gsub("%20", " ")
|
111
113
|
|
112
114
|
if fd = @inherited_fds.delete(str)
|
113
|
-
logger.log "* Inherited #{str}"
|
114
115
|
io = inherit_unix_listener path, fd
|
116
|
+
logger.log "* Inherited #{str}"
|
115
117
|
elsif sock = @activated_sockets.delete([ :unix, path ])
|
116
|
-
logger.log "* Activated #{str}"
|
117
118
|
io = inherit_unix_listener path, sock
|
119
|
+
logger.log "* Activated #{str}"
|
118
120
|
else
|
119
|
-
logger.log "* Listening on #{str}"
|
120
|
-
|
121
121
|
umask = nil
|
122
122
|
mode = nil
|
123
123
|
backlog = 1024
|
@@ -139,6 +139,7 @@ module Puma
|
|
139
139
|
end
|
140
140
|
|
141
141
|
io = add_unix_listener path, umask, mode, backlog
|
142
|
+
logger.log "* Listening on #{str}"
|
142
143
|
end
|
143
144
|
|
144
145
|
@listeners << [str, io]
|
@@ -162,6 +163,7 @@ module Puma
|
|
162
163
|
end
|
163
164
|
|
164
165
|
ctx.keystore_pass = params['keystore-pass']
|
166
|
+
ctx.ssl_cipher_list = params['ssl_cipher_list'] if params['ssl_cipher_list']
|
165
167
|
else
|
166
168
|
unless params['key']
|
167
169
|
@events.error "Please specify the SSL key via 'key='"
|
@@ -182,6 +184,7 @@ module Puma
|
|
182
184
|
end
|
183
185
|
|
184
186
|
ctx.ca = params['ca'] if params['ca']
|
187
|
+
ctx.ssl_cipher_filter = params['ssl_cipher_filter'] if params['ssl_cipher_filter']
|
185
188
|
end
|
186
189
|
|
187
190
|
if params['verify_mode']
|
@@ -202,11 +205,11 @@ module Puma
|
|
202
205
|
logger.log "* Inherited #{str}"
|
203
206
|
io = inherit_ssl_listener fd, ctx
|
204
207
|
elsif sock = @activated_sockets.delete([ :tcp, uri.host, uri.port ])
|
205
|
-
logger.log "* Activated #{str}"
|
206
208
|
io = inherit_ssl_listener sock, ctx
|
209
|
+
logger.log "* Activated #{str}"
|
207
210
|
else
|
208
|
-
logger.log "* Listening on #{str}"
|
209
211
|
io = add_ssl_listener uri.host, uri.port, ctx
|
212
|
+
logger.log "* Listening on #{str}"
|
210
213
|
end
|
211
214
|
|
212
215
|
@listeners << [str, io] if io
|
@@ -313,6 +316,7 @@ module Puma
|
|
313
316
|
s.setsockopt(Socket::SOL_SOCKET,Socket::SO_REUSEADDR, true)
|
314
317
|
s.listen backlog
|
315
318
|
|
319
|
+
|
316
320
|
ssl = MiniSSL::Server.new s, ctx
|
317
321
|
env = @proto_env.dup
|
318
322
|
env[HTTPS_KEY] = HTTPS
|
data/lib/puma/cli.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'optparse'
|
2
4
|
require 'uri'
|
3
5
|
|
6
|
+
require 'puma'
|
4
7
|
require 'puma/configuration'
|
5
8
|
require 'puma/launcher'
|
6
9
|
require 'puma/const'
|
@@ -83,6 +86,14 @@ module Puma
|
|
83
86
|
raise UnsupportedOption
|
84
87
|
end
|
85
88
|
|
89
|
+
def configure_control_url(command_line_arg)
|
90
|
+
if command_line_arg
|
91
|
+
@control_url = command_line_arg
|
92
|
+
elsif Puma.jruby?
|
93
|
+
unsupported "No default url available on JRuby"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
86
97
|
# Build the OptionParser object to handle the available options.
|
87
98
|
#
|
88
99
|
|
@@ -97,13 +108,13 @@ module Puma
|
|
97
108
|
file_config.load arg
|
98
109
|
end
|
99
110
|
|
100
|
-
o.on "--control URL", "The bind url to use for the control server"
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
111
|
+
o.on "--control-url URL", "The bind url to use for the control server. Use 'auto' to use temp unix server" do |arg|
|
112
|
+
configure_control_url(arg)
|
113
|
+
end
|
114
|
+
|
115
|
+
# alias --control-url for backwards-compatibility
|
116
|
+
o.on "--control URL", "DEPRECATED alias for --control-url" do |arg|
|
117
|
+
configure_control_url(arg)
|
107
118
|
end
|
108
119
|
|
109
120
|
o.on "--control-token TOKEN",
|
data/lib/puma/client.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class IO
|
2
4
|
# We need to use this for a jruby work around on both 1.8 and 1.9.
|
3
5
|
# So this either creates the constant (on 1.8), or harmlessly
|
@@ -21,6 +23,17 @@ module Puma
|
|
21
23
|
|
22
24
|
class ConnectionError < RuntimeError; end
|
23
25
|
|
26
|
+
# An instance of this class represents a unique request from a client.
|
27
|
+
# For example a web request from a browser or from CURL. This
|
28
|
+
#
|
29
|
+
# An instance of `Puma::Client` can be used as if it were an IO object
|
30
|
+
# for example it is passed into `IO.select` inside of the `Puma::Reactor`.
|
31
|
+
# This is accomplished by the `to_io` method which gets called on any
|
32
|
+
# non-IO objects being used with the IO api such as `IO.select.
|
33
|
+
#
|
34
|
+
# Instances of this class are responsible for knowing if
|
35
|
+
# the header and body are fully buffered via the `try_to_finish` method.
|
36
|
+
# They can be used to "time out" a response via the `timeout_at` reader.
|
24
37
|
class Client
|
25
38
|
include Puma::Const
|
26
39
|
extend Puma::Delegation
|
@@ -157,6 +170,7 @@ module Puma
|
|
157
170
|
if len == 0
|
158
171
|
@body.rewind
|
159
172
|
rest = io.read
|
173
|
+
rest = rest[2..-1] if rest.start_with?("\r\n")
|
160
174
|
@buffer = rest.empty? ? nil : rest
|
161
175
|
@requests_served += 1
|
162
176
|
@ready = true
|
data/lib/puma/cluster.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'puma/runner'
|
2
4
|
require 'puma/util'
|
3
5
|
require 'puma/plugin'
|
@@ -5,6 +7,17 @@ require 'puma/plugin'
|
|
5
7
|
require 'time'
|
6
8
|
|
7
9
|
module Puma
|
10
|
+
# This class is instantiated by the `Puma::Launcher` and used
|
11
|
+
# to boot and serve a Ruby application when puma "workers" are needed
|
12
|
+
# i.e. when using multi-processes. For example `$ puma -w 5`
|
13
|
+
#
|
14
|
+
# At the core of this class is running an instance of `Puma::Server` which
|
15
|
+
# gets created via the `start_server` method from the `Puma::Runner` class
|
16
|
+
# that this inherits from.
|
17
|
+
#
|
18
|
+
# An instance of this class will spawn the number of processes passed in
|
19
|
+
# via the `spawn_workers` method call. Each worker will have it's own
|
20
|
+
# instance of a `Puma::Server`.
|
8
21
|
class Cluster < Runner
|
9
22
|
WORKER_CHECK_INTERVAL = 5
|
10
23
|
|
@@ -281,7 +294,9 @@ module Puma
|
|
281
294
|
begin
|
282
295
|
b = server.backlog || 0
|
283
296
|
r = server.running || 0
|
284
|
-
|
297
|
+
t = server.pool_capacity || 0
|
298
|
+
m = server.max_threads || 0
|
299
|
+
payload = %Q!#{base_payload}{ "backlog":#{b}, "running":#{r}, "pool_capacity":#{t}, "max_threads": #{m} }\n!
|
285
300
|
io << payload
|
286
301
|
rescue IOError
|
287
302
|
Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
|
data/lib/puma/commonlogger.rb
CHANGED
data/lib/puma/configuration.rb
CHANGED
data/lib/puma/const.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
#encoding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
2
4
|
module Puma
|
3
5
|
class UnsupportedOption < RuntimeError
|
4
6
|
end
|
@@ -98,8 +100,8 @@ module Puma
|
|
98
100
|
# too taxing on performance.
|
99
101
|
module Const
|
100
102
|
|
101
|
-
PUMA_VERSION = VERSION = "3.
|
102
|
-
CODE_NAME = "
|
103
|
+
PUMA_VERSION = VERSION = "3.12.1".freeze
|
104
|
+
CODE_NAME = "Llamas in Pajamas".freeze
|
103
105
|
PUMA_SERVER_STRING = ['puma', PUMA_VERSION, CODE_NAME].join(' ').freeze
|
104
106
|
|
105
107
|
FAST_TRACK_KA_TIMEOUT = 0.2
|
data/lib/puma/control_cli.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'optparse'
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
4
|
+
require_relative 'state_file'
|
5
|
+
require_relative 'const'
|
6
|
+
require_relative 'detect'
|
7
|
+
require_relative 'configuration'
|
6
8
|
require 'uri'
|
7
9
|
require 'socket'
|
8
10
|
|
@@ -69,6 +71,7 @@ module Puma
|
|
69
71
|
end
|
70
72
|
|
71
73
|
opts.order!(argv) { |a| opts.terminate a }
|
74
|
+
opts.parse!
|
72
75
|
|
73
76
|
@command = argv.shift
|
74
77
|
|
@@ -128,7 +131,7 @@ module Puma
|
|
128
131
|
uri = URI.parse @control_url
|
129
132
|
|
130
133
|
# create server object by scheme
|
131
|
-
|
134
|
+
server = case uri.scheme
|
132
135
|
when "tcp"
|
133
136
|
TCPSocket.new uri.host, uri.port
|
134
137
|
when "unix"
|
@@ -146,9 +149,9 @@ module Puma
|
|
146
149
|
url = url + "?token=#{@control_auth_token}"
|
147
150
|
end
|
148
151
|
|
149
|
-
|
152
|
+
server << "GET #{url} HTTP/1.0\r\n\r\n"
|
150
153
|
|
151
|
-
unless data =
|
154
|
+
unless data = server.read
|
152
155
|
raise "Server closed connection before responding"
|
153
156
|
end
|
154
157
|
|
@@ -171,8 +174,8 @@ module Puma
|
|
171
174
|
message "Command #{@command} sent success"
|
172
175
|
message response.last if @command == "stats" || @command == "gc-stats"
|
173
176
|
end
|
174
|
-
|
175
|
-
|
177
|
+
ensure
|
178
|
+
server.close if server && !server.closed?
|
176
179
|
end
|
177
180
|
|
178
181
|
def send_signal
|
@@ -204,7 +207,6 @@ module Puma
|
|
204
207
|
Process.kill "SIGUSR1", @pid
|
205
208
|
|
206
209
|
else
|
207
|
-
message "Puma is started"
|
208
210
|
return
|
209
211
|
end
|
210
212
|
|
@@ -220,7 +222,7 @@ module Puma
|
|
220
222
|
end
|
221
223
|
|
222
224
|
def run
|
223
|
-
start if @command == "start"
|
225
|
+
return start if @command == "start"
|
224
226
|
|
225
227
|
prepare_configuration
|
226
228
|
|
data/lib/puma/convenient.rb
CHANGED
data/lib/puma/daemon_ext.rb
CHANGED
data/lib/puma/delegation.rb
CHANGED
data/lib/puma/detect.rb
CHANGED
data/lib/puma/dsl.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Puma
|
2
4
|
# The methods that are available for use inside the config file.
|
3
5
|
# These same methods are used in Puma cli and the rack handler
|
@@ -55,6 +57,14 @@ module Puma
|
|
55
57
|
@plugins.clear
|
56
58
|
end
|
57
59
|
|
60
|
+
def set_default_host(host)
|
61
|
+
@options[:default_host] = host
|
62
|
+
end
|
63
|
+
|
64
|
+
def default_host
|
65
|
+
@options[:default_host] || Configuration::DefaultTCPHost
|
66
|
+
end
|
67
|
+
|
58
68
|
def inject(&blk)
|
59
69
|
instance_eval(&blk)
|
60
70
|
end
|
@@ -138,7 +148,7 @@ module Puma
|
|
138
148
|
# Define the TCP port to bind to. Use +bind+ for more advanced options.
|
139
149
|
#
|
140
150
|
def port(port, host=nil)
|
141
|
-
host ||=
|
151
|
+
host ||= default_host
|
142
152
|
bind "tcp://#{host}:#{port}"
|
143
153
|
end
|
144
154
|
|
@@ -146,13 +156,13 @@ module Puma
|
|
146
156
|
# them
|
147
157
|
#
|
148
158
|
def persistent_timeout(seconds)
|
149
|
-
@options[:persistent_timeout] = seconds
|
159
|
+
@options[:persistent_timeout] = Integer(seconds)
|
150
160
|
end
|
151
161
|
|
152
162
|
# Define how long the tcp socket stays open, if no data has been received
|
153
163
|
#
|
154
164
|
def first_data_timeout(seconds)
|
155
|
-
@options[:first_data_timeout] = seconds
|
165
|
+
@options[:first_data_timeout] = Integer(seconds)
|
156
166
|
end
|
157
167
|
|
158
168
|
# Work around leaky apps that leave garbage in Thread locals
|
@@ -169,7 +179,7 @@ module Puma
|
|
169
179
|
end
|
170
180
|
|
171
181
|
# When shutting down, drain the accept socket of pending
|
172
|
-
# connections and
|
182
|
+
# connections and process them. This loops over the accept
|
173
183
|
# socket until there are no more read events and then stops
|
174
184
|
# looking and waits for the requests to finish.
|
175
185
|
def drain_on_shutdown(which=true)
|
@@ -424,17 +434,17 @@ module Puma
|
|
424
434
|
# that have not checked in within the given +timeout+.
|
425
435
|
# This mitigates hung processes. Default value is 60 seconds.
|
426
436
|
def worker_timeout(timeout)
|
427
|
-
@options[:worker_timeout] = timeout
|
437
|
+
@options[:worker_timeout] = Integer(timeout)
|
428
438
|
end
|
429
439
|
|
430
440
|
# *Cluster mode only* Set the timeout for workers to boot
|
431
441
|
def worker_boot_timeout(timeout)
|
432
|
-
@options[:worker_boot_timeout] = timeout
|
442
|
+
@options[:worker_boot_timeout] = Integer(timeout)
|
433
443
|
end
|
434
444
|
|
435
445
|
# *Cluster mode only* Set the timeout for worker shutdown
|
436
446
|
def worker_shutdown_timeout(timeout)
|
437
|
-
@options[:worker_shutdown_timeout] = timeout
|
447
|
+
@options[:worker_shutdown_timeout] = Integer(timeout)
|
438
448
|
end
|
439
449
|
|
440
450
|
# When set to true (the default), workers accept all requests
|
@@ -493,7 +503,7 @@ module Puma
|
|
493
503
|
when Hash
|
494
504
|
if hdr = val[:header]
|
495
505
|
@options[:remote_address] = :header
|
496
|
-
@options[:remote_address_header] = "HTTP_" + hdr.upcase.
|
506
|
+
@options[:remote_address_header] = "HTTP_" + hdr.upcase.tr("-", "_")
|
497
507
|
else
|
498
508
|
raise "Invalid value for set_remote_address - #{val.inspect}"
|
499
509
|
end
|
data/lib/puma/events.rb
CHANGED
data/lib/puma/io_buffer.rb
CHANGED
data/lib/puma/java_io_buffer.rb
CHANGED