puma 3.11.3 → 4.0.0
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 +61 -0
- data/README.md +41 -11
- data/docs/architecture.md +2 -1
- data/docs/deployment.md +24 -4
- data/docs/restart.md +5 -3
- data/docs/systemd.md +37 -9
- data/ext/puma_http11/PumaHttp11Service.java +2 -0
- data/ext/puma_http11/mini_ssl.c +42 -5
- data/ext/puma_http11/org/jruby/puma/IOBuffer.java +72 -0
- data/ext/puma_http11/org/jruby/puma/MiniSSL.java +17 -4
- data/lib/puma.rb +8 -0
- data/lib/puma/app/status.rb +3 -2
- data/lib/puma/binder.rb +22 -10
- data/lib/puma/cli.rb +18 -7
- data/lib/puma/client.rb +54 -22
- data/lib/puma/cluster.rb +54 -15
- data/lib/puma/commonlogger.rb +2 -0
- data/lib/puma/configuration.rb +4 -1
- data/lib/puma/const.rb +8 -2
- data/lib/puma/control_cli.rb +23 -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 +63 -11
- data/lib/puma/events.rb +2 -0
- data/lib/puma/io_buffer.rb +3 -6
- data/lib/puma/jruby_restart.rb +2 -0
- data/lib/puma/launcher.rb +15 -13
- data/lib/puma/minissl.rb +20 -4
- 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 +215 -30
- data/lib/puma/runner.rb +11 -2
- data/lib/puma/server.rb +63 -26
- data/lib/puma/single.rb +14 -3
- data/lib/puma/state_file.rb +2 -0
- data/lib/puma/tcp_logger.rb +2 -0
- data/lib/puma/thread_pool.rb +50 -5
- data/lib/puma/util.rb +2 -6
- 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 +7 -7
- 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 +23 -9
- data/lib/puma/compat.rb +0 -14
- data/lib/puma/java_io_buffer.rb +0 -45
- data/lib/puma/rack/backports/uri/common_193.rb +0 -33
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: b22a5ddb0ac910e28c3789564c70be998eaa0dec5eca7c668c6a4478ab35012b
|
4
|
+
data.tar.gz: b98d67fb71305279ee8169c80546e46d4b63a4be522462545023f8917d82fa72
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1f7186d10e0783ffd899b65b25fdda553346074b3bad7416726a99a0f77709318a275e67856beb101ff75c9b75dba48af917d48504bf6f5fc15b64dd7c8a190a
|
7
|
+
data.tar.gz: 1881c9c149c4e631c9bec14cd92344785933c81bf4fb997721c61081d4a3f6f9a5bf4cbf0f8faca44110deaa7331b6177a67d734af3006b1e0b677a7782fc5f9
|
data/History.md
CHANGED
@@ -1,3 +1,64 @@
|
|
1
|
+
## Master
|
2
|
+
|
3
|
+
x features
|
4
|
+
x bugfixes
|
5
|
+
|
6
|
+
## 4.0.0 / 2019-06-25
|
7
|
+
|
8
|
+
9 features
|
9
|
+
* Add support for disabling TLSv1.0 (#1562)
|
10
|
+
* Request body read time metric (#1569)
|
11
|
+
* Add out_of_band hook (#1648)
|
12
|
+
* Re-implement (native) IOBuffer for JRuby (#1691)
|
13
|
+
* Min worker timeout (#1716)
|
14
|
+
* Add option to suppress SignalException on SIGTERM (#1690)
|
15
|
+
* Allow mutual TLS CA to be set using `ssl_bind` DSL (#1689)
|
16
|
+
* Reactor now uses nio4r instead of `select` (#1728)
|
17
|
+
9 x bugfixes
|
18
|
+
* Do not accept new requests on shutdown (#1685, #1808)
|
19
|
+
* Fix 3 corner cases when request body is chunked (#1508)
|
20
|
+
* Change pid existence check's condition branches (#1650)
|
21
|
+
* Don't call .stop on a server that doesn't exist (#1655)
|
22
|
+
* Implemented NID_X9_62_prime256v1 (P-256) curve over P-521 (#1671)
|
23
|
+
* Fix @notify.close can't modify frozen IOError (RuntimeError) (#1583)
|
24
|
+
* Fix Java 8 support (#1773)
|
25
|
+
* Fix error `uninitialized constant Puma::Cluster` (#1731)
|
26
|
+
* Fix `not_token` being able to be set to true (#1803)
|
27
|
+
|
28
|
+
## 3.12.1 / 2019-03-19
|
29
|
+
|
30
|
+
* 1 features
|
31
|
+
* Internal strings are frozen (#1649)
|
32
|
+
* 3 bugfixes
|
33
|
+
* Fix chunked ending check (#1607)
|
34
|
+
* Rack handler should use provided default host (#1700)
|
35
|
+
* Better support for detecting runtimes that support `fork` (#1630)
|
36
|
+
|
37
|
+
## 3.12.0 / 2018-07-13
|
38
|
+
|
39
|
+
* 5 features:
|
40
|
+
* You can now specify which SSL ciphers the server should support, default is unchanged (#1478)
|
41
|
+
* The setting for Puma's `max_threads` is now in `Puma.stats` (#1604)
|
42
|
+
* Pool capacity is now in `Puma.stats` (#1579)
|
43
|
+
* Installs restricted to Ruby 2.2+ (#1506)
|
44
|
+
* `--control` is now deprecated in favor of `--control-url` (#1487)
|
45
|
+
|
46
|
+
* 2 bugfixes:
|
47
|
+
* 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)
|
48
|
+
* In a test env puma now emits the stack on an exception (#1557)
|
49
|
+
|
50
|
+
## 3.11.4 / 2018-04-12
|
51
|
+
|
52
|
+
* 2 features:
|
53
|
+
* Manage puma as a service using rc.d (#1529)
|
54
|
+
* Server stats are now available from a top level method (#1532)
|
55
|
+
* 5 bugfixes:
|
56
|
+
* Fix parsing CLI options (#1482)
|
57
|
+
* Order of stderr and stdout is made before redirecting to a log file (#1511)
|
58
|
+
* Init.d fix of `ps -p` to check if pid exists (#1545)
|
59
|
+
* Early hints bugfix (#1550)
|
60
|
+
* Purge interrupt queue when closing socket fails (#1553)
|
61
|
+
|
1
62
|
## 3.11.3 / 2018-03-05
|
2
63
|
|
3
64
|
* 3 bugfixes:
|
data/README.md
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
<p align="center">
|
2
|
-
<img src="
|
2
|
+
<img src="https://puma.io/images/logos/puma-logo-large.png">
|
3
3
|
</p>
|
4
4
|
|
5
5
|
# Puma: A Ruby Web Server Built For Concurrency
|
6
6
|
|
7
7
|
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/puma/puma?utm\_source=badge&utm\_medium=badge&utm\_campaign=pr-badge)
|
8
|
-
[![Build Status](https://secure.travis-ci.org/puma/puma.svg)](
|
9
|
-
[![
|
10
|
-
[![Dependency Status](https://gemnasium.com/puma/puma.svg)](https://gemnasium.com/puma/puma)
|
8
|
+
[![Travis Build Status](https://secure.travis-ci.org/puma/puma.svg)](https://travis-ci.org/puma/puma)
|
9
|
+
[![Appveyor Build Status](https://ci.appveyor.com/api/projects/status/0xnxc7a26u9b2bub/branch/master?svg=true)](https://ci.appveyor.com/project/puma/puma/branch/master)
|
11
10
|
[![Code Climate](https://codeclimate.com/github/puma/puma.svg)](https://codeclimate.com/github/puma/puma)
|
11
|
+
[![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)
|
12
12
|
|
13
13
|
Puma is a **simple, fast, threaded, and highly concurrent HTTP 1.1 server for Ruby/Rack applications** in development and production.
|
14
14
|
|
@@ -16,7 +16,7 @@ Puma is a **simple, fast, threaded, and highly concurrent HTTP 1.1 server for Ru
|
|
16
16
|
|
17
17
|
Under the hood, Puma processes requests using a C-optimized Ragel extension (inherited from Mongrel) that provides fast, accurate HTTP 1.1 protocol parsing in a portable way. Puma then serves the request in a thread from an internal thread pool. Since each request is served in a separate thread, truly concurrent Ruby implementations (JRuby, Rubinius) will use all available CPU cores.
|
18
18
|
|
19
|
-
Puma was designed to be the go-to server for [Rubinius](
|
19
|
+
Puma was designed to be the go-to server for [Rubinius](https://rubini.us), but also works well with JRuby and MRI.
|
20
20
|
|
21
21
|
On MRI, there is a Global VM Lock (GVL) that ensures only one thread can run Ruby code at a time. But if you're doing a lot of blocking IO (such as HTTP calls to external APIs like Twitter), Puma still improves MRI's throughput by allowing blocking IO to be run concurrently.
|
22
22
|
|
@@ -25,7 +25,7 @@ On MRI, there is a Global VM Lock (GVL) that ensures only one thread can run Rub
|
|
25
25
|
```
|
26
26
|
$ gem install puma
|
27
27
|
$ puma <any rackup (*.ru) file>
|
28
|
-
```
|
28
|
+
```
|
29
29
|
|
30
30
|
## Frameworks
|
31
31
|
|
@@ -157,17 +157,40 @@ $ 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
|
```
|
164
163
|
|
164
|
+
#### Controlling SSL Cipher Suites
|
165
|
+
|
166
|
+
Need to use or avoid specific SSL cipher suites? Use `ssl_cipher_filter` or `ssl_cipher_list` options.
|
167
|
+
|
168
|
+
##### Ruby:
|
169
|
+
|
170
|
+
```
|
171
|
+
$ puma -b 'ssl://127.0.0.1:9292?key=path_to_key&cert=path_to_cert&ssl_cipher_filter=!aNULL:AES+SHA'
|
172
|
+
```
|
173
|
+
|
174
|
+
##### JRuby:
|
175
|
+
|
176
|
+
```
|
177
|
+
$ 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'
|
178
|
+
```
|
179
|
+
|
180
|
+
See https://www.openssl.org/docs/man1.0.2/apps/ciphers.html for cipher filter format and full list of cipher suites.
|
181
|
+
|
182
|
+
Don't want to use insecure TLSv1.0 ?
|
183
|
+
|
184
|
+
```
|
185
|
+
$ puma -b 'ssl://127.0.0.1:9292?key=path_to_key&cert=path_to_cert&no_tlsv1=true'
|
186
|
+
```
|
187
|
+
|
165
188
|
### Control/Status Server
|
166
189
|
|
167
190
|
Puma has a built-in status/control app that can be used to query and control Puma itself.
|
168
191
|
|
169
192
|
```
|
170
|
-
$ puma --control tcp://127.0.0.1:9293 --control-token foo
|
193
|
+
$ puma --control-url tcp://127.0.0.1:9293 --control-token foo
|
171
194
|
```
|
172
195
|
|
173
196
|
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 +198,7 @@ Puma will start the control server on localhost port 9293. All requests to the c
|
|
175
198
|
You can also interact with the control server via `pumactl`. This command will restart Puma:
|
176
199
|
|
177
200
|
```
|
178
|
-
$ pumactl -
|
201
|
+
$ pumactl --control-url 'tcp://127.0.0.1:9293' --control-token foo restart
|
179
202
|
```
|
180
203
|
|
181
204
|
To see a list of `pumactl` options, use `pumactl --help`.
|
@@ -217,10 +240,10 @@ Some platforms do not support all Puma features.
|
|
217
240
|
|
218
241
|
## Known Bugs
|
219
242
|
|
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:
|
243
|
+
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
244
|
|
222
245
|
```ruby
|
223
|
-
if %w(2.2.7 2.2.8 2.3.4 2.4.1).include? RUBY_VERSION
|
246
|
+
if %w(2.2.7 2.2.8 2.2.9 2.2.10 2.3.4 2.4.1).include? RUBY_VERSION
|
224
247
|
begin
|
225
248
|
require 'stopgap_13632'
|
226
249
|
rescue LoadError
|
@@ -239,6 +262,13 @@ reliability in production environments:
|
|
239
262
|
* [tools/jungle](https://github.com/puma/puma/tree/master/tools/jungle) for sysvinit (init.d) and upstart
|
240
263
|
* [docs/systemd](https://github.com/puma/puma/blob/master/docs/systemd.md)
|
241
264
|
|
265
|
+
## Community Plugins
|
266
|
+
|
267
|
+
* [puma-heroku](https://github.com/evanphx/puma-heroku) — default Puma configuration for running on Heroku
|
268
|
+
* [puma-metrics](https://github.com/harmjanblok/puma-metrics) — export Puma metrics to Prometheus
|
269
|
+
* [puma-plugin-statsd](https://github.com/yob/puma-plugin-statsd) — send Puma metrics to statsd
|
270
|
+
* [puma-plugin-systemd](https://github.com/sj26/puma-plugin-systemd) — deeper integration with systemd for notify, status and watchdog
|
271
|
+
|
242
272
|
## Contributing
|
243
273
|
|
244
274
|
To run the test suite:
|
data/docs/architecture.md
CHANGED
@@ -20,6 +20,7 @@ Clustered mode is shown/discussed here. Single mode is analogous to having a sin
|
|
20
20
|
* By default, a single, separate thread is used to receive HTTP requests across the socket.
|
21
21
|
* When at least one worker thread is available for work, a connection is accepted and placed in this request buffer
|
22
22
|
* This thread waits for entire HTTP requests to be received over the connection
|
23
|
+
* The time spent waiting for the HTTP request body to be received is exposed to the Rack app as `env['puma.request_body_wait']` (milliseconds)
|
23
24
|
* Once received, the connection is pushed into the "todo" set
|
24
25
|
* Worker threads pop work off the "todo" set for processing
|
25
26
|
* The thread processes the request via the rack application (which generates the HTTP response)
|
@@ -33,4 +34,4 @@ Clustered mode is shown/discussed here. Single mode is analogous to having a sin
|
|
33
34
|
The `queue_requests` option is `true` by default, enabling the separate thread used to buffer requests as described above.
|
34
35
|
|
35
36
|
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
|
37
|
+
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/deployment.md
CHANGED
@@ -38,22 +38,42 @@ Here are some rules of thumb:
|
|
38
38
|
* As you grow more confident in the thread safety of your app, you can tune the
|
39
39
|
workers down and the threads up.
|
40
40
|
|
41
|
+
#### Ubuntu / Systemd (Systemctl) Installation
|
42
|
+
|
43
|
+
See [systemd.md](systemd.md)
|
44
|
+
|
41
45
|
#### Worker utilization
|
42
46
|
|
43
|
-
**How do you know if you'
|
47
|
+
**How do you know if you've got enough (or too many workers)?**
|
44
48
|
|
45
49
|
A good question. Due to MRI's GIL, only one thread can be executing Ruby code at a time.
|
46
50
|
But since so many apps are waiting on IO from DBs, etc., they can utilize threads
|
47
51
|
to make better use of the process.
|
48
52
|
|
49
53
|
The rule of thumb is you never want processes that are pegged all the time. This
|
50
|
-
means that there is more work to do
|
54
|
+
means that there is more work to do than the process can get through. On the other
|
51
55
|
hand, if you have processes that sit around doing nothing, then they're just eating
|
52
56
|
up resources.
|
53
57
|
|
54
|
-
|
58
|
+
Watch your CPU utilization over time and aim for about 70% on average. This means
|
55
59
|
you've got capacity still but aren't starving threads.
|
56
60
|
|
61
|
+
**Measuring utilization**
|
62
|
+
|
63
|
+
Using a timestamp header from an upstream proxy server (eg. nginx or haproxy), it's
|
64
|
+
possible to get an indication of how long requests have been waiting for a Puma
|
65
|
+
thread to become available.
|
66
|
+
|
67
|
+
* Have your upstream proxy set a header with the time it received the request:
|
68
|
+
* nginx: `proxy_set_header X-Request-Start "${msec}";`
|
69
|
+
* haproxy: `http-request set-header X-Request-Start "%t";`
|
70
|
+
* In your Rack middleware, determine the amount of time elapsed since `X-Request-Start`.
|
71
|
+
* To improve accuracy, you will want to subtract time spent waiting for slow clients:
|
72
|
+
* `env['puma.request_body_wait']` contains the number of milliseconds Puma spent
|
73
|
+
waiting for the client to send the request body.
|
74
|
+
* haproxy: `%Th` (TLS handshake time) and `%Ti` (idle time before request) can
|
75
|
+
can also be added as headers.
|
76
|
+
|
57
77
|
## Daemonizing
|
58
78
|
|
59
79
|
I prefer to not daemonize my servers and use something like `runit` or `upstart` to
|
@@ -62,7 +82,7 @@ makes it easy to figure out what is going on. Additionally, unlike `unicorn`,
|
|
62
82
|
puma does not require daemonization to do zero-downtime restarts.
|
63
83
|
|
64
84
|
I see people using daemonization because they start puma directly via capistrano
|
65
|
-
task and thus want it to live on past the `cap deploy`. To
|
85
|
+
task and thus want it to live on past the `cap deploy`. To these people I say:
|
66
86
|
You need to be using a process monitor. Nothing is making sure puma stays up in
|
67
87
|
this scenario! You're just waiting for something weird to happen, puma to die,
|
68
88
|
and to get paged at 3am. Do yourself a favor, at least the process monitoring
|
data/docs/restart.md
CHANGED
@@ -2,8 +2,8 @@
|
|
2
2
|
|
3
3
|
To perform a restart, there are 3 builtin mechanisms:
|
4
4
|
|
5
|
-
* Send the `puma` process the `SIGUSR2` signal
|
6
|
-
* Send the `puma` process the `SIGUSR1` signal (rolling restart, cluster mode only)
|
5
|
+
* Send the `puma` process the `SIGUSR2` signal (normal restart)
|
6
|
+
* Send the `puma` process the `SIGUSR1` signal (restart in phases (a "rolling restart"), cluster mode only)
|
7
7
|
* Use the status server and issue `/restart`
|
8
8
|
|
9
9
|
No code is shared between the current and restarted process, so it should be safe to issue a restart any place where you would manually stop Puma and start it again.
|
@@ -20,7 +20,9 @@ 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
|
+
|
25
|
+
**Note**: Hot and phased restarts are only available on MRI, not on JRuby. They are also unavailable on Windows servers.
|
24
26
|
|
25
27
|
### Release Directory
|
26
28
|
|
data/docs/systemd.md
CHANGED
@@ -32,21 +32,26 @@ Type=simple
|
|
32
32
|
# Preferably configure a non-privileged user
|
33
33
|
# User=
|
34
34
|
|
35
|
-
# The path to the
|
36
|
-
# Also replace the "<
|
37
|
-
|
35
|
+
# The path to the your application code root directory.
|
36
|
+
# Also replace the "<YOUR_APP_PATH>" place holders below with this path.
|
37
|
+
# Example /home/username/myapp
|
38
|
+
WorkingDirectory=<YOUR_APP_PATH>
|
38
39
|
|
39
40
|
# Helpful for debugging socket activation, etc.
|
40
41
|
# Environment=PUMA_DEBUG=1
|
41
42
|
|
42
|
-
#
|
43
|
-
#
|
44
|
-
#
|
45
|
-
ExecStart
|
43
|
+
# SystemD will not run puma even if it is in your path. You must specify
|
44
|
+
# an absolute URL to puma. For example /usr/local/bin/puma
|
45
|
+
# Alternatively, create a binstub with `bundle binstubs puma --path ./sbin` in the WorkingDirectory
|
46
|
+
ExecStart=/<FULLPATH>/bin/puma -C <YOUR_APP_PATH>/puma.rb
|
47
|
+
|
48
|
+
# Variant: Rails start.
|
49
|
+
# ExecStart=/<FULLPATH>/bin/puma -C <YOUR_APP_PATH>/config/puma.rb ../config.ru
|
46
50
|
|
47
|
-
# Variant: Use config file with `bind` directives instead:
|
48
|
-
# ExecStart=<WD>/sbin/puma -C config.rb
|
49
51
|
# Variant: Use `bundle exec --keep-file-descriptors puma` instead of binstub
|
52
|
+
# Variant: Specify directives inline.
|
53
|
+
# ExecStart=/<FULLPATH>/puma -b tcp://0.0.0.0:9292 -b ssl://0.0.0.0:9293?key=key.pem&cert=cert.pem
|
54
|
+
|
50
55
|
|
51
56
|
Restart=always
|
52
57
|
|
@@ -66,6 +71,13 @@ listening sockets open across puma restarts and achieves graceful
|
|
66
71
|
restarts, including when upgraded puma, and is compatible with both
|
67
72
|
clustered mode and application preload.
|
68
73
|
|
74
|
+
**Note:** Any wrapper scripts which `exec`, or other indirections in
|
75
|
+
`ExecStart`, may result in activated socket file descriptors being closed
|
76
|
+
before they reach the puma master process. For example, if using `bundle exec`,
|
77
|
+
pass the `--keep-file-descriptors` flag. `bundle exec` can be avoided by using a
|
78
|
+
`puma` executable generated by `bundle binstubs puma`. This is tracked in
|
79
|
+
[#1499].
|
80
|
+
|
69
81
|
**Note:** Socket activation doesn't currently work on jruby. This is
|
70
82
|
tracked in [#1367].
|
71
83
|
|
@@ -102,6 +114,16 @@ for additional configuration details.
|
|
102
114
|
Note that the above configurations will work with Puma in either
|
103
115
|
single process or cluster mode.
|
104
116
|
|
117
|
+
### Sockets and symlinks
|
118
|
+
|
119
|
+
When using releases folders, you should set the socket path using the
|
120
|
+
shared folder path (ex. `/srv/projet/shared/tmp/puma.sock`), not the
|
121
|
+
release folder path (`/srv/projet/releases/1234/tmp/puma.sock`).
|
122
|
+
|
123
|
+
Puma will detect the release path socket as different than the one provided by
|
124
|
+
systemd and attempt to bind it again, resulting in the exception
|
125
|
+
`There is already a server bound to:`.
|
126
|
+
|
105
127
|
## Usage
|
106
128
|
|
107
129
|
Without socket activation, use `systemctl` as root (e.g. via `sudo`) as
|
@@ -237,6 +259,12 @@ PIDFile=<WD>/shared/tmp/pids/puma.pid
|
|
237
259
|
# reconsider if you actually need the forking config.
|
238
260
|
Restart=no
|
239
261
|
|
262
|
+
# `puma_ctl restart` wouldn't work without this. It's because `pumactl`
|
263
|
+
# changes PID on restart and systemd stops the service afterwards
|
264
|
+
# because of the PID change. This option prevents stopping after PID
|
265
|
+
# change.
|
266
|
+
RemainAfterExit=yes
|
267
|
+
|
240
268
|
[Install]
|
241
269
|
WantedBy=multi-user.target
|
242
270
|
~~~~
|
@@ -6,11 +6,13 @@ import org.jruby.Ruby;
|
|
6
6
|
import org.jruby.runtime.load.BasicLibraryService;
|
7
7
|
|
8
8
|
import org.jruby.puma.Http11;
|
9
|
+
import org.jruby.puma.IOBuffer;
|
9
10
|
import org.jruby.puma.MiniSSL;
|
10
11
|
|
11
12
|
public class PumaHttp11Service implements BasicLibraryService {
|
12
13
|
public boolean basicLoad(final Ruby runtime) throws IOException {
|
13
14
|
Http11.createHttp11(runtime);
|
15
|
+
IOBuffer.createIOBuffer(runtime);
|
14
16
|
MiniSSL.createMiniSSL(runtime);
|
15
17
|
return true;
|
16
18
|
}
|
data/ext/puma_http11/mini_ssl.c
CHANGED
@@ -142,6 +142,7 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
|
|
142
142
|
VALUE obj;
|
143
143
|
SSL_CTX* ctx;
|
144
144
|
SSL* ssl;
|
145
|
+
int ssl_options;
|
145
146
|
|
146
147
|
ms_conn* conn = engine_alloc(self, &obj);
|
147
148
|
|
@@ -161,6 +162,13 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
|
|
161
162
|
ID sym_verify_mode = rb_intern("verify_mode");
|
162
163
|
VALUE verify_mode = rb_funcall(mini_ssl_ctx, sym_verify_mode, 0);
|
163
164
|
|
165
|
+
ID sym_ssl_cipher_filter = rb_intern("ssl_cipher_filter");
|
166
|
+
VALUE ssl_cipher_filter = rb_funcall(mini_ssl_ctx, sym_ssl_cipher_filter, 0);
|
167
|
+
|
168
|
+
ID sym_no_tlsv1 = rb_intern("no_tlsv1");
|
169
|
+
VALUE no_tlsv1 = rb_funcall(mini_ssl_ctx, sym_no_tlsv1, 0);
|
170
|
+
|
171
|
+
|
164
172
|
ctx = SSL_CTX_new(SSLv23_server_method());
|
165
173
|
conn->ctx = ctx;
|
166
174
|
|
@@ -172,20 +180,37 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
|
|
172
180
|
SSL_CTX_load_verify_locations(ctx, RSTRING_PTR(ca), NULL);
|
173
181
|
}
|
174
182
|
|
175
|
-
|
183
|
+
ssl_options = 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;
|
184
|
+
|
185
|
+
if(RTEST(no_tlsv1)) {
|
186
|
+
ssl_options |= SSL_OP_NO_TLSv1;
|
187
|
+
}
|
188
|
+
SSL_CTX_set_options(ctx, ssl_options);
|
176
189
|
SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
|
177
190
|
|
178
|
-
|
191
|
+
if (!NIL_P(ssl_cipher_filter)) {
|
192
|
+
StringValue(ssl_cipher_filter);
|
193
|
+
SSL_CTX_set_cipher_list(ctx, RSTRING_PTR(ssl_cipher_filter));
|
194
|
+
}
|
195
|
+
else {
|
196
|
+
SSL_CTX_set_cipher_list(ctx, "HIGH:!aNULL@STRENGTH");
|
197
|
+
}
|
179
198
|
|
180
199
|
DH *dh = get_dh1024();
|
181
200
|
SSL_CTX_set_tmp_dh(ctx, dh);
|
182
201
|
|
183
|
-
#
|
184
|
-
|
202
|
+
#if OPENSSL_VERSION_NUMBER < 0x10002000L
|
203
|
+
// Remove this case if OpenSSL 1.0.1 (now EOL) support is no
|
204
|
+
// longer needed.
|
205
|
+
EC_KEY *ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
|
185
206
|
if (ecdh) {
|
186
207
|
SSL_CTX_set_tmp_ecdh(ctx, ecdh);
|
187
208
|
EC_KEY_free(ecdh);
|
188
209
|
}
|
210
|
+
#elif OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
211
|
+
// Prior to OpenSSL 1.1.0, servers must manually enable server-side ECDH
|
212
|
+
// negotiation.
|
213
|
+
SSL_CTX_set_ecdh_auto(ctx, 1);
|
189
214
|
#endif
|
190
215
|
|
191
216
|
ssl = SSL_new(ctx);
|
@@ -208,7 +233,7 @@ VALUE engine_init_client(VALUE klass) {
|
|
208
233
|
VALUE obj;
|
209
234
|
ms_conn* conn = engine_alloc(klass, &obj);
|
210
235
|
|
211
|
-
conn->ctx = SSL_CTX_new(
|
236
|
+
conn->ctx = SSL_CTX_new(DTLS_method());
|
212
237
|
conn->ssl = SSL_new(conn->ctx);
|
213
238
|
SSL_set_app_data(conn->ssl, NULL);
|
214
239
|
SSL_set_verify(conn->ssl, SSL_VERIFY_NONE, NULL);
|
@@ -424,6 +449,18 @@ void Init_mini_ssl(VALUE puma) {
|
|
424
449
|
mod = rb_define_module_under(puma, "MiniSSL");
|
425
450
|
eng = rb_define_class_under(mod, "Engine", rb_cObject);
|
426
451
|
|
452
|
+
// OpenSSL Build / Runtime/Load versions
|
453
|
+
|
454
|
+
/* Version of OpenSSL that Puma was compiled with */
|
455
|
+
rb_define_const(mod, "OPENSSL_VERSION", rb_str_new2(OPENSSL_VERSION_TEXT));
|
456
|
+
|
457
|
+
#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000
|
458
|
+
/* Version of OpenSSL that Puma loaded with */
|
459
|
+
rb_define_const(mod, "OPENSSL_LIBRARY_VERSION", rb_str_new2(OpenSSL_version(OPENSSL_VERSION)));
|
460
|
+
#else
|
461
|
+
rb_define_const(mod, "OPENSSL_LIBRARY_VERSION", rb_str_new2(SSLeay_version(SSLEAY_VERSION)));
|
462
|
+
#endif
|
463
|
+
|
427
464
|
rb_define_singleton_method(mod, "check", noop, 0);
|
428
465
|
|
429
466
|
eError = rb_define_class_under(mod, "SSLError", rb_eStandardError);
|