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.

Files changed (48) hide show
  1. checksums.yaml +5 -5
  2. data/History.md +40 -0
  3. data/README.md +15 -5
  4. data/docs/architecture.md +1 -1
  5. data/docs/restart.md +1 -1
  6. data/docs/systemd.md +10 -0
  7. data/ext/puma_http11/mini_ssl.c +22 -1
  8. data/ext/puma_http11/org/jruby/puma/MiniSSL.java +6 -0
  9. data/lib/puma/binder.rb +13 -9
  10. data/lib/puma/cli.rb +18 -7
  11. data/lib/puma/client.rb +14 -0
  12. data/lib/puma/cluster.rb +16 -1
  13. data/lib/puma/commonlogger.rb +2 -0
  14. data/lib/puma/configuration.rb +2 -0
  15. data/lib/puma/const.rb +4 -2
  16. data/lib/puma/control_cli.rb +13 -11
  17. data/lib/puma/convenient.rb +2 -0
  18. data/lib/puma/daemon_ext.rb +2 -0
  19. data/lib/puma/delegation.rb +2 -0
  20. data/lib/puma/detect.rb +2 -0
  21. data/lib/puma/dsl.rb +18 -8
  22. data/lib/puma/events.rb +2 -0
  23. data/lib/puma/io_buffer.rb +2 -0
  24. data/lib/puma/java_io_buffer.rb +2 -0
  25. data/lib/puma/jruby_restart.rb +2 -0
  26. data/lib/puma/launcher.rb +5 -2
  27. data/lib/puma/minissl.rb +7 -3
  28. data/lib/puma/null_io.rb +2 -0
  29. data/lib/puma/plugin.rb +2 -0
  30. data/lib/puma/rack/builder.rb +2 -1
  31. data/lib/puma/reactor.rb +134 -0
  32. data/lib/puma/runner.rb +10 -1
  33. data/lib/puma/server.rb +40 -4
  34. data/lib/puma/single.rb +12 -1
  35. data/lib/puma/state_file.rb +2 -0
  36. data/lib/puma/tcp_logger.rb +2 -0
  37. data/lib/puma/thread_pool.rb +46 -5
  38. data/lib/puma/util.rb +1 -0
  39. data/lib/puma.rb +8 -0
  40. data/lib/rack/handler/puma.rb +4 -0
  41. data/tools/jungle/README.md +10 -4
  42. data/tools/jungle/init.d/README.md +2 -0
  43. data/tools/jungle/init.d/puma +2 -2
  44. data/tools/jungle/init.d/run-puma +1 -1
  45. data/tools/jungle/rc.d/README.md +74 -0
  46. data/tools/jungle/rc.d/puma +61 -0
  47. data/tools/jungle/rc.d/puma.conf +10 -0
  48. metadata +11 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 4804608b8eb91d9bfd64c81497f624c5c623fdda
4
- data.tar.gz: 76eac44fc46d7a7d53fc83d5d67eb0d1cdbb14c3
2
+ SHA256:
3
+ metadata.gz: 5d0e3b5d74ced5d332fa04832c60b4b8b9c16514f3441cefea046d6ca4948025
4
+ data.tar.gz: 9462d0f9e3357c2b245f194b43281e5f8e5ebf0ee981e7658a938d880e3e4404
5
5
  SHA512:
6
- metadata.gz: 0ffda6912f5ab5aad0cd430dcfb73b8f4ac97764c205b6396ff545d7672ab828f626da30e881a8789a4dcee5e8a4346e383a3b69569cc2be7bde604165251c0a
7
- data.tar.gz: ef1bc4ef2372bfec240b4a36f60035c978ba45c8423db18c7372c3ca0f52a7dc90ba83ef9dfa2a5b20f85a832d0f4ba9a5ced2d41a165a6bd8b49d021c007721
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 -C 'tcp://127.0.0.1:9293' --control-token foo restart
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 syncronously do any waiting necessarry to read the HTTP request from the socket.
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 below).
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
@@ -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
- SSL_CTX_set_cipher_list(ctx, "HIGH:!aNULL@STRENGTH");
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
- "Use 'auto' to use temp unix server" do |arg|
102
- if arg
103
- @control_url = arg
104
- elsif Puma.jruby?
105
- unsupported "No default url available on JRuby"
106
- end
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
- payload = %Q!#{base_payload}{ "backlog":#{b}, "running":#{r} }\n!
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
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Puma
2
4
  # Rack::CommonLogger forwards every request to the given +app+, and
3
5
  # logs a line in the
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'puma/rack/builder'
2
4
  require 'puma/plugin'
3
5
  require 'puma/const'
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.11.3".freeze
102
- CODE_NAME = "Love Song".freeze
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
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'optparse'
2
- require 'puma/state_file'
3
- require 'puma/const'
4
- require 'puma/detect'
5
- require 'puma/configuration'
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
- @server = case uri.scheme
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
- @server << "GET #{url} HTTP/1.0\r\n\r\n"
152
+ server << "GET #{url} HTTP/1.0\r\n\r\n"
150
153
 
151
- unless data = @server.read
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
- @server.close
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
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'puma/launcher'
2
4
  require 'puma/configuration'
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Process
2
4
 
3
5
  # This overrides the default version because it is broken if it
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Puma
2
4
  module Delegation
3
5
  def forward(what, who)
data/lib/puma/detect.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Puma
2
4
  IS_JRUBY = defined?(JRUBY_VERSION)
3
5
 
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 ||= Configuration::DefaultTCPHost
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 proces them. This loops over the accept
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.gsub("-", "_")
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
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'puma/const'
2
4
  require "puma/null_io"
3
5
  require 'stringio'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'puma/detect'
2
4
 
3
5
  if Puma.jruby?
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'java'
2
4
 
3
5
  # Conservative native JRuby/Java implementation of IOBuffer
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'ffi'
2
4
 
3
5
  module Puma