puma 5.6.5 → 6.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +102 -11
  3. data/README.md +21 -17
  4. data/bin/puma-wild +1 -1
  5. data/docs/compile_options.md +34 -0
  6. data/docs/fork_worker.md +1 -3
  7. data/docs/testing_benchmarks_local_files.md +150 -0
  8. data/docs/testing_test_rackup_ci_files.md +36 -0
  9. data/ext/puma_http11/extconf.rb +11 -8
  10. data/ext/puma_http11/http11_parser.c +1 -1
  11. data/ext/puma_http11/http11_parser.h +1 -1
  12. data/ext/puma_http11/http11_parser.java.rl +2 -2
  13. data/ext/puma_http11/http11_parser.rl +2 -2
  14. data/ext/puma_http11/http11_parser_common.rl +2 -2
  15. data/ext/puma_http11/mini_ssl.c +36 -15
  16. data/ext/puma_http11/org/jruby/puma/Http11.java +3 -3
  17. data/ext/puma_http11/org/jruby/puma/Http11Parser.java +1 -1
  18. data/ext/puma_http11/org/jruby/puma/MiniSSL.java +156 -53
  19. data/ext/puma_http11/puma_http11.c +17 -9
  20. data/lib/puma/app/status.rb +3 -3
  21. data/lib/puma/binder.rb +36 -42
  22. data/lib/puma/cli.rb +11 -17
  23. data/lib/puma/client.rb +22 -12
  24. data/lib/puma/cluster/worker.rb +13 -11
  25. data/lib/puma/cluster/worker_handle.rb +4 -1
  26. data/lib/puma/cluster.rb +28 -25
  27. data/lib/puma/configuration.rb +74 -58
  28. data/lib/puma/const.rb +14 -18
  29. data/lib/puma/control_cli.rb +3 -6
  30. data/lib/puma/detect.rb +2 -0
  31. data/lib/puma/dsl.rb +93 -52
  32. data/lib/puma/error_logger.rb +17 -9
  33. data/lib/puma/events.rb +6 -126
  34. data/lib/puma/io_buffer.rb +29 -4
  35. data/lib/puma/jruby_restart.rb +2 -1
  36. data/lib/puma/launcher/bundle_pruner.rb +104 -0
  37. data/lib/puma/launcher.rb +96 -156
  38. data/lib/puma/log_writer.rb +137 -0
  39. data/lib/puma/minissl/context_builder.rb +23 -12
  40. data/lib/puma/minissl.rb +82 -11
  41. data/lib/puma/plugin/tmp_restart.rb +1 -1
  42. data/lib/puma/rack/builder.rb +4 -4
  43. data/lib/puma/rack_default.rb +1 -1
  44. data/lib/puma/reactor.rb +3 -3
  45. data/lib/puma/request.rb +292 -161
  46. data/lib/puma/runner.rb +41 -20
  47. data/lib/puma/server.rb +53 -66
  48. data/lib/puma/single.rb +10 -10
  49. data/lib/puma/state_file.rb +1 -4
  50. data/lib/puma/systemd.rb +3 -2
  51. data/lib/puma/thread_pool.rb +16 -13
  52. data/lib/puma/util.rb +0 -11
  53. data/lib/puma.rb +11 -8
  54. data/lib/rack/handler/puma.rb +9 -9
  55. metadata +7 -3
  56. data/lib/puma/queue_close.rb +0 -26
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7be1244aa7c9d74f0021e1763e05b7220ceb3630b41ef7cf2205b71d5f5cf494
4
- data.tar.gz: 802a80a1437d272cfbd101be2fa5370860fd3745b17996661db5eaa47b98b0e1
3
+ metadata.gz: c8a1a6014d9e1130e8ba06d5f74d472216448df3dbce4c15c4c24c91fbfe5e30
4
+ data.tar.gz: f1be3485e37cd230f6c35854aeb959ffeab1dac0162bf482799a4755222bc498
5
5
  SHA512:
6
- metadata.gz: f99a9be986d9c7d617b7dbbdae9072e183b7dc957df74f353b110223f1194350a4d87614869aaaae133c737c2ddb12633989850adee14c97e088db830a6e5754
7
- data.tar.gz: 684325223794be8efc7adf39c7eba75bb326bd3646a15aca28ebe92e83b5c836706ca37aeb6c5ec14bb4c9fcdb74ceb8c3b6d146ec862fb5008337c5430b66cc
6
+ metadata.gz: bbdd201a97e5dffccbbb8d8f336693746b87763313422a94ac21f73641ca712b9d2461051cc0bd02771b51af606ce595c2dd09bff0c716146cf9ac56e7ae51f4
7
+ data.tar.gz: e378848b22d1139559edd6736a9164a5cd98064c6232f0b2cc108122f79c93429ec33b156baa17e6ff82e9b3c77dbddbd22b2a0525a16f749129cf6f70c006da
data/History.md CHANGED
@@ -1,8 +1,52 @@
1
+ ## 6.0.0 / 2022-10-XX
2
+
3
+ * Breaking Changes
4
+ * Dropping Ruby 2.2 and 2.3 support (now 2.4+) ([#2919])
5
+ * Remote_addr functionality has changed ([#2652], [#2653])
6
+ * No longer supporting Java 1.7 or below (JRuby 9.1 was the last release to support this) ([#2849])
7
+ * Remove nakayoshi GC ([#2933], [#2925])
8
+ * wait_for_less_busy_worker is now default on ([#2940])
9
+ * Prefix all environment variables with `PUMA_` ([#2924], [#2853])
10
+ * Removed some constants ([#2957], [#2958], [#2959], [#2960])
11
+ * The following classes are now part of Puma's private API: `Client`, `Cluster::Worker`, `Cluster::Worker`, `HandleRequest`. ([#2988])
12
+
13
+ * Features
14
+ * Increase throughput on large (100kb+) response bodies by 3-10x ([#2896], [#2892])
15
+ * Increase throughput on file responses ([#2923])
16
+ * Add support for streaming bodies in Rack. ([#2740])
17
+ * Allow OpenSSL session reuse via a 'reuse' ssl_bind method or bind string query parameter ([#2845])
18
+ * Allow `run_hooks` to pass a hash to blocks for use later ([#2917], [#2915])
19
+ * Allow using `preload_app!` with `fork_worker` ([#2907])
20
+ * Support request_body_wait metric with higher precision ([#2953])
21
+ * Allow header values to be arrays (Rack 3) ([#2936], [#2931])
22
+ * Export Puma/Ruby versions in /stats ([#2875])
23
+ * Allow configuring request uri max length & request path max length ([#2840])
24
+ * Add a couple of public accessors ([#2774])
25
+ * Log entire backtrace when worker start fails ([#2891])
26
+ * [jruby] Enable TLSv1.3 support ([#2886])
27
+ * [jruby] support setting TLS protocols + rename ssl_cipher_list ([#2899])
28
+ * [jruby] Support a truststore option ([#2849], [#2904], [#2884])
29
+
30
+ * Bugfixes
31
+ * Load the configuration before passing it to the binder ([#2897])
32
+ * Do not raise error raised on HTTP methods we don't recognize or support, like CONNECT ([#2932], [#1441])
33
+ * Fixed a memory leak when creating a new SSL listener ([#2956])
34
+
35
+ * Refactor
36
+ * log_writer.rb - add internal_write method ([#2888])
37
+ * [WIP] Refactor: Split out LogWriter from Events (no logic change) ([#2798])
38
+ * Extract prune_bundler code into it's own class. ([#2797])
39
+ * Refactor Launcher#run to increase readability (no logic change) ([#2795])
40
+ * Ruby 3.2 will have native IO#wait_* methods, don't require io/wait ([#2903])
41
+ * Various internal API refactorings ([#2942], [#2921], [#2922], [#2955])
42
+
1
43
  ## 5.6.5 / 2022-08-23
2
44
 
45
+ * Feature
46
+ * Puma::ControlCLI - allow refork command to be sent as a request ([#2868], [#2866])
47
+
3
48
  * Bugfixes
4
49
  * NullIO#closed should return false ([#2883])
5
- * Puma::ControlCLI - allow refork command to be sent as a request ([#2868], [#2866])
6
50
  * [jruby] Fix TLS verification hang ([#2890], [#2729])
7
51
  * extconf.rb - don't use pkg_config('openssl') if '--with-openssl-dir' is used ([#2885], [#2839])
8
52
  * MiniSSL - detect SSL_CTX_set_dh_auto ([#2864], [#2863])
@@ -318,6 +362,16 @@
318
362
  * Support parallel tests in verbose progress reporting ([#2223])
319
363
  * Refactor error handling in server accept loop ([#2239])
320
364
 
365
+ ## 4.3.12 / 2022-03-30
366
+
367
+ * Security
368
+ * Close several HTTP Request Smuggling exploits (CVE-2022-24790)
369
+
370
+ ## 4.3.11 / 2022-02-11
371
+
372
+ * Security
373
+ * Always close the response body (GHSA-rmj8-8hhh-gv5h)
374
+
321
375
  ## 4.3.10 / 2021-10-12
322
376
 
323
377
  * Bugfixes
@@ -1861,15 +1915,59 @@ be added back in a future date when a java Puma::MiniSSL is added.
1861
1915
  * Bugfixes
1862
1916
  * Your bugfix goes here <Most recent on the top, like GitHub> (#Github Number)
1863
1917
 
1864
- [#2883]:https://github.com/puma/puma/pull/2883 "PR by @MSP-Greg, merged 2022-06-02"
1918
+ [#2919]:https://github.com/puma/puma/pull/2919 "PR by @MSP-Greg, merged 2022-08-30"
1919
+ [#2652]:https://github.com/puma/puma/issues/2652 "Issue by @Roguelazer, closed 2022-09-04"
1920
+ [#2653]:https://github.com/puma/puma/pull/2653 "PR by @Roguelazer, closed 2022-03-07"
1921
+ [#2849]:https://github.com/puma/puma/pull/2849 "PR by @kares, merged 2022-04-09"
1922
+ [#2933]:https://github.com/puma/puma/pull/2933 "PR by @cafedomancer, merged 2022-09-09"
1923
+ [#2925]:https://github.com/puma/puma/issues/2925 "Issue by @nateberkopec, closed 2022-09-09"
1924
+ [#2940]:https://github.com/puma/puma/pull/2940 "PR by @cafedomancer, merged 2022-09-10"
1925
+ [#2924]:https://github.com/puma/puma/pull/2924 "PR by @cafedomancer, merged 2022-09-07"
1926
+ [#2853]:https://github.com/puma/puma/issues/2853 "Issue by @nateberkopec, closed 2022-09-07"
1927
+ [#2957]:https://github.com/puma/puma/pull/2957 "PR by @JuanitoFatas, merged 2022-09-16"
1928
+ [#2958]:https://github.com/puma/puma/pull/2958 "PR by @JuanitoFatas, merged 2022-09-16"
1929
+ [#2959]:https://github.com/puma/puma/pull/2959 "PR by @JuanitoFatas, merged 2022-09-16"
1930
+ [#2960]:https://github.com/puma/puma/pull/2960 "PR by @JuanitoFatas, merged 2022-09-16"
1931
+ [#2988]:https://github.com/puma/puma/issues/2988 "Issue by @MSP-Greg, merged 2022-10-12"
1932
+ [#2896]:https://github.com/puma/puma/pull/2896 "PR by @MSP-Greg, merged 2022-09-13"
1933
+ [#2892]:https://github.com/puma/puma/pull/2892 "PR by @guilleiguaran, closed 2022-09-13"
1934
+ [#2923]:https://github.com/puma/puma/pull/2923 "PR by @nateberkopec, merged 2022-09-09"
1935
+ [#2740]:https://github.com/puma/puma/pull/2740 "PR by @ioquatix, merged 2022-01-29"
1936
+ [#2845]:https://github.com/puma/puma/issues/2845 "Issue by @donv, closed 2022-03-22"
1937
+ [#2917]:https://github.com/puma/puma/pull/2917 "PR by @MSP-Greg, merged 2022-09-19"
1938
+ [#2915]:https://github.com/puma/puma/issues/2915 "Issue by @mperham, closed 2022-09-19"
1939
+ [#2907]:https://github.com/puma/puma/pull/2907 "PR by @casperisfine, merged 2022-09-15"
1940
+ [#2953]:https://github.com/puma/puma/pull/2953 "PR by @JuanitoFatas, merged 2022-09-14"
1941
+ [#2936]:https://github.com/puma/puma/pull/2936 "PR by @MSP-Greg, merged 2022-09-09"
1942
+ [#2931]:https://github.com/puma/puma/issues/2931 "Issue by @dentarg, closed 2022-09-09"
1943
+ [#2875]:https://github.com/puma/puma/pull/2875 "PR by @ylecuyer, merged 2022-05-19"
1944
+ [#2840]:https://github.com/puma/puma/pull/2840 "PR by @LukaszMaslej, merged 2022-04-13"
1945
+ [#2774]:https://github.com/puma/puma/pull/2774 "PR by @ob-stripe, merged 2022-01-31"
1946
+ [#2891]:https://github.com/puma/puma/pull/2891 "PR by @gingerlime, merged 2022-06-02"
1947
+ [#2886]:https://github.com/puma/puma/pull/2886 "PR by @kares, merged 2022-05-30"
1948
+ [#2899]:https://github.com/puma/puma/pull/2899 "PR by @kares, merged 2022-07-04"
1949
+ [#2904]:https://github.com/puma/puma/pull/2904 "PR by @kares, merged 2022-08-27"
1950
+ [#2884]:https://github.com/puma/puma/pull/2884 "PR by @kares, merged 2022-05-30"
1951
+ [#2897]:https://github.com/puma/puma/pull/2897 "PR by @Edouard-chin, merged 2022-08-27"
1952
+ [#2932]:https://github.com/puma/puma/pull/2932 "PR by @mrzasa, merged 2022-09-12"
1953
+ [#1441]:https://github.com/puma/puma/issues/1441 "Issue by @nirvdrum, closed 2022-09-12"
1954
+ [#2956]:https://github.com/puma/puma/pull/2956 "PR by @MSP-Greg, merged 2022-09-15"
1955
+ [#2888]:https://github.com/puma/puma/pull/2888 "PR by @MSP-Greg, merged 2022-06-01"
1956
+ [#2798]:https://github.com/puma/puma/pull/2798 "PR by @johnnyshields, merged 2022-02-05"
1957
+ [#2797]:https://github.com/puma/puma/pull/2797 "PR by @johnnyshields, merged 2022-02-01"
1958
+ [#2795]:https://github.com/puma/puma/pull/2795 "PR by @johnnyshields, merged 2022-01-31"
1959
+ [#2903]:https://github.com/puma/puma/pull/2903 "PR by @MSP-Greg, merged 2022-08-27"
1960
+ [#2942]:https://github.com/puma/puma/pull/2942 "PR by @nateberkopec, merged 2022-09-15"
1961
+ [#2921]:https://github.com/puma/puma/issues/2921 "Issue by @MSP-Greg, closed 2022-09-15"
1962
+ [#2922]:https://github.com/puma/puma/issues/2922 "Issue by @MSP-Greg, closed 2022-09-10"
1963
+ [#2955]:https://github.com/puma/puma/pull/2955 "PR by @cafedomancer, merged 2022-09-15"
1865
1964
  [#2868]:https://github.com/puma/puma/pull/2868 "PR by @MSP-Greg, merged 2022-06-02"
1866
1965
  [#2866]:https://github.com/puma/puma/issues/2866 "Issue by @slondr, closed 2022-06-02"
1867
- [#2888]:https://github.com/puma/puma/pull/2888 "PR by @MSP-Greg, merged 2022-06-01"
1966
+ [#2883]:https://github.com/puma/puma/pull/2883 "PR by @MSP-Greg, merged 2022-06-02"
1868
1967
  [#2890]:https://github.com/puma/puma/pull/2890 "PR by @kares, merged 2022-06-01"
1869
1968
  [#2729]:https://github.com/puma/puma/issues/2729 "Issue by @kares, closed 2022-06-01"
1870
1969
  [#2885]:https://github.com/puma/puma/pull/2885 "PR by @MSP-Greg, merged 2022-05-30"
1871
1970
  [#2839]:https://github.com/puma/puma/issues/2839 "Issue by @wlipa, closed 2022-05-30"
1872
- [#2882]:https://github.com/puma/puma/pull/2882 "PR by @MSP-Greg, merged 2022-05-19"
1873
1971
  [#2864]:https://github.com/puma/puma/pull/2864 "PR by @MSP-Greg, merged 2022-04-26"
1874
1972
  [#2863]:https://github.com/puma/puma/issues/2863 "Issue by @eradman, closed 2022-04-26"
1875
1973
  [#2861]:https://github.com/puma/puma/pull/2861 "PR by @BlakeWilliams, merged 2022-04-17"
@@ -1880,13 +1978,6 @@ be added back in a future date when a java Puma::MiniSSL is added.
1880
1978
  [#2838]:https://github.com/puma/puma/pull/2838 "PR by @epsilon-0, merged 2022-03-03"
1881
1979
  [#2817]:https://github.com/puma/puma/pull/2817 "PR by @khustochka, merged 2022-02-20"
1882
1980
  [#2810]:https://github.com/puma/puma/pull/2810 "PR by @kzkn, merged 2022-01-27"
1883
- [#2899]:https://github.com/puma/puma/pull/2899 "PR by @kares, merged 2022-07-04"
1884
- [#2891]:https://github.com/puma/puma/pull/2891 "PR by @gingerlime, merged 2022-06-02"
1885
- [#2886]:https://github.com/puma/puma/pull/2886 "PR by @kares, merged 2022-05-30"
1886
- [#2884]:https://github.com/puma/puma/pull/2884 "PR by @kares, merged 2022-05-30"
1887
- [#2875]:https://github.com/puma/puma/pull/2875 "PR by @ylecuyer, merged 2022-05-19"
1888
- [#2840]:https://github.com/puma/puma/pull/2840 "PR by @LukaszMaslej, merged 2022-04-13"
1889
- [#2849]:https://github.com/puma/puma/pull/2849 "PR by @kares, merged 2022-04-09"
1890
1981
  [#2809]:https://github.com/puma/puma/pull/2809 "PR by @dentarg, merged 2022-01-26"
1891
1982
  [#2764]:https://github.com/puma/puma/pull/2764 "PR by @dentarg, merged 2022-01-18"
1892
1983
  [#2708]:https://github.com/puma/puma/issues/2708 "Issue by @erikaxel, closed 2022-01-18"
data/README.md CHANGED
@@ -4,10 +4,8 @@
4
4
 
5
5
  # Puma: A Ruby Web Server Built For Parallelism
6
6
 
7
- [![Actions MRI](https://github.com/puma/puma/workflows/MRI/badge.svg?branch=master)](https://github.com/puma/puma/actions?query=workflow%3AMRI)
8
- [![Actions non MRI](https://github.com/puma/puma/workflows/non_MRI/badge.svg?branch=master)](https://github.com/puma/puma/actions?query=workflow%3Anon_MRI)
7
+ [![Actions](https://github.com/puma/puma/workflows/Tests/badge.svg?branch=master)](https://github.com/puma/puma/actions?query=workflow%3ATests)
9
8
  [![Code Climate](https://codeclimate.com/github/puma/puma.svg)](https://codeclimate.com/github/puma/puma)
10
- [![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
9
  [![StackOverflow](https://img.shields.io/badge/stackoverflow-Puma-blue.svg)]( https://stackoverflow.com/questions/tagged/puma )
12
10
 
13
11
  Puma is a **simple, fast, multi-threaded, and highly parallel HTTP 1.1 server for Ruby/Rack applications**.
@@ -108,15 +106,23 @@ Puma also offers "clustered mode". Clustered mode `fork`s workers from a master
108
106
  $ puma -t 8:32 -w 3
109
107
  ```
110
108
 
109
+ Or with the `WEB_CONCURRENCY` environment variable:
110
+
111
+ ```
112
+ $ WEB_CONCURRENCY=3 puma -t 8:32
113
+ ```
114
+
111
115
  Note that threads are still used in clustered mode, and the `-t` thread flag setting is per worker, so `-w 2 -t 16:16` will spawn 32 threads in total, with 16 in each worker process.
112
116
 
113
- In clustered mode, Puma can "preload" your application. This loads all the application code *prior* to forking. Preloading reduces total memory usage of your application via an operating system feature called [copy-on-write](https://en.wikipedia.org/wiki/Copy-on-write) (Ruby 2.0+ only). Use the `--preload` flag from the command line:
117
+ In clustered mode, Puma can "preload" your application. This loads all the application code *prior* to forking. Preloading reduces total memory usage of your application via an operating system feature called [copy-on-write](https://en.wikipedia.org/wiki/Copy-on-write).
118
+
119
+ If the `WEB_CONCURRENCY` environment variable is set to a value > 1 (and `--prune-bundler` has not been specified), preloading will be enabled by default. Otherwise, you can use the `--preload` flag from the command line:
114
120
 
115
121
  ```
116
122
  $ puma -w 3 --preload
117
123
  ```
118
124
 
119
- If you're using a configuration file, use the `preload_app!` method:
125
+ Or, if you're using a configuration file, you can use the `preload_app!` method:
120
126
 
121
127
  ```ruby
122
128
  # config/puma.rb
@@ -124,7 +130,9 @@ workers 3
124
130
  preload_app!
125
131
  ```
126
132
 
127
- Additionally, you can specify a block in your configuration file that will be run on boot of each worker:
133
+ Preloading can’t be used with phased restart, since phased restart kills and restarts workers one-by-one, and preloading copies the code of master into the workers.
134
+
135
+ When using clustered mode, you can specify a block in your configuration file that will be run on boot of each worker:
128
136
 
129
137
  ```ruby
130
138
  # config/puma.rb
@@ -137,12 +145,10 @@ This code can be used to setup the process before booting the application, allow
137
145
  you to do some Puma-specific things that you don't want to embed in your application.
138
146
  For instance, you could fire a log notification that a worker booted or send something to statsd. This can be called multiple times.
139
147
 
140
- Constants loaded by your application (such as `Rails`) will not be available in `on_worker_boot`.
141
- However, these constants _will_ be available if `preload_app!` is enabled, either explicitly in your `puma` config or automatically if
142
- using 2 or more workers in cluster mode.
143
- If `preload_app!` is not enabled and 1 worker is used, then `on_worker_boot` will fire, but your app will not be preloaded and constants will not be available.
148
+ Constants loaded by your application (such as `Rails`) will not be available in `on_worker_boot`
149
+ unless preloading is enabled.
144
150
 
145
- `before_fork` specifies a block to be run before workers are forked:
151
+ You can also specify a block to be run before workers are forked, using `before_fork`:
146
152
 
147
153
  ```ruby
148
154
  # config/puma.rb
@@ -151,8 +157,6 @@ before_fork do
151
157
  end
152
158
  ```
153
159
 
154
- Preloading can’t be used with phased restart, since phased restart kills and restarts workers one-by-one, and `preload_app!` copies the code of master into the workers.
155
-
156
160
  ### Error handling
157
161
 
158
162
  If puma encounters an error outside of the context of your application, it will respond with a 500 and a simple
@@ -192,15 +196,15 @@ Need a bit of security? Use SSL sockets:
192
196
  ```
193
197
  $ puma -b 'ssl://127.0.0.1:9292?key=path_to_key&cert=path_to_cert'
194
198
  ```
195
- #### Self-signed SSL certificates (via the [`localhost`] gem, for development use):
199
+ #### Self-signed SSL certificates (via the [`localhost`] gem, for development use):
196
200
 
197
- Puma supports the [`localhost`] gem for self-signed certificates. This is particularly useful if you want to use Puma with SSL locally, and self-signed certificates will work for your use-case. Currently, the integration can only be used in MRI.
201
+ Puma supports the [`localhost`] gem for self-signed certificates. This is particularly useful if you want to use Puma with SSL locally, and self-signed certificates will work for your use-case. Currently, the integration can only be used in MRI.
198
202
 
199
203
  Puma automatically configures SSL when the [`localhost`] gem is loaded in a `development` environment:
200
204
 
201
205
  ```ruby
202
206
  # Add the gem to your Gemfile
203
- group(:development) do
207
+ group(:development) do
204
208
  gem 'localhost'
205
209
  end
206
210
 
@@ -350,7 +354,7 @@ reliability in production environments:
350
354
  * [rc.d](docs/jungle/rc.d/README.md)
351
355
  * [systemd](docs/systemd.md)
352
356
 
353
- Community guides:
357
+ Community guides:
354
358
 
355
359
  * [Deploying Puma on OpenBSD using relayd and httpd](https://gist.github.com/anon987654321/4532cf8d6c59c1f43ec8973faa031103)
356
360
 
data/bin/puma-wild CHANGED
@@ -16,7 +16,7 @@ end
16
16
 
17
17
  module Puma; end
18
18
 
19
- Puma.const_set("WILD_ARGS", ["-I", inc])
19
+ Puma.const_set(:WILD_ARGS, ["-I", inc])
20
20
 
21
21
  require 'puma/cli'
22
22
 
@@ -19,3 +19,37 @@ For Bundler, use its configuration system:
19
19
  ```
20
20
  bundle config build.puma "--with-cflags='-D PUMA_QUERY_STRING_MAX_LENGTH=64000'"
21
21
  ```
22
+
23
+ ## Request Path, `PUMA_REQUEST_PATH_MAX_LENGTH`
24
+
25
+ By default, the max length of `REQUEST_PATH` is `8192`. But you may want to
26
+ adjust it to accept longer paths in requests.
27
+
28
+ For manual install, pass the `PUMA_REQUEST_PATH_MAX_LENGTH` option like this:
29
+
30
+ ```
31
+ gem install puma -- --with-cflags="-D PUMA_REQUEST_PATH_MAX_LENGTH=64000"
32
+ ```
33
+
34
+ For Bundler, use its configuration system:
35
+
36
+ ```
37
+ bundle config build.puma "--with-cflags='-D PUMA_REQUEST_PATH_MAX_LENGTH=64000'"
38
+ ```
39
+
40
+ ## Request URI, `PUMA_REQUEST_URI_MAX_LENGTH`
41
+
42
+ By default, the max length of `REQUEST_URI` is `1024 * 12`. But you may want to
43
+ adjust it to accept longer URIs in requests.
44
+
45
+ For manual install, pass the `PUMA_REQUEST_URI_MAX_LENGTH` option like this:
46
+
47
+ ```
48
+ gem install puma -- --with-cflags="-D PUMA_REQUEST_URI_MAX_LENGTH=64000"
49
+ ```
50
+
51
+ For Bundler, use its configuration system:
52
+
53
+ ```
54
+ bundle config build.puma "--with-cflags='-D PUMA_REQUEST_URI_MAX_LENGTH=64000'"
55
+ ```
data/docs/fork_worker.md CHANGED
@@ -10,7 +10,7 @@ Puma 5 introduces an experimental new cluster-mode configuration option, `fork_w
10
10
  10004 \_ puma: cluster worker 3: 10000 [puma]
11
11
  ```
12
12
 
13
- Similar to the `preload_app!` option, the `fork_worker` option allows your application to be initialized only once for copy-on-write memory savings, and it has two additional advantages:
13
+ The `fork_worker` option allows your application to be initialized only once for copy-on-write memory savings, and it has two additional advantages:
14
14
 
15
15
  1. **Compatible with phased restart.** Because the master process itself doesn't preload the application, this mode works with phased restart (`SIGUSR1` or `pumactl phased-restart`). When worker 0 reloads as part of a phased restart, it initializes a new copy of your application first, then the other workers reload by forking from this new worker already containing the new preloaded application.
16
16
 
@@ -24,8 +24,6 @@ Similar to the `preload_app!` option, the `fork_worker` option allows your appli
24
24
 
25
25
  ### Limitations
26
26
 
27
- - Not compatible with the `preload_app!` option
28
-
29
27
  - This mode is still very experimental so there may be bugs or edge-cases, particularly around expected behavior of existing hooks. Please open a [bug report](https://github.com/puma/puma/issues/new?template=bug_report.md) if you encounter any issues.
30
28
 
31
29
  - In order to fork new workers cleanly, worker 0 shuts down its server and stops serving requests so there are no open file descriptors or other kinds of shared global state between processes, and to maximize copy-on-write efficiency across the newly-forked workers. This may temporarily reduce total capacity of the cluster during a phased restart / refork.
@@ -0,0 +1,150 @@
1
+ # Testing - benchmark/local files
2
+
3
+ These files generate data that shows request-per-second (RPS), etc. Typically, files are in
4
+ pairs, a shell script and a Ruby script. The shell script starts the server, then runs the
5
+ Ruby file, which starts client request stream(s), then collects and logs metrics.
6
+
7
+ ## response_time_wrk.sh
8
+
9
+ This uses [wrk] for generating data. One or more wrk runs are performed. Summarizes RPS and
10
+ wrk latency times. The default for the `-b` argument runs 28 different client request streams,
11
+ and takes a bit over 5 minutes. See 'Request Stream Configuration' below for `-b` argument
12
+ description.
13
+
14
+ <details>
15
+ <summary>Summary output for<br/><code>benchmarks/local/response_time_wrk.sh -w2 -t5:5 -s tcp6</code>:</summary>
16
+
17
+ ```
18
+ Type req/sec 50% 75% 90% 99% 100% Resp Size
19
+ ───────────────────────────────────────────────────────────────── 1kB
20
+ array 13710 0.74 2.52 5.23 7.76 37.45 1024
21
+ chunk 13502 0.76 2.55 5.28 7.84 11.23 1042
22
+ string 13794 0.74 2.51 5.20 7.75 14.07 1024
23
+ io 9615 1.16 3.45 7.13 10.57 15.75 1024
24
+ ───────────────────────────────────────────────────────────────── 10kB
25
+ array 13458 0.76 2.57 5.31 7.93 13.94 10239
26
+ chunk 13066 0.78 2.64 5.46 8.18 38.48 10320
27
+ string 13500 0.76 2.55 5.29 7.88 11.42 10240
28
+ io 9293 1.18 3.59 7.39 10.94 16.99 10240
29
+ ───────────────────────────────────────────────────────────────── 100kB
30
+ array 11315 0.96 3.06 6.33 9.49 17.69 102424
31
+ chunk 9916 1.10 3.48 7.20 10.73 15.14 103075
32
+ string 10948 1.00 3.17 6.57 9.83 17.88 102378
33
+ io 8901 1.21 3.72 7.48 11.27 59.98 102407
34
+ ───────────────────────────────────────────────────────────────── 256kB
35
+ array 9217 1.15 3.82 7.88 11.74 17.12 262212
36
+ chunk 7339 1.45 4.76 9.81 14.63 22.70 264007
37
+ string 8574 1.19 3.81 7.73 11.21 15.80 262147
38
+ io 8911 1.19 3.80 7.55 15.25 60.01 262183
39
+ ───────────────────────────────────────────────────────────────── 512kB
40
+ array 6951 1.49 5.03 10.28 15.90 25.08 524378
41
+ chunk 5234 2.03 6.56 13.57 20.46 32.15 527862
42
+ string 6438 1.55 5.04 10.12 16.28 72.87 524275
43
+ io 8533 1.15 4.62 8.79 48.15 70.51 524327
44
+ ───────────────────────────────────────────────────────────────── 1024kB
45
+ array 4122 1.80 15.59 41.87 67.79 121.00 1048565
46
+ chunk 3158 2.82 15.22 31.00 71.39 99.90 1055654
47
+ string 4710 2.24 6.66 13.65 20.38 70.44 1048575
48
+ io 8355 1.23 3.95 7.94 14.08 68.54 1048498
49
+ ───────────────────────────────────────────────────────────────── 2048kB
50
+ array 2454 4.12 14.02 27.70 43.48 88.89 2097415
51
+ chunk 1743 6.26 17.65 36.98 55.78 92.10 2111358
52
+ string 2479 4.38 12.52 25.65 38.44 95.62 2097502
53
+ io 8264 1.25 3.83 7.76 11.73 65.69 2097090
54
+
55
+ Body ────────── req/sec ────────── ─────── req 50% times ───────
56
+ KB array chunk string io array chunk string io
57
+ 1 13710 13502 13794 9615 0.745 0.757 0.741 1.160
58
+ 10 13458 13066 13500 9293 0.760 0.784 0.759 1.180
59
+ 100 11315 9916 10948 8901 0.960 1.100 1.000 1.210
60
+ 256 9217 7339 8574 8911 1.150 1.450 1.190 1.190
61
+ 512 6951 5234 6438 8533 1.490 2.030 1.550 1.150
62
+ 1024 4122 3158 4710 8355 1.800 2.820 2.240 1.230
63
+ 2048 2454 1743 2479 8264 4.120 6.260 4.380 1.250
64
+ ─────────────────────────────────────────────────────────────────────
65
+ wrk -t8 -c16 -d10s
66
+ benchmarks/local/response_time_wrk.sh -w2 -t5:5 -s tcp6 -Y
67
+ Server cluster mode -w2 -t5:5, bind: tcp6
68
+ Puma repo branch 00-response-refactor
69
+ ruby 3.2.0dev (2022-06-14T01:21:55Z master 048f14221c) +YJIT [x86_64-linux]
70
+
71
+ [2136] - Gracefully shutting down workers...
72
+ [2136] === puma shutdown: 2022-06-13 21:16:13 -0500 ===
73
+ [2136] - Goodbye!
74
+
75
+ 5:15 Total Time
76
+ ```
77
+ </details><br/>
78
+
79
+ ## bench_base.sh, bench_base.rb
80
+
81
+ These two files setup parameters for the Puma server, which is normally started in a shell
82
+ script. It then starts a Ruby file (a subclass of BenchBase), passing arguments to it. The
83
+ Ruby file is normally used to generate a client request stream(s).
84
+
85
+ ### Puma Configuration
86
+
87
+ The following arguments are used for the Puma server:
88
+
89
+ * **`-C`** - configuration file
90
+ * **`-d`** - app delay
91
+ * **`-r`** - rackup file, often defaults to test/rackup/ci_select.ru
92
+ * **`-s`** - bind socket type, default is tcp/tcp4, also tcp6, ssl/ssl4, ssl6, unix, or aunix
93
+ (unix & abstract unix are not available with wrk).
94
+ * **`-t`** - threads, expressed as '5:5', same as Puma --thread
95
+ * **`-w`** - workers, same as Puma --worker
96
+ * **`-Y`** - enable Ruby YJIT
97
+
98
+ ### Request Stream Configuration
99
+
100
+ The following arguments are used for request streams:
101
+
102
+ * **`-b`** - response body configuration. Body type options are a array, c chunked, s string,
103
+ and i for File/IO. None or any combination can be specified, they should start the option.
104
+ Then, any combination of comma separated integers can be used for the response body size
105
+ in kB. The string 'ac50,100' would create four runs, 50kb array, 50kB chunked, 100kB array,
106
+ and 100kB chunked. See 'Testing - test/rackup/ci-*.ru files' for more info.
107
+ * **`-c`** - connections per client request stream thread, defaults to 2 for wrk.
108
+ * **`-D`** - duration of client request stream in seconds.
109
+ * **`-T`** - number of threads in the client request stream. For wrk, this defaults to
110
+ 80% of Puma workers * max_threads.
111
+
112
+ ### Notes - Configuration
113
+
114
+ The above lists script arguments.
115
+
116
+ `bench_base.sh` contains most server defaults. Many can be set via ENV variables.
117
+
118
+ `bench_base.rb` contains the client request stream defaults. The default value for
119
+ `-b` is `acsi1,10,100,256,512,1024,2048`, which is a 4 x 7 matrix, and hence, runs
120
+ 28 jobs. Also, the i body type (File/IO) generates files, they are placed in the
121
+ `"#{Dir.tmpdir}/.puma_response_body_io"` directory, which is created.
122
+
123
+ ### Notes - wrk
124
+
125
+ The shell scripts use `-T` for wrk's thread count, since `-t` is used for Puma
126
+ server threads. Regarding the `-c` argument, wrk has an interesting behavior.
127
+ The total number of connections is set by `(connections/threads).to_i`. The scripts
128
+ here use `-c` as connections per thread. Hence, using `-T4 -c2` will yield a total
129
+ of eight wrk connections, two per thread. The equivalent wrk arguments would be `-t4 -c8`.
130
+
131
+ Puma can only process so many requests, and requests will queue in the backlog
132
+ until Puma can respond to them. With wrk, if the number of total connections is
133
+ too high, one will see the upper latency times increase, pushing into the lower
134
+ latency times as the connections are increased. The default values for wrk's
135
+ threads and connections were chosen to minimize requests' time in the backlog.
136
+
137
+ An example with four wrk runs using `-b s10`. Notice that `req/sec` varies by
138
+ less than 1%, but the `75%` times increase by an order of magnitude:
139
+ ```
140
+ req/sec 50% 75% 90% 99% 100% Resp Size wrk cmd line
141
+ ─────────────────────────────────────────────────────────────────────────────
142
+ 13597 0.755 2.550 5.260 7.800 13.310 12040 wrk -t8 -c16 -d10
143
+ 13549 0.793 4.430 8.140 11.220 16.600 12002 wrk -t10 -c20 -d10
144
+ 13570 1.040 25.790 40.010 49.070 58.300 11982 wrk -t8 -c64 -d10
145
+ 13684 1.050 25.820 40.080 49.160 66.190 12033 wrk -t16 -c64 -d10
146
+ ```
147
+ Finally, wrk's output may cause rounding errors, so the response body size calculation is
148
+ imprecise.
149
+
150
+ [wrk]: <https://github.com/ioquatix/wrk>
@@ -0,0 +1,36 @@
1
+ # Testing - test/rackup/ci-*.ru files
2
+
3
+ ## Overview
4
+
5
+ Puma should efficiently handle a variety of response bodies, varying both by size
6
+ and by the type of object used for the body.
7
+
8
+ Five rackup files are located in 'test/rackup' that can be used. All have their
9
+ request body size (in kB) set via `Body-Conf` header or with `ENV['CI_BODY_CONF']`.
10
+ Additionally, the ci_select.ru file can have it's body type set via a starting
11
+ character.
12
+
13
+ * **ci_array.ru** - body is an `Array` of 1kB strings. `Content-Length` is not set.
14
+ * **ci_chunked.ru** - body is an `Enumerator` of 1kB strings. `Content-Length` is not set.
15
+ * **ci_io.ru** - body is a File/IO object. `Content-Length` is set.
16
+ * **ci_string.ru** - body is a single string. `Content-Length` is set.
17
+ * **ci_select.ru** - can be any of the above.
18
+
19
+ All responses have 25 headers, total length approx 1kB. ci_array.ru and ci_chunked.ru
20
+ contain 1kB items.
21
+
22
+ All can be delayed by a float value (seconds) specified by the `Dly` header
23
+
24
+ Note that rhe `Body-Conf` header takes precedence, and `ENV['CI_BODY_CONF']` is
25
+ only read on load.
26
+
27
+ ## ci_select.ru
28
+
29
+ The ci_select.ru file allows a starting character to specify the body type in the
30
+ `Body-Conf` header or with `ENV['CI_BODY_CONF']`.
31
+ * **a** - array of strings
32
+ * **c** - chunked (enum)
33
+ * **s** - single string
34
+ * **i** - File/IO
35
+
36
+ A value of `a100` would return a body as an array of 100 1kB strings.
@@ -2,20 +2,22 @@ require 'mkmf'
2
2
 
3
3
  dir_config("puma_http11")
4
4
 
5
- if $mingw && RUBY_VERSION >= '2.4'
5
+ if $mingw
6
6
  append_cflags '-fstack-protector-strong -D_FORTIFY_SOURCE=2'
7
7
  append_ldflags '-fstack-protector-strong -l:libssp.a'
8
8
  have_library 'ssp'
9
9
  end
10
10
 
11
- unless ENV["DISABLE_SSL"]
11
+ unless ENV["PUMA_DISABLE_SSL"]
12
12
  # don't use pkg_config('openssl') if '--with-openssl-dir' is used
13
13
  has_openssl_dir = dir_config('openssl').any?
14
14
  found_pkg_config = !has_openssl_dir && pkg_config('openssl')
15
15
 
16
- found_ssl = if (!$mingw || RUBY_VERSION >= '2.4') && found_pkg_config
16
+ found_ssl = if !$mingw && found_pkg_config
17
17
  puts 'using OpenSSL pkgconfig (openssl.pc)'
18
18
  true
19
+ elsif have_library('libcrypto', 'BIO_read') && have_library('libssl', 'SSL_CTX_new')
20
+ true
19
21
  elsif %w'crypto libeay32'.find {|crypto| have_library(crypto, 'BIO_read')} &&
20
22
  %w'ssl ssleay32'.find {|ssl| have_library(ssl, 'SSL_CTX_new')}
21
23
  true
@@ -28,13 +30,14 @@ unless ENV["DISABLE_SSL"]
28
30
  have_header "openssl/bio.h"
29
31
 
30
32
  # below is yes for 1.0.2 & later
31
- have_func "DTLS_method" , "openssl/ssl.h"
33
+ have_func "DTLS_method" , "openssl/ssl.h"
34
+ have_func "SSL_CTX_set_session_cache_mode(NULL, 0)", "openssl/ssl.h"
32
35
 
33
36
  # below are yes for 1.1.0 & later
34
- have_func "TLS_server_method" , "openssl/ssl.h"
35
- have_func "SSL_CTX_set_min_proto_version(NULL, 0)", "openssl/ssl.h"
37
+ have_func "TLS_server_method" , "openssl/ssl.h"
38
+ have_func "SSL_CTX_set_min_proto_version(NULL, 0)" , "openssl/ssl.h"
36
39
 
37
- have_func "X509_STORE_up_ref"
40
+ have_func "X509_STORE_up_ref"
38
41
  have_func "SSL_CTX_set_ecdh_auto(NULL, 0)" , "openssl/ssl.h"
39
42
 
40
43
  # below exists in 1.1.0 and later, but isn't documented until 3.0.0
@@ -53,7 +56,7 @@ unless ENV["DISABLE_SSL"]
53
56
  end
54
57
  end
55
58
 
56
- if ENV["MAKE_WARNINGS_INTO_ERRORS"]
59
+ if ENV["PUMA_MAKE_WARNINGS_INTO_ERRORS"]
57
60
  # Make all warnings into errors
58
61
  # Except `implicit-fallthrough` since most failures comes from ragel state machine generated code
59
62
  if respond_to?(:append_cflags, true) # Ruby 2.5 and later
@@ -297,7 +297,7 @@ case 13:
297
297
  tr18:
298
298
  #line 65 "ext/puma_http11/http11_parser.rl"
299
299
  {
300
- parser->http_version(parser, PTR_TO(mark), LEN(mark, p));
300
+ parser->server_protocol(parser, PTR_TO(mark), LEN(mark, p));
301
301
  }
302
302
  goto st14;
303
303
  tr26:
@@ -46,7 +46,7 @@ typedef struct puma_parser {
46
46
  element_cb fragment;
47
47
  element_cb request_path;
48
48
  element_cb query_string;
49
- element_cb http_version;
49
+ element_cb server_protocol;
50
50
  element_cb header_done;
51
51
 
52
52
  char buf[BUFFER_LEN];
@@ -39,8 +39,8 @@ public class Http11Parser {
39
39
  Http11.query_string(runtime, parser.data, parser.buffer, parser.query_start, fpc-parser.query_start);
40
40
  }
41
41
 
42
- action http_version {
43
- Http11.http_version(runtime, parser.data, parser.buffer, parser.mark, fpc-parser.mark);
42
+ action server_protocol {
43
+ Http11.server_protocol(runtime, parser.data, parser.buffer, parser.mark, fpc-parser.mark);
44
44
  }
45
45
 
46
46
  action request_path {
@@ -62,8 +62,8 @@ static void snake_upcase_char(char *c)
62
62
  parser->query_string(parser, PTR_TO(query_start), LEN(query_start, fpc));
63
63
  }
64
64
 
65
- action http_version {
66
- parser->http_version(parser, PTR_TO(mark), LEN(mark, fpc));
65
+ action server_protocol {
66
+ parser->server_protocol(parser, PTR_TO(mark), LEN(mark, fpc));
67
67
  }
68
68
 
69
69
  action request_path {
@@ -38,8 +38,8 @@
38
38
  Method = ( upper | digit | safe ){1,20} >mark %request_method;
39
39
 
40
40
  http_number = ( digit+ "." digit+ ) ;
41
- HTTP_Version = ( "HTTP/" http_number ) >mark %http_version ;
42
- Request_Line = ( Method " " Request_URI ("#" Fragment){0,1} " " HTTP_Version CRLF ) ;
41
+ Server_Protocol = ( "HTTP/" http_number ) >mark %server_protocol ;
42
+ Request_Line = ( Method " " Request_URI ("#" Fragment){0,1} " " Server_Protocol CRLF ) ;
43
43
 
44
44
  field_name = ( token -- ":" )+ >start_field $snake_upcase_field %write_field;
45
45