puma 3.12.1 → 4.0.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of puma might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/History.md +47 -5
- data/README.md +29 -9
- data/docs/architecture.md +1 -0
- data/docs/deployment.md +24 -4
- data/docs/restart.md +4 -2
- data/docs/systemd.md +27 -9
- data/ext/puma_http11/PumaHttp11Service.java +2 -0
- data/ext/puma_http11/extconf.rb +8 -0
- data/ext/puma_http11/mini_ssl.c +26 -4
- data/ext/puma_http11/org/jruby/puma/IOBuffer.java +72 -0
- data/ext/puma_http11/org/jruby/puma/MiniSSL.java +11 -4
- data/lib/puma/app/status.rb +3 -2
- data/lib/puma/binder.rb +10 -1
- data/lib/puma/client.rb +43 -25
- data/lib/puma/cluster.rb +38 -14
- data/lib/puma/configuration.rb +2 -1
- data/lib/puma/const.rb +6 -2
- data/lib/puma/control_cli.rb +10 -0
- data/lib/puma/dsl.rb +45 -3
- data/lib/puma/io_buffer.rb +1 -6
- data/lib/puma/launcher.rb +12 -13
- data/lib/puma/minissl.rb +13 -1
- data/lib/puma/reactor.rb +104 -53
- data/lib/puma/runner.rb +1 -1
- data/lib/puma/server.rb +25 -24
- data/lib/puma/single.rb +2 -2
- data/lib/puma/thread_pool.rb +5 -1
- data/lib/puma/util.rb +1 -6
- data/tools/jungle/init.d/puma +5 -5
- metadata +22 -11
- data/lib/puma/compat.rb +0 -14
- data/lib/puma/java_io_buffer.rb +0 -47
- data/lib/puma/rack/backports/uri/common_193.rb +0 -33
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2da4583ff5ef681c3c08be5b56e1bcf2134d34ddf226f066aecc288a8bf197b5
|
4
|
+
data.tar.gz: '0963edfc828d163f4c7afeee080ff6264171db93416a423b8585fe20f532e7c1'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6fcb34a36a1ab1a24c2f2ce859fcb99aa99a7fcdddfa6ab034e1af70fe02b6d44158b8fccb5e3d41c90fefcd80f835aa62e7c6121c428f01f8816abc39d8a3c1
|
7
|
+
data.tar.gz: 147d74c560432cbaaed701dd815287e4e71241468c6222a6e6186a63e2c39aaeed4615287f5cd3bb373be5195251b17fe98c945c15d73821c9d41bbbc8309a7d
|
data/History.md
CHANGED
@@ -1,10 +1,43 @@
|
|
1
1
|
## Master
|
2
2
|
|
3
|
-
*
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
* Features
|
4
|
+
* Your feature goes here (#Github Number)
|
5
|
+
|
6
|
+
* Bugfixes
|
7
|
+
* Your bugfix goes here (#Github Number)
|
8
|
+
|
9
|
+
## 4.0.1 / 2019-07-11
|
10
|
+
|
11
|
+
* 2 bugfixes
|
12
|
+
* Fix socket removed after reload - should fix problems with systemd socket activation. (#1829)
|
13
|
+
* Add extconf tests for DTLS_method & TLS_server_method, use in minissl.rb. Should fix "undefined symbol: DTLS_method" when compiling against old OpenSSL versions. (#1832)
|
14
|
+
* Removed unnecessary RUBY_VERSION checks. (#1827)
|
15
|
+
|
16
|
+
## 4.0.0 / 2019-06-25
|
17
|
+
|
18
|
+
* 9 features
|
19
|
+
* Add support for disabling TLSv1.0 (#1562)
|
20
|
+
* Request body read time metric (#1569)
|
21
|
+
* Add out_of_band hook (#1648)
|
22
|
+
* Re-implement (native) IOBuffer for JRuby (#1691)
|
23
|
+
* Min worker timeout (#1716)
|
24
|
+
* Add option to suppress SignalException on SIGTERM (#1690)
|
25
|
+
* Allow mutual TLS CA to be set using `ssl_bind` DSL (#1689)
|
26
|
+
* Reactor now uses nio4r instead of `select` (#1728)
|
27
|
+
* Add status to pumactl with pidfile (#1824)
|
28
|
+
|
29
|
+
* 9 bugfixes
|
30
|
+
* Do not accept new requests on shutdown (#1685, #1808)
|
31
|
+
* Fix 3 corner cases when request body is chunked (#1508)
|
32
|
+
* Change pid existence check's condition branches (#1650)
|
33
|
+
* Don't call .stop on a server that doesn't exist (#1655)
|
34
|
+
* Implemented NID_X9_62_prime256v1 (P-256) curve over P-521 (#1671)
|
35
|
+
* Fix @notify.close can't modify frozen IOError (RuntimeError) (#1583)
|
36
|
+
* Fix Java 8 support (#1773)
|
37
|
+
* Fix error `uninitialized constant Puma::Cluster` (#1731)
|
38
|
+
* Fix `not_token` being able to be set to true (#1803)
|
39
|
+
|
40
|
+
## 3.12.1 / 2019-03-19
|
8
41
|
|
9
42
|
* 1 features
|
10
43
|
* Internal strings are frozen (#1649)
|
@@ -1410,3 +1443,12 @@ be added back in a future date when a java Puma::MiniSSL is added.
|
|
1410
1443
|
## 1.0.0 / 2012-03-29
|
1411
1444
|
|
1412
1445
|
* Released!
|
1446
|
+
|
1447
|
+
## Ignore - this is for maintainers to copy-paste during release
|
1448
|
+
## Master
|
1449
|
+
|
1450
|
+
* Features
|
1451
|
+
* Your feature goes here (#Github Number)
|
1452
|
+
|
1453
|
+
* Bugfixes
|
1454
|
+
* Your bugfix goes here (#Github Number)
|
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
|
|
@@ -160,18 +160,31 @@ Need a bit of security? Use SSL sockets:
|
|
160
160
|
```
|
161
161
|
$ puma -b 'ssl://127.0.0.1:9292?key=path_to_key&cert=path_to_cert'
|
162
162
|
```
|
163
|
+
|
163
164
|
#### Controlling SSL Cipher Suites
|
164
|
-
|
165
|
-
|
165
|
+
|
166
|
+
Need to use or avoid specific SSL cipher suites? Use `ssl_cipher_filter` or `ssl_cipher_list` options.
|
167
|
+
|
168
|
+
##### Ruby:
|
169
|
+
|
166
170
|
```
|
167
171
|
$ puma -b 'ssl://127.0.0.1:9292?key=path_to_key&cert=path_to_cert&ssl_cipher_filter=!aNULL:AES+SHA'
|
168
172
|
```
|
169
|
-
|
173
|
+
|
174
|
+
##### JRuby:
|
175
|
+
|
170
176
|
```
|
171
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'
|
172
178
|
```
|
179
|
+
|
173
180
|
See https://www.openssl.org/docs/man1.0.2/apps/ciphers.html for cipher filter format and full list of cipher suites.
|
174
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
|
+
|
175
188
|
### Control/Status Server
|
176
189
|
|
177
190
|
Puma has a built-in status/control app that can be used to query and control Puma itself.
|
@@ -249,6 +262,13 @@ reliability in production environments:
|
|
249
262
|
* [tools/jungle](https://github.com/puma/puma/tree/master/tools/jungle) for sysvinit (init.d) and upstart
|
250
263
|
* [docs/systemd](https://github.com/puma/puma/blob/master/docs/systemd.md)
|
251
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
|
+
|
252
272
|
## Contributing
|
253
273
|
|
254
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)
|
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.
|
@@ -22,6 +22,8 @@ But again beware, upgrading an application sometimes involves upgrading the data
|
|
22
22
|
|
23
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
|
+
**Note**: Hot and phased restarts are only available on MRI, not on JRuby. They are also unavailable on Windows servers.
|
26
|
+
|
25
27
|
### Release Directory
|
26
28
|
|
27
29
|
If your symlink releases into a common working directory (i.e., `/current` from Capistrano), Puma won't pick up your new changes when running phased restarts without additional configuration. You should set your working directory within Puma's config to specify the directory it should use. This is a change from earlier versions of Puma (< 2.15) that would infer the directory for you.
|
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
|
|
@@ -247,6 +259,12 @@ PIDFile=<WD>/shared/tmp/pids/puma.pid
|
|
247
259
|
# reconsider if you actually need the forking config.
|
248
260
|
Restart=no
|
249
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
|
+
|
250
268
|
[Install]
|
251
269
|
WantedBy=multi-user.target
|
252
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/extconf.rb
CHANGED
@@ -9,6 +9,14 @@ unless ENV["DISABLE_SSL"]
|
|
9
9
|
%w'ssl ssleay32'.find {|ssl| have_library(ssl, 'SSL_CTX_new')}
|
10
10
|
|
11
11
|
have_header "openssl/bio.h"
|
12
|
+
|
13
|
+
# below is yes for 1.0.2 & later
|
14
|
+
have_func "DTLS_method" , "openssl/ssl.h"
|
15
|
+
|
16
|
+
# below are yes for 1.1.0 & later, may need to check func rather than macro
|
17
|
+
# with versions after 1.1.1
|
18
|
+
have_func "TLS_server_method" , "openssl/ssl.h"
|
19
|
+
have_macro "SSL_CTX_set_min_proto_version", "openssl/ssl.h"
|
12
20
|
end
|
13
21
|
end
|
14
22
|
|
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
|
|
@@ -164,7 +165,14 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
|
|
164
165
|
ID sym_ssl_cipher_filter = rb_intern("ssl_cipher_filter");
|
165
166
|
VALUE ssl_cipher_filter = rb_funcall(mini_ssl_ctx, sym_ssl_cipher_filter, 0);
|
166
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
|
+
#ifdef HAVE_TLS_SERVER_METHOD
|
172
|
+
ctx = SSL_CTX_new(TLS_server_method());
|
173
|
+
#else
|
167
174
|
ctx = SSL_CTX_new(SSLv23_server_method());
|
175
|
+
#endif
|
168
176
|
conn->ctx = ctx;
|
169
177
|
|
170
178
|
SSL_CTX_use_certificate_chain_file(ctx, RSTRING_PTR(cert));
|
@@ -175,7 +183,12 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
|
|
175
183
|
SSL_CTX_load_verify_locations(ctx, RSTRING_PTR(ca), NULL);
|
176
184
|
}
|
177
185
|
|
178
|
-
|
186
|
+
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;
|
187
|
+
|
188
|
+
if(RTEST(no_tlsv1)) {
|
189
|
+
ssl_options |= SSL_OP_NO_TLSv1;
|
190
|
+
}
|
191
|
+
SSL_CTX_set_options(ctx, ssl_options);
|
179
192
|
SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
|
180
193
|
|
181
194
|
if (!NIL_P(ssl_cipher_filter)) {
|
@@ -189,12 +202,18 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
|
|
189
202
|
DH *dh = get_dh1024();
|
190
203
|
SSL_CTX_set_tmp_dh(ctx, dh);
|
191
204
|
|
192
|
-
#
|
193
|
-
|
205
|
+
#if OPENSSL_VERSION_NUMBER < 0x10002000L
|
206
|
+
// Remove this case if OpenSSL 1.0.1 (now EOL) support is no
|
207
|
+
// longer needed.
|
208
|
+
EC_KEY *ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
|
194
209
|
if (ecdh) {
|
195
210
|
SSL_CTX_set_tmp_ecdh(ctx, ecdh);
|
196
211
|
EC_KEY_free(ecdh);
|
197
212
|
}
|
213
|
+
#elif OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
214
|
+
// Prior to OpenSSL 1.1.0, servers must manually enable server-side ECDH
|
215
|
+
// negotiation.
|
216
|
+
SSL_CTX_set_ecdh_auto(ctx, 1);
|
198
217
|
#endif
|
199
218
|
|
200
219
|
ssl = SSL_new(ctx);
|
@@ -216,8 +235,11 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
|
|
216
235
|
VALUE engine_init_client(VALUE klass) {
|
217
236
|
VALUE obj;
|
218
237
|
ms_conn* conn = engine_alloc(klass, &obj);
|
219
|
-
|
238
|
+
#ifdef HAVE_DTLS_METHOD
|
239
|
+
conn->ctx = SSL_CTX_new(DTLS_method());
|
240
|
+
#else
|
220
241
|
conn->ctx = SSL_CTX_new(DTLSv1_method());
|
242
|
+
#endif
|
221
243
|
conn->ssl = SSL_new(conn->ctx);
|
222
244
|
SSL_set_app_data(conn->ssl, NULL);
|
223
245
|
SSL_set_verify(conn->ssl, SSL_VERIFY_NONE, NULL);
|
@@ -0,0 +1,72 @@
|
|
1
|
+
package org.jruby.puma;
|
2
|
+
|
3
|
+
import org.jruby.*;
|
4
|
+
import org.jruby.anno.JRubyMethod;
|
5
|
+
import org.jruby.runtime.ObjectAllocator;
|
6
|
+
import org.jruby.runtime.ThreadContext;
|
7
|
+
import org.jruby.runtime.builtin.IRubyObject;
|
8
|
+
import org.jruby.util.ByteList;
|
9
|
+
|
10
|
+
/**
|
11
|
+
* @author kares
|
12
|
+
*/
|
13
|
+
public class IOBuffer extends RubyObject {
|
14
|
+
|
15
|
+
private static final ObjectAllocator ALLOCATOR = new ObjectAllocator() {
|
16
|
+
public IRubyObject allocate(Ruby runtime, RubyClass klass) {
|
17
|
+
return new IOBuffer(runtime, klass);
|
18
|
+
}
|
19
|
+
};
|
20
|
+
|
21
|
+
public static void createIOBuffer(Ruby runtime) {
|
22
|
+
RubyModule mPuma = runtime.defineModule("Puma");
|
23
|
+
RubyClass cIOBuffer = mPuma.defineClassUnder("IOBuffer", runtime.getObject(), ALLOCATOR);
|
24
|
+
cIOBuffer.defineAnnotatedMethods(IOBuffer.class);
|
25
|
+
}
|
26
|
+
|
27
|
+
private static final int DEFAULT_SIZE = 4096;
|
28
|
+
|
29
|
+
final ByteList buffer = new ByteList(DEFAULT_SIZE);
|
30
|
+
|
31
|
+
IOBuffer(Ruby runtime, RubyClass klass) {
|
32
|
+
super(runtime, klass);
|
33
|
+
}
|
34
|
+
|
35
|
+
@JRubyMethod
|
36
|
+
public RubyInteger used(ThreadContext context) {
|
37
|
+
return context.runtime.newFixnum(buffer.getRealSize());
|
38
|
+
}
|
39
|
+
|
40
|
+
@JRubyMethod
|
41
|
+
public RubyInteger capacity(ThreadContext context) {
|
42
|
+
return context.runtime.newFixnum(buffer.unsafeBytes().length);
|
43
|
+
}
|
44
|
+
|
45
|
+
@JRubyMethod
|
46
|
+
public IRubyObject reset() {
|
47
|
+
buffer.setRealSize(0);
|
48
|
+
return this;
|
49
|
+
}
|
50
|
+
|
51
|
+
@JRubyMethod(name = { "to_s", "to_str" })
|
52
|
+
public RubyString to_s(ThreadContext context) {
|
53
|
+
return RubyString.newStringShared(context.runtime, buffer.unsafeBytes(), 0, buffer.getRealSize());
|
54
|
+
}
|
55
|
+
|
56
|
+
@JRubyMethod(name = "<<")
|
57
|
+
public IRubyObject add(IRubyObject str) {
|
58
|
+
addImpl(str.convertToString());
|
59
|
+
return this;
|
60
|
+
}
|
61
|
+
|
62
|
+
@JRubyMethod(rest = true)
|
63
|
+
public IRubyObject append(IRubyObject[] strs) {
|
64
|
+
for (IRubyObject str : strs) addImpl(str.convertToString());
|
65
|
+
return this;
|
66
|
+
}
|
67
|
+
|
68
|
+
private void addImpl(RubyString str) {
|
69
|
+
buffer.append(str.getByteList());
|
70
|
+
}
|
71
|
+
|
72
|
+
}
|