puma 6.1.1 → 6.3.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of puma might be problematic. Click here for more details.

Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +76 -1
  3. data/LICENSE +0 -0
  4. data/README.md +39 -4
  5. data/bin/puma-wild +0 -0
  6. data/docs/architecture.md +0 -0
  7. data/docs/compile_options.md +0 -0
  8. data/docs/deployment.md +0 -0
  9. data/docs/fork_worker.md +0 -0
  10. data/docs/images/puma-connection-flow-no-reactor.png +0 -0
  11. data/docs/images/puma-connection-flow.png +0 -0
  12. data/docs/images/puma-general-arch.png +0 -0
  13. data/docs/jungle/README.md +0 -0
  14. data/docs/jungle/rc.d/README.md +0 -0
  15. data/docs/jungle/rc.d/puma.conf +0 -0
  16. data/docs/kubernetes.md +0 -0
  17. data/docs/nginx.md +0 -0
  18. data/docs/plugins.md +0 -0
  19. data/docs/rails_dev_mode.md +0 -0
  20. data/docs/restart.md +0 -0
  21. data/docs/signals.md +0 -0
  22. data/docs/stats.md +0 -0
  23. data/docs/systemd.md +0 -0
  24. data/docs/testing_benchmarks_local_files.md +0 -0
  25. data/docs/testing_test_rackup_ci_files.md +0 -0
  26. data/ext/puma_http11/PumaHttp11Service.java +0 -0
  27. data/ext/puma_http11/ext_help.h +0 -0
  28. data/ext/puma_http11/extconf.rb +0 -0
  29. data/ext/puma_http11/http11_parser.c +0 -0
  30. data/ext/puma_http11/http11_parser.h +0 -0
  31. data/ext/puma_http11/http11_parser.java.rl +0 -0
  32. data/ext/puma_http11/http11_parser.rl +0 -0
  33. data/ext/puma_http11/http11_parser_common.rl +0 -0
  34. data/ext/puma_http11/mini_ssl.c +30 -2
  35. data/ext/puma_http11/no_ssl/PumaHttp11Service.java +0 -0
  36. data/ext/puma_http11/org/jruby/puma/Http11.java +0 -0
  37. data/ext/puma_http11/org/jruby/puma/Http11Parser.java +0 -0
  38. data/ext/puma_http11/org/jruby/puma/MiniSSL.java +0 -0
  39. data/ext/puma_http11/puma_http11.c +0 -0
  40. data/lib/puma/app/status.rb +1 -1
  41. data/lib/puma/binder.rb +8 -6
  42. data/lib/puma/cli.rb +1 -1
  43. data/lib/puma/client.rb +18 -10
  44. data/lib/puma/cluster/worker.rb +0 -0
  45. data/lib/puma/cluster/worker_handle.rb +0 -0
  46. data/lib/puma/cluster.rb +0 -0
  47. data/lib/puma/commonlogger.rb +21 -14
  48. data/lib/puma/configuration.rb +1 -0
  49. data/lib/puma/const.rb +58 -9
  50. data/lib/puma/control_cli.rb +0 -0
  51. data/lib/puma/detect.rb +0 -0
  52. data/lib/puma/dsl.rb +78 -2
  53. data/lib/puma/error_logger.rb +2 -1
  54. data/lib/puma/events.rb +0 -0
  55. data/lib/puma/io_buffer.rb +0 -0
  56. data/lib/puma/jruby_restart.rb +0 -0
  57. data/lib/puma/json_serialization.rb +0 -0
  58. data/lib/puma/launcher/bundle_pruner.rb +0 -0
  59. data/lib/puma/launcher.rb +2 -0
  60. data/lib/puma/log_writer.rb +10 -4
  61. data/lib/puma/minissl/context_builder.rb +1 -0
  62. data/lib/puma/minissl.rb +17 -0
  63. data/lib/puma/plugin/systemd.rb +0 -0
  64. data/lib/puma/plugin/tmp_restart.rb +0 -0
  65. data/lib/puma/plugin.rb +0 -0
  66. data/lib/puma/rack/builder.rb +2 -2
  67. data/lib/puma/rack/urlmap.rb +0 -0
  68. data/lib/puma/rack_default.rb +1 -1
  69. data/lib/puma/reactor.rb +16 -7
  70. data/lib/puma/request.rb +64 -48
  71. data/lib/puma/runner.rb +0 -0
  72. data/lib/puma/sd_notify.rb +0 -0
  73. data/lib/puma/server.rb +16 -4
  74. data/lib/puma/single.rb +0 -0
  75. data/lib/puma/state_file.rb +0 -0
  76. data/lib/puma/thread_pool.rb +7 -3
  77. data/lib/puma/util.rb +0 -0
  78. data/lib/puma.rb +0 -0
  79. data/lib/rack/handler/puma.rb +12 -6
  80. data/tools/Dockerfile +0 -0
  81. data/tools/trickletest.rb +0 -0
  82. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6a987a441328b2f8be7f7a147af233c0c41b393b98714ed621e2508dc28819d8
4
- data.tar.gz: bc30afa48b1647abf34f6cf362e3374b76a7e25c605f3ed7e5fd1e7c96dad8fb
3
+ metadata.gz: dcbde9283993550beb848a4f777bf9d33a1e163f5356cfeeb40be3eede72e7d0
4
+ data.tar.gz: 5394fdd8307e5a1fd40c7cf560d01565a6a9d69fd0fa0006ff6b28e483e627aa
5
5
  SHA512:
6
- metadata.gz: 4a1a05276e82ffd6d012bc75e6f38c2bf30932cb9cd9a6b73a14d783e012f4b942128a72bf0bb8f9bbf8a0062c03d5df234a6baccbc490a2bb64150f480b531f
7
- data.tar.gz: 6127f2e9b3fd82795696ecd8e0f2016b7252f71d86433087c42c826c7d0d1cc8d2ceda8e4243bf99969d96ba261172e39d59e977ba24d5d75225d7707c64f2a9
6
+ metadata.gz: 473b3047986b69763e01fb3b3f7fc1137070cb041ae235e520216e568860295a3b0ed105e4c52ee1d3aa05353d1b247e0782a1aa7bde840a540200f21d84320b
7
+ data.tar.gz: 69e625526fcc0b7216a419326e172114ed0ba4c7842722c1f896ed4d2fd559e4b58ea31f95a7ca52d37f11b5930433cfa6faab3f510996a39b1de3d3ff46d2a7
data/History.md CHANGED
@@ -1,3 +1,50 @@
1
+ ## 6.3.1 / 2023-08-18
2
+
3
+ * Security
4
+ * Address HTTP request smuggling vulnerabilities with zero-length Content Length header and trailer fields ([GHSA-68xg-gqqm-vgj8](https://github.com/puma/puma/security/advisories/GHSA-68xg-gqqm-vgj8))
5
+
6
+ ## 6.3.0 / 2023-05-31
7
+
8
+ * Features
9
+ * Add dsl method `supported_http_methods` ([#3106], [#3014])
10
+ * Puma error responses no longer have any fingerprints to indicate Puma ([#3161], [#3037])
11
+ * Support decryption of SSL key ([#3133], [#3132])
12
+
13
+ * Bugfixes
14
+ * Don't send 103 early hints response when only invalid headers are used ([#3163])
15
+ * Handle malformed request path ([#3155], [#3148])
16
+ * Misc lib file fixes - trapping additional errors, CI helper ([#3129])
17
+ * Fixup req form data file upload with "r\n" line endings ([#3137])
18
+ * Restore rack 1.6 compatibility Restore rack 1.6 compatibility ([#3156])
19
+
20
+ * Refactor
21
+ * const.rb - Update Puma::HTTP_STATUS_CODES ([#3162])
22
+ * Clarify Reactor#initialize ([#3151])
23
+
24
+ ## 6.2.2 / 2023-04-17
25
+
26
+ * Bugfixes
27
+ * Fix Rack-related NameError by adding :: operator ([#3118], [#3117])
28
+
29
+ ## 6.2.1 / 2023-03-31
30
+
31
+ * Bugfixes
32
+ * Fix java 8 compatibility ([#3109], [#3108])
33
+ * Always write io_buffer when in "enum bodies" branch. ([#3113], [#3112])
34
+ * Fix warn_if_in_single_mode incorrect message ([#3111])
35
+
36
+ ## 6.2.0 / 2023-03-29
37
+
38
+ * Features
39
+ * Ability to supply a custom logger ([#2770], [#2511])
40
+ * Warn when clustered-only hooks are defined in single mode ([#3089])
41
+ * Adds the on_booted event ([#2709])
42
+
43
+ * Bugfixes
44
+ * Loggers - internal_write - catch Errno::EINVAL ([#3091])
45
+ * commonlogger.rb - fix HIJACK time format, use constants, not strings ([#3074])
46
+ * Fixed some edge cases regarding request hijacking ([#3072])
47
+
1
48
  ## 6.1.1 / 2023-02-28
2
49
 
3
50
  * Bugfixes
@@ -1954,6 +2001,34 @@ be added back in a future date when a java Puma::MiniSSL is added.
1954
2001
  * Bugfixes
1955
2002
  * Your bugfix goes here <Most recent on the top, like GitHub> (#Github Number)
1956
2003
 
2004
+ [#3106]:https://github.com/puma/puma/pull/3106 "PR by @MSP-Greg, merged 2023-05-29"
2005
+ [#3014]:https://github.com/puma/puma/issues/3014 "Issue by @kyledrake, closed 2023-05-29"
2006
+ [#3161]:https://github.com/puma/puma/pull/3161 "PR by @MSP-Greg, merged 2023-05-27"
2007
+ [#3037]:https://github.com/puma/puma/issues/3037 "Issue by @daisy1754, closed 2023-05-27"
2008
+ [#3133]:https://github.com/puma/puma/pull/3133 "PR by @stanhu, merged 2023-04-30"
2009
+ [#3132]:https://github.com/puma/puma/issues/3132 "Issue by @stanhu, closed 2023-04-30"
2010
+ [#3163]:https://github.com/puma/puma/pull/3163 "PR by @MSP-Greg, merged 2023-05-27"
2011
+ [#3155]:https://github.com/puma/puma/pull/3155 "PR by @dentarg, merged 2023-05-14"
2012
+ [#3148]:https://github.com/puma/puma/issues/3148 "Issue by @dentarg, closed 2023-05-14"
2013
+ [#3129]:https://github.com/puma/puma/pull/3129 "PR by @MSP-Greg, merged 2023-05-02"
2014
+ [#3137]:https://github.com/puma/puma/pull/3137 "PR by @MSP-Greg, merged 2023-04-30"
2015
+ [#3156]:https://github.com/puma/puma/pull/3156 "PR by @severin, merged 2023-05-16"
2016
+ [#3162]:https://github.com/puma/puma/pull/3162 "PR by @MSP-Greg, merged 2023-05-23"
2017
+ [#3151]:https://github.com/puma/puma/pull/3151 "PR by @nateberkopec, merged 2023-05-12"
2018
+ [#3118]:https://github.com/puma/puma/pull/3118 "PR by @ninoseki, merged 2023-04-01"
2019
+ [#3117]:https://github.com/puma/puma/issues/3117 "Issue by @ninoseki, closed 2023-04-01"
2020
+ [#3109]:https://github.com/puma/puma/pull/3109 "PR by @ahorek, merged 2023-03-31"
2021
+ [#3108]:https://github.com/puma/puma/issues/3108 "Issue by @treviateo, closed 2023-03-31"
2022
+ [#3113]:https://github.com/puma/puma/pull/3113 "PR by @collinsauve, merged 2023-03-31"
2023
+ [#3112]:https://github.com/puma/puma/issues/3112 "Issue by @dmke, closed 2023-03-31"
2024
+ [#3111]:https://github.com/puma/puma/pull/3111 "PR by @adzap, merged 2023-03-30"
2025
+ [#2770]:https://github.com/puma/puma/pull/2770 "PR by @vzajkov, merged 2023-03-29"
2026
+ [#2511]:https://github.com/puma/puma/issues/2511 "Issue by @jchristie55332, closed 2021-12-12"
2027
+ [#3089]:https://github.com/puma/puma/pull/3089 "PR by @Vuta, merged 2023-03-06"
2028
+ [#2709]:https://github.com/puma/puma/pull/2709 "PR by @rodzyn, merged 2023-02-20"
2029
+ [#3091]:https://github.com/puma/puma/pull/3091 "PR by @MSP-Greg, merged 2023-03-28"
2030
+ [#3074]:https://github.com/puma/puma/pull/3074 "PR by @MSP-Greg, merged 2023-03-14"
2031
+ [#3072]:https://github.com/puma/puma/pull/3072 "PR by @MSP-Greg, merged 2023-02-17"
1957
2032
  [#3079]:https://github.com/puma/puma/pull/3079 "PR by @mohamedhafez, merged 2023-02-24"
1958
2033
  [#3080]:https://github.com/puma/puma/pull/3080 "PR by @MSP-Greg, merged 2023-02-16"
1959
2034
  [#3058]:https://github.com/puma/puma/pull/3058 "PR by @dentarg, merged 2023-01-29"
@@ -2050,7 +2125,7 @@ be added back in a future date when a java Puma::MiniSSL is added.
2050
2125
  [#2794]:https://github.com/puma/puma/pull/2794 "PR by @johnnyshields, merged 2022-01-10"
2051
2126
  [#2759]:https://github.com/puma/puma/pull/2759 "PR by @ob-stripe, merged 2021-12-11"
2052
2127
  [#2731]:https://github.com/puma/puma/pull/2731 "PR by @baelter, merged 2021-11-02"
2053
- [#2341]:https://github.com/puma/puma/issues/2341 "Issue by @cjlarose, closed 2021-11-02"
2128
+ [#2341]:https://github.com/puma/puma/issues/2341 "Issue by @cjlarose, opened 2020-08-18"
2054
2129
  [#2728]:https://github.com/puma/puma/pull/2728 "PR by @dalibor, merged 2021-10-31"
2055
2130
  [#2733]:https://github.com/puma/puma/pull/2733 "PR by @ob-stripe, merged 2021-12-12"
2056
2131
  [#2807]:https://github.com/puma/puma/pull/2807 "PR by @MSP-Greg, merged 2022-01-25"
data/LICENSE CHANGED
File without changes
data/README.md CHANGED
@@ -157,6 +157,15 @@ before_fork do
157
157
  end
158
158
  ```
159
159
 
160
+ You can also specify a block to be run after puma is booted using `on_booted`:
161
+
162
+ ```ruby
163
+ # config/puma.rb
164
+ on_booted do
165
+ # configuration here
166
+ end
167
+ ```
168
+
160
169
  ### Error handling
161
170
 
162
171
  If puma encounters an error outside of the context of your application, it will respond with a 500 and a simple
@@ -270,6 +279,30 @@ $ puma -b 'ssl://127.0.0.1:9292?key=path_to_key&cert=path_to_cert&verification_f
270
279
  List of available flags: `USE_CHECK_TIME`, `CRL_CHECK`, `CRL_CHECK_ALL`, `IGNORE_CRITICAL`, `X509_STRICT`, `ALLOW_PROXY_CERTS`, `POLICY_CHECK`, `EXPLICIT_POLICY`, `INHIBIT_ANY`, `INHIBIT_MAP`, `NOTIFY_POLICY`, `EXTENDED_CRL_SUPPORT`, `USE_DELTAS`, `CHECK_SS_SIGNATURE`, `TRUSTED_FIRST`, `SUITEB_128_LOS_ONLY`, `SUITEB_192_LOS`, `SUITEB_128_LOS`, `PARTIAL_CHAIN`, `NO_ALT_CHAINS`, `NO_CHECK_TIME`
271
280
  (see https://www.openssl.org/docs/manmaster/man3/X509_VERIFY_PARAM_set_hostflags.html#VERIFICATION-FLAGS).
272
281
 
282
+ #### Controlling OpenSSL Password Decryption
283
+
284
+ To enable runtime decryption of an encrypted SSL key (not available for JRuby), use `key_password_command`:
285
+
286
+ ```
287
+ $ puma -b 'ssl://127.0.0.1:9292?key=path_to_key&cert=path_to_cert&key_password_command=/path/to/command.sh'
288
+ ```
289
+
290
+ `key_password_command` must:
291
+
292
+ 1. Be executable by Puma.
293
+ 2. Print the decryption password to stdout.
294
+
295
+ For example:
296
+
297
+ ```shell
298
+ #!/bin/sh
299
+
300
+ echo "this is my password"
301
+ ```
302
+
303
+ `key_password_command` can be used with `key` or `key_pem`. If the key
304
+ is not encrypted, the executable will not be called.
305
+
273
306
  ### Control/Status Server
274
307
 
275
308
  Puma has a built-in status and control app that can be used to query and control Puma.
@@ -345,11 +378,13 @@ end
345
378
 
346
379
  ## Deployment
347
380
 
348
- Puma has support for Capistrano with an [external gem](https://github.com/seuros/capistrano-puma).
381
+ * Puma has support for Capistrano with an [external gem](https://github.com/seuros/capistrano-puma).
382
+
383
+ * Additionally, Puma has support for built-in daemonization via the [puma-daemon](https://github.com/kigster/puma-daemon) ruby gem. The gem restores the `daemonize` option that was removed from Puma starting version 5, but only for MRI Ruby.
384
+
349
385
 
350
386
  It is common to use process monitors with Puma. Modern process monitors like systemd or rc.d
351
- provide continuous monitoring and restarts for increased
352
- reliability in production environments:
387
+ provide continuous monitoring and restarts for increased reliability in production environments:
353
388
 
354
389
  * [rc.d](docs/jungle/rc.d/README.md)
355
390
  * [systemd](docs/systemd.md)
@@ -364,7 +399,7 @@ Community guides:
364
399
 
365
400
  * [puma-metrics](https://github.com/harmjanblok/puma-metrics) — export Puma metrics to Prometheus
366
401
  * [puma-plugin-statsd](https://github.com/yob/puma-plugin-statsd) — send Puma metrics to statsd
367
- * [puma-plugin-systemd](https://github.com/sj26/puma-plugin-systemd) — deeper integration with systemd for notify, status and watchdog
402
+ * [puma-plugin-systemd](https://github.com/sj26/puma-plugin-systemd) — deeper integration with systemd for notify, status and watchdog. Puma 5.1.0 integrated notify and watchdog, which probably conflicts with this plugin. Puma 6.1.0 added status support which obsoletes the plugin entirely.
368
403
  * [puma-plugin-telemetry](https://github.com/babbel/puma-plugin-telemetry) - telemetry plugin for Puma offering various targets to publish
369
404
 
370
405
  ### Monitoring
data/bin/puma-wild CHANGED
File without changes
data/docs/architecture.md CHANGED
File without changes
File without changes
data/docs/deployment.md CHANGED
File without changes
data/docs/fork_worker.md CHANGED
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
data/docs/kubernetes.md CHANGED
File without changes
data/docs/nginx.md CHANGED
File without changes
data/docs/plugins.md CHANGED
File without changes
File without changes
data/docs/restart.md CHANGED
File without changes
data/docs/signals.md CHANGED
File without changes
data/docs/stats.md CHANGED
File without changes
data/docs/systemd.md CHANGED
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -185,6 +185,18 @@ static int engine_verify_callback(int preverify_ok, X509_STORE_CTX* ctx) {
185
185
  return preverify_ok;
186
186
  }
187
187
 
188
+ static int password_callback(char *buf, int size, int rwflag, void *userdata) {
189
+ const char *password = (const char *) userdata;
190
+ size_t len = strlen(password);
191
+
192
+ if (len > (size_t) size) {
193
+ return 0;
194
+ }
195
+
196
+ memcpy(buf, password, len);
197
+ return (int) len;
198
+ }
199
+
188
200
  static VALUE
189
201
  sslctx_alloc(VALUE klass) {
190
202
  SSL_CTX *ctx;
@@ -212,10 +224,12 @@ sslctx_initialize(VALUE self, VALUE mini_ssl_ctx) {
212
224
  SSL_CTX* ctx;
213
225
  int ssl_options;
214
226
  VALUE key, cert, ca, verify_mode, ssl_cipher_filter, no_tlsv1, no_tlsv1_1,
215
- verification_flags, session_id_bytes, cert_pem, key_pem;
227
+ verification_flags, session_id_bytes, cert_pem, key_pem, key_password_command, key_password;
216
228
  BIO *bio;
217
229
  X509 *x509;
218
230
  EVP_PKEY *pkey;
231
+ pem_password_cb *password_cb = NULL;
232
+ const char *password = NULL;
219
233
  #ifdef HAVE_SSL_CTX_SET_MIN_PROTO_VERSION
220
234
  int min;
221
235
  #endif
@@ -235,6 +249,8 @@ sslctx_initialize(VALUE self, VALUE mini_ssl_ctx) {
235
249
 
236
250
  key = rb_funcall(mini_ssl_ctx, rb_intern_const("key"), 0);
237
251
 
252
+ key_password_command = rb_funcall(mini_ssl_ctx, rb_intern_const("key_password_command"), 0);
253
+
238
254
  cert = rb_funcall(mini_ssl_ctx, rb_intern_const("cert"), 0);
239
255
 
240
256
  ca = rb_funcall(mini_ssl_ctx, rb_intern_const("ca"), 0);
@@ -261,6 +277,18 @@ sslctx_initialize(VALUE self, VALUE mini_ssl_ctx) {
261
277
  }
262
278
  }
263
279
 
280
+ if (!NIL_P(key_password_command)) {
281
+ key_password = rb_funcall(mini_ssl_ctx, rb_intern_const("key_password"), 0);
282
+
283
+ if (!NIL_P(key_password)) {
284
+ StringValue(key_password);
285
+ password_cb = password_callback;
286
+ password = RSTRING_PTR(key_password);
287
+ SSL_CTX_set_default_passwd_cb(ctx, password_cb);
288
+ SSL_CTX_set_default_passwd_cb_userdata(ctx, (void *) password);
289
+ }
290
+ }
291
+
264
292
  if (!NIL_P(key)) {
265
293
  StringValue(key);
266
294
 
@@ -285,7 +313,7 @@ sslctx_initialize(VALUE self, VALUE mini_ssl_ctx) {
285
313
  if (!NIL_P(key_pem)) {
286
314
  bio = BIO_new(BIO_s_mem());
287
315
  BIO_puts(bio, RSTRING_PTR(key_pem));
288
- pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
316
+ pkey = PEM_read_bio_PrivateKey(bio, NULL, password_cb, (void *) password);
289
317
 
290
318
  if (SSL_CTX_use_PrivateKey(ctx, pkey) != 1) {
291
319
  BIO_free(bio);
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -80,7 +80,7 @@ module Puma
80
80
 
81
81
  def authenticate(env)
82
82
  return true unless @auth_token
83
- env['QUERY_STRING'].to_s.split(/&;/).include?("token=#{@auth_token}")
83
+ env['QUERY_STRING'].to_s.split('&;').include? "token=#{@auth_token}"
84
84
  end
85
85
 
86
86
  def rack_response(status, body, content_type='application/json')
data/lib/puma/binder.rb CHANGED
@@ -48,7 +48,6 @@ module Puma
48
48
 
49
49
  @envs = {}
50
50
  @ios = []
51
- localhost_authority
52
51
  end
53
52
 
54
53
  attr_reader :ios
@@ -451,11 +450,14 @@ module Puma
451
450
 
452
451
  def close_listeners
453
452
  @listeners.each do |l, io|
454
- io.close unless io.closed?
455
- uri = URI.parse l
456
- next unless uri.scheme == 'unix'
457
- unix_path = "#{uri.host}#{uri.path}"
458
- File.unlink unix_path if @unix_paths.include?(unix_path) && File.exist?(unix_path)
453
+ begin
454
+ io.close unless io.closed?
455
+ uri = URI.parse l
456
+ next unless uri.scheme == 'unix'
457
+ unix_path = "#{uri.host}#{uri.path}"
458
+ File.unlink unix_path if @unix_paths.include?(unix_path) && File.exist?(unix_path)
459
+ rescue Errno::EBADF
460
+ end
459
461
  end
460
462
  end
461
463
 
data/lib/puma/cli.rb CHANGED
@@ -93,7 +93,7 @@ module Puma
93
93
  #
94
94
 
95
95
  def setup_options
96
- @conf = Configuration.new do |user_config, file_config|
96
+ @conf = Configuration.new({}, {events: @events}) do |user_config, file_config|
97
97
  @parser = OptionParser.new do |o|
98
98
  o.on "-b", "--bind URI", "URI to bind to (tcp://, unix://, ssl://)" do |arg|
99
99
  user_config.bind arg
data/lib/puma/client.rb CHANGED
@@ -49,7 +49,8 @@ module Puma
49
49
 
50
50
  # chunked body validation
51
51
  CHUNK_SIZE_INVALID = /[^\h]/.freeze
52
- CHUNK_VALID_ENDING = "\r\n".freeze
52
+ CHUNK_VALID_ENDING = Const::LINE_END
53
+ CHUNK_VALID_ENDING_SIZE = CHUNK_VALID_ENDING.bytesize
53
54
 
54
55
  # Content-Length header value validation
55
56
  CONTENT_LENGTH_VALUE_INVALID = /[^\d]/.freeze
@@ -68,7 +69,7 @@ module Puma
68
69
  @to_io = io.to_io
69
70
  @io_buffer = IOBuffer.new
70
71
  @proto_env = env
71
- @env = env ? env.dup : nil
72
+ @env = env&.dup
72
73
 
73
74
  @parser = HttpParser.new
74
75
  @parsed_bytes = 0
@@ -99,7 +100,8 @@ module Puma
99
100
 
100
101
  @in_last_chunk = false
101
102
 
102
- @read_buffer = +""
103
+ # need unfrozen ASCII-8BIT, +'' is UTF-8
104
+ @read_buffer = String.new # rubocop: disable Performance/UnfreezeString
103
105
  end
104
106
 
105
107
  attr_reader :env, :to_io, :body, :io, :timeout_at, :ready, :hijacked,
@@ -381,8 +383,8 @@ module Puma
381
383
  cl = @env[CONTENT_LENGTH]
382
384
 
383
385
  if cl
384
- # cannot contain characters that are not \d
385
- if CONTENT_LENGTH_VALUE_INVALID.match? cl
386
+ # cannot contain characters that are not \d, or be empty
387
+ if CONTENT_LENGTH_VALUE_INVALID.match?(cl) || cl.empty?
386
388
  raise HttpParserError, "Invalid Content-Length: #{cl.inspect}"
387
389
  end
388
390
  else
@@ -543,7 +545,7 @@ module Puma
543
545
 
544
546
  while !io.eof?
545
547
  line = io.gets
546
- if line.end_with?("\r\n")
548
+ if line.end_with?(CHUNK_VALID_ENDING)
547
549
  # Puma doesn't process chunk extensions, but should parse if they're
548
550
  # present, which is the reason for the semicolon regex
549
551
  chunk_hex = line.strip[/\A[^;]+/]
@@ -555,13 +557,19 @@ module Puma
555
557
  @in_last_chunk = true
556
558
  @body.rewind
557
559
  rest = io.read
558
- last_crlf_size = "\r\n".bytesize
559
- if rest.bytesize < last_crlf_size
560
+ if rest.bytesize < CHUNK_VALID_ENDING_SIZE
560
561
  @buffer = nil
561
- @partial_part_left = last_crlf_size - rest.bytesize
562
+ @partial_part_left = CHUNK_VALID_ENDING_SIZE - rest.bytesize
562
563
  return false
563
564
  else
564
- @buffer = rest[last_crlf_size..-1]
565
+ # if the next character is a CRLF, set buffer to everything after that CRLF
566
+ start_of_rest = if rest.start_with?(CHUNK_VALID_ENDING)
567
+ CHUNK_VALID_ENDING_SIZE
568
+ else # we have started a trailer section, which we do not support. skip it!
569
+ rest.index(CHUNK_VALID_ENDING*2) + CHUNK_VALID_ENDING_SIZE*2
570
+ end
571
+
572
+ @buffer = rest[start_of_rest..-1]
565
573
  @buffer = nil if @buffer.empty?
566
574
  set_ready
567
575
  return true
File without changes
File without changes
data/lib/puma/cluster.rb CHANGED
File without changes
@@ -3,7 +3,7 @@
3
3
  module Puma
4
4
  # Rack::CommonLogger forwards every request to the given +app+, and
5
5
  # logs a line in the
6
- # {Apache common log format}[https://httpd.apache.org/docs/1.3/logs.html#common]
6
+ # {Apache common log format}[https://httpd.apache.org/docs/2.4/logs.html#common]
7
7
  # to the +logger+.
8
8
  #
9
9
  # If +logger+ is nil, CommonLogger will fall back +rack.errors+, which is
@@ -16,7 +16,7 @@ module Puma
16
16
  # (which is called without arguments in order to make the error appear for
17
17
  # sure)
18
18
  class CommonLogger
19
- # Common Log Format: https://httpd.apache.org/docs/1.3/logs.html#common
19
+ # Common Log Format: https://httpd.apache.org/docs/2.4/logs.html#common
20
20
  #
21
21
  # lilith.local - - [07/Aug/2006 23:58:02 -0400] "GET / HTTP/1.1" 500 -
22
22
  #
@@ -25,10 +25,17 @@ module Puma
25
25
 
26
26
  HIJACK_FORMAT = %{%s - %s [%s] "%s %s%s %s" HIJACKED -1 %0.4f\n}
27
27
 
28
- CONTENT_LENGTH = 'Content-Length'.freeze
29
- PATH_INFO = 'PATH_INFO'.freeze
30
- QUERY_STRING = 'QUERY_STRING'.freeze
31
- REQUEST_METHOD = 'REQUEST_METHOD'.freeze
28
+ LOG_TIME_FORMAT = '%d/%b/%Y:%H:%M:%S %z'
29
+
30
+ CONTENT_LENGTH = 'Content-Length' # should be lower case from app,
31
+ # Util::HeaderHash allows mixed
32
+ HTTP_VERSION = Const::HTTP_VERSION
33
+ HTTP_X_FORWARDED_FOR = Const::HTTP_X_FORWARDED_FOR
34
+ PATH_INFO = Const::PATH_INFO
35
+ QUERY_STRING = Const::QUERY_STRING
36
+ REMOTE_ADDR = Const::REMOTE_ADDR
37
+ REMOTE_USER = 'REMOTE_USER'
38
+ REQUEST_METHOD = Const::REQUEST_METHOD
32
39
 
33
40
  def initialize(app, logger=nil)
34
41
  @app = app
@@ -57,13 +64,13 @@ module Puma
57
64
  now = Time.now
58
65
 
59
66
  msg = HIJACK_FORMAT % [
60
- env['HTTP_X_FORWARDED_FOR'] || env["REMOTE_ADDR"] || "-",
61
- env["REMOTE_USER"] || "-",
62
- now.strftime("%d/%b/%Y %H:%M:%S"),
67
+ env[HTTP_X_FORWARDED_FOR] || env[REMOTE_ADDR] || "-",
68
+ env[REMOTE_USER] || "-",
69
+ now.strftime(LOG_TIME_FORMAT),
63
70
  env[REQUEST_METHOD],
64
71
  env[PATH_INFO],
65
72
  env[QUERY_STRING].empty? ? "" : "?#{env[QUERY_STRING]}",
66
- env["HTTP_VERSION"],
73
+ env[HTTP_VERSION],
67
74
  now - began_at ]
68
75
 
69
76
  write(msg)
@@ -74,13 +81,13 @@ module Puma
74
81
  length = extract_content_length(header)
75
82
 
76
83
  msg = FORMAT % [
77
- env['HTTP_X_FORWARDED_FOR'] || env["REMOTE_ADDR"] || "-",
78
- env["REMOTE_USER"] || "-",
79
- now.strftime("%d/%b/%Y:%H:%M:%S %z"),
84
+ env[HTTP_X_FORWARDED_FOR] || env[REMOTE_ADDR] || "-",
85
+ env[REMOTE_USER] || "-",
86
+ now.strftime(LOG_TIME_FORMAT),
80
87
  env[REQUEST_METHOD],
81
88
  env[PATH_INFO],
82
89
  env[QUERY_STRING].empty? ? "" : "?#{env[QUERY_STRING]}",
83
- env["HTTP_VERSION"],
90
+ env[HTTP_VERSION],
84
91
  status.to_s[0..3],
85
92
  length,
86
93
  now - began_at ]
@@ -157,6 +157,7 @@ module Puma
157
157
  reaping_time: 1,
158
158
  remote_address: :socket,
159
159
  silence_single_worker_warning: false,
160
+ silence_fork_callback_warning: false,
160
161
  tag: File.basename(Dir.getwd),
161
162
  tcp_host: '0.0.0.0'.freeze,
162
163
  tcp_port: 9292,