Skip to content

Instantly share code, notes, and snippets.

@pvalena
Created January 18, 2022 12:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pvalena/e4affc6bfcb1e2e4a3898723327de761 to your computer and use it in GitHub Desktop.
Save pvalena/e4affc6bfcb1e2e4a3898723327de761 to your computer and use it in GitHub Desktop.
NOTE: Gem::Specification#has_rdoc is deprecated with no replacement. It will be removed in Rubygems 4
Gem::Specification#has_rdoc called from /usr/share/gems/gems/gem-compare-0.0.7/lib/rubygems/comparator/utils.rb:112.
NOTE: Gem::Specification#has_rdoc is deprecated with no replacement. It will be removed in Rubygems 4
Gem::Specification#has_rdoc called from /usr/share/gems/gems/gem-compare-0.0.7/lib/rubygems/comparator/utils.rb:112.
Compared versions: ["4.3.6", "5.5.2"]
DIFFERENT description:
4.3.6: Puma is a simple, fast, threaded, and highly concurrent HTTP 1.1 server for Ruby/Rack applications. Puma is intended for use in both development and production environments. It's great for highly concurrent Ruby implementations such as Rubinius and JRuby as well as as providing process worker support to support CRuby well.
5.5.2: Puma is a simple, fast, threaded, and highly parallel HTTP 1.1 server for Ruby/Rack applications. Puma is intended for use in both development and production environments. It's great for highly parallel Ruby implementations such as Rubinius and JRuby as well as as providing process worker support to support CRuby well.
DIFFERENT homepage:
4.3.6: http://puma.io
5.5.2: https://puma.io
DIFFERENT metadata:
4.3.6: {"msys2_mingw_dependencies"=>"openssl", "changelog_uri"=>"https://github.com/puma/puma/blob/master/History.md"}
5.5.2: {"bug_tracker_uri"=>"https://github.com/puma/puma/issues", "changelog_uri"=>"https://github.com/puma/puma/blob/master/History.md", "homepage_uri"=>"https://puma.io", "source_code_uri"=>"https://github.com/puma/puma"}
DIFFERENT require_paths:
4.3.6: ["/usr/lib64/gems/ruby/puma-4.3.6", "lib"]
5.5.2: ["/usr/lib64/gems/ruby/puma-5.5.2", "lib"]
DIFFERENT summary:
4.3.6: Puma is a simple, fast, threaded, and highly concurrent HTTP 1.1 server for Ruby/Rack applications
5.5.2: Puma is a simple, fast, threaded, and highly parallel HTTP 1.1 server for Ruby/Rack applications
DIFFERENT files:
4.3.6->5.5.2:
* Deleted:
tools/docker/
tools/jungle/
tools/jungle/init.d/
tools/jungle/rc.d/
tools/jungle/upstart/
* Added:
docs/jungle/
docs/jungle/rc.d/
ext/puma_http11/no_ssl/
lib/puma/cluster/
docs/jungle/rc.d/puma
(!) Unexpected permissions: 100755
(!) File is executable
(!) Shebang found: #!/bin/sh
commit 91ae167706d3409c0277eb4ade20042f18d25d33
Author: Pavel Valena <pvalena@redhat.com>
Date: Wed Jun 10 22:07:22 2020 +0200
Update to puma 5.5.2
also enhance .spec file.
test/shell/run.rb was replaced by test/test_integration_cluster.rb
Resolves: rhbz#1880111
diff --git a/rubygem-puma-3.6.0-fedora-crypto-policy-cipher-list.patch b/rubygem-puma-3.6.0-fedora-crypto-policy-cipher-list.patch
index 0633e2d..1e9954f 100644
--- a/rubygem-puma-3.6.0-fedora-crypto-policy-cipher-list.patch
+++ b/rubygem-puma-3.6.0-fedora-crypto-policy-cipher-list.patch
@@ -2,7 +2,7 @@ diff --git a/ext/puma_http11/mini_ssl.c b/ext/puma_http11/mini_ssl.c
index 7e0fd5e..88c4652 100644
--- a/ext/puma_http11/mini_ssl.c
+++ b/ext/puma_http11/mini_ssl.c
-@@ -223,7 +223,7 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
+@@ -286,7 +286,7 @@ sslctx_initialize(VALUE self, VALUE mini_ssl_ctx) {
SSL_CTX_set_cipher_list(ctx, RSTRING_PTR(ssl_cipher_filter));
}
else {
@@ -10,7 +10,7 @@ index 7e0fd5e..88c4652 100644
+ SSL_CTX_set_cipher_list(ctx, "PROFILE=SYSTEM");
}
- DH *dh = get_dh1024();
+ dh = get_dh2048();
--
-2.5.5
+2.30.0
diff --git a/rubygem-puma-5.0.0-Report-pumactl-exit.patch b/rubygem-puma-5.0.0-Report-pumactl-exit.patch
deleted file mode 100644
index f18f2b6..0000000
--- a/rubygem-puma-5.0.0-Report-pumactl-exit.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From aebca2b3d7f7a8cd51b0a7047851c9a2e0af7013 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?V=C3=ADt=20Ondruch?= <vondruch@redhat.com>
-Date: Fri, 7 Aug 2020 12:52:31 +0200
-Subject: [PATCH] Do not quite when `pumactl` unexpectedly exits.
-
-When `pumactl` encounters issue, it exits [[1]]. That way also the whole
-test suite unexpectedly exits. Rescuing `SystemExit` exception keeps the
-test suite finish.
-
-Fixes #2329
-
-[1]: https://github.com/puma/puma/blob/0f718d516b92cd8bc4120c543b06792b22ac20bb/lib/puma/control_cli.rb#L272
----
- test/test_pumactl.rb | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
-diff --git a/test/test_pumactl.rb b/test/test_pumactl.rb
-index 96bafa28e..e5c5ec7e6 100644
---- a/test/test_pumactl.rb
-+++ b/test/test_pumactl.rb
-@@ -178,7 +178,10 @@ def test_control_ssl
- def assert_command_cli_output(options, expected_out)
- cmd = Puma::ControlCLI.new(options)
- out, _ = capture_subprocess_io do
-- cmd.run
-+ begin
-+ cmd.run
-+ rescue SystemExit => e
-+ end
- end
- assert_match expected_out, out
- end
diff --git a/rubygem-puma-5.0.0-Update-test-certs-and-code.patch b/rubygem-puma-5.0.0-Update-test-certs-and-code.patch
deleted file mode 100644
index 36671a4..0000000
--- a/rubygem-puma-5.0.0-Update-test-certs-and-code.patch
+++ /dev/null
@@ -1,1583 +0,0 @@
-From aac47086f1a6e38baf69159a2bc7e64b0495f080 Mon Sep 17 00:00:00 2001
-From: MSP-Greg <Greg.mpls@gmail.com>
-Date: Fri, 7 Aug 2020 16:31:36 -0500
-Subject: [PATCH 2/3] Update test certs to work with more secure OpenSSL
- (Ubuntu 20.04)
-
-Added code for generating/updating
----
- examples/puma/cert_puma.pem | 34 ++---
- examples/puma/client-certs/ca.crt | 34 ++---
- examples/puma/client-certs/ca.key | 50 +++----
- examples/puma/client-certs/client.crt | 34 ++---
- examples/puma/client-certs/client.key | 50 +++----
- examples/puma/client-certs/client_expired.crt | 34 ++---
- examples/puma/client-certs/client_expired.key | 50 +++----
- examples/puma/client-certs/client_unknown.crt | 34 ++---
- examples/puma/client-certs/client_unknown.key | 50 +++----
- examples/puma/client-certs/generate.rb | 78 ----------
- .../puma/client-certs/generate_client_test.rb | 133 ++++++++++++++++++
- examples/puma/client-certs/keystore.jks | Bin 3743 -> 3740 bytes
- .../client-certs/run_server_with_certs.rb | 26 ++++
- examples/puma/client-certs/server.crt | 34 ++---
- examples/puma/client-certs/server.key | 50 +++----
- examples/puma/client-certs/server.p12 | Bin 3274 -> 3266 bytes
- examples/puma/client-certs/unknown_ca.crt | 34 ++---
- examples/puma/client-certs/unknown_ca.key | 50 +++----
- examples/puma/generate_server_test.rb | 56 ++++++++
- examples/puma/keystore.jks | Bin 2211 -> 2253 bytes
- examples/puma/puma_keypair.pem | 38 +++--
- examples/puma/server.p12 | Bin 0 -> 2550 bytes
- test/helpers/ssl.rb | 2 +-
- 23 files changed, 511 insertions(+), 360 deletions(-)
- delete mode 100644 examples/puma/client-certs/generate.rb
- create mode 100644 examples/puma/client-certs/generate_client_test.rb
- create mode 100644 examples/puma/client-certs/run_server_with_certs.rb
- create mode 100644 examples/puma/generate_server_test.rb
- create mode 100644 examples/puma/server.p12
-
-diff --git a/examples/puma/cert_puma.pem b/examples/puma/cert_puma.pem
-index 7e68d622a..a0730990d 100644
---- a/examples/puma/cert_puma.pem
-+++ b/examples/puma/cert_puma.pem
-@@ -1,19 +1,21 @@
- -----BEGIN CERTIFICATE-----
--MIIC/jCCAeagAwIBAgIBAjANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJVUzEO
--MAwGA1UECgwFbG9jYWwxDTALBgNVBAsMBGFlcm8xCzAJBgNVBAMMAkNBMB4XDTEy
--MDExNDAwMjcyN1oXDTEzMDExMzAwMjcyN1owSDELMAkGA1UEBhMCVVMxDjAMBgNV
-+MIIDgjCCAmqgAwIBAgIBAjANBgkqhkiG9w0BAQsFADA5MQswCQYDVQQGEwJVUzEO
-+MAwGA1UECgwFbG9jYWwxDTALBgNVBAsMBGFlcm8xCzAJBgNVBAMMAkNBMB4XDTIw
-+MDgwMTAwMDAwMFoXDTI0MDgwMTAwMDAwMFowSDELMAkGA1UEBhMCVVMxDjAMBgNV
- BAoMBWxvY2FsMQ0wCwYDVQQLDARhZXJvMQswCQYDVQQLDAJDQTENMAsGA1UEAwwE
--cHVtYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArxfNMp+g/pKhsDEkB3KR
--1MAkbfnN/UKMvfXwlnXpz7YX1LHHnMutiI/PqymAp6BPcu+umuW2qMHQyqqtyATm
--Z9jr3t837nhmxwG1noRaKRtsckn9FD43ZlpPg0Q5QnhS4oOsXwJzilqPjdDFYrKN
--3TSvIGM2+hVqpVoGYAHDKbMCAwEAAaOBhTCBgjAMBgNVHRMBAf8EAjAAMDEGCWCG
--SAGG+EIBDQQkFiJSdWJ5L09wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0G
--A1UdDgQWBBTyDyJlmYBDwfWdRj6lWGvoY43k9DALBgNVHQ8EBAMCBaAwEwYDVR0l
--BAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQEFBQADggEBAIbBVfoVCG8RyVesPW+q
--5i0wAMbHZ1fwv1RKp17c68DYDs0YYPi0bA0ss8AgpU6thWmskxPiFaE6D5x8iv9f
--zkcHxgr1Mrbx6RLx9tLUVehSmRv3aiVO4k9Mp6vf+rJK1AYeaGBmvoqTBLwy7Jrt
--ytKMdqMJj5jKWkWgEGgTnjzbcOClmCQab9isigIzTxMyC/LjeKZe8pPeVX6OM8bY
--y8XGZp9B7uwdPzqt/g25IzTC0KsQwq8cB0raAtZzIyTNv42zcUjmQNVazAozCTcq
--MsEtK2z7TYBC3udTsdyS2qVqCpsk7IMOBGrw8vk4SNhO+coiDObW2K/HNvhl0tZC
--oQI=
-+cHVtYTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9pa0gvlNdwge/u
-+aZNE5hTyBLH3eQzdduGcYjoSy6AVgab8M8s5O7RPMEDORV6xRuGfNgRI40Kkx4E8
-+w5icHSp9WumsEi5FrKIcIXttquLdcBkUEq9N/mPVZAlg5Jr5IePzWafM0gTdKlR1
-+LN/UHcVaMHWt4/Kz2ja9wlUhaKly7+UG1JdHhQ1yrAVVUTLN9YT8VTkyaB11+K0m
-+KpdvHcyFuB4yBcvCd4iGSIqf7wjlEIRp8Pa9C6tR8gAlCi4APlzmngYod3wbXAhE
-+psjvSXCWCdeHKD/wAgBz1abA4yNnSIhb4KFFkGMn+F74ZjeCZN287lz/18gQLn06
-+3EXVKIECAwEAAaOBhTCBgjAMBgNVHRMBAf8EAjAAMDEGCWCGSAGG+EIBDQQkFiJS
-+dWJ5L09wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBTyDyJl
-+mYBDwfWdRj6lWGvoY43k9DALBgNVHQ8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUH
-+AwEwDQYJKoZIhvcNAQELBQADggEBAH2YCJJY9RFO8a7wW+9LonTVL1QLvpS0bgqC
-+1CvW3ANCXriCXHUHc/aLmneRfXhrezCcAgqyqG2+HxJ3fLllec7lbiznnV7DaAmn
-+Jhgmlho9fw2FxPA4iZ5DQvCALS0Ho4Vo+kPVExbhH4XKZkVTJosms5TWmDaeyfN0
-+PyWDeyKsjqi9oXqqAZKBo9DFWxkJUThzpxXdWo2S9cKt7EWJJlgdlmQGyoo39Xdu
-+86MxNGfaS+7ChzcXQVu1B/t0fpFKfkVCEKvNEQ50v/D01Ed0hgQPOaqgFvFMp0eU
-+B0b1xpKQ2OshyOK1048ou3Gv+fAw+xtcC840T0DDMte73sysXtg=
- -----END CERTIFICATE-----
-diff --git a/examples/puma/client-certs/ca.crt b/examples/puma/client-certs/ca.crt
-index 7ca63b0ba..a69ea6fb6 100644
---- a/examples/puma/client-certs/ca.crt
-+++ b/examples/puma/client-certs/ca.crt
-@@ -1,19 +1,19 @@
- -----BEGIN CERTIFICATE-----
--MIIDEDCCAfigAwIBAgIBATANBgkqhkiG9w0BAQUFADA4MRMwEQYKCZImiZPyLGQB
--GRYDbmV0MRQwEgYKCZImiZPyLGQBGRYEcHVtYTELMAkGA1UEAwwCY2EwIBcNMTQw
--MjAyMjAwODI3WhgPMjExNTAxMDkyMDA4MjdaMDgxEzARBgoJkiaJk/IsZAEZFgNu
--ZXQxFDASBgoJkiaJk/IsZAEZFgRwdW1hMQswCQYDVQQDDAJjYTCCASIwDQYJKoZI
--hvcNAQEBBQADggEPADCCAQoCggEBAN0u8/heGbkoFDDsx6uidE6DKPvjIPnZPFzR
--CMkzrNgIeq/hfAItIJAO0m8YZivkUWeE3ut4ibSL+OVTvLRWDL/L736LILUxrD2f
--joKHHLSVIUWl3H0VjYDE2RCiVkvxP4sAo7EYecZesTtb7W7DdAjHztFZIl+wT+ri
--MlxDRmYxwsOPQtL0/wJZF80uTpC29V47NY9ITd/A+1xMblPAuQKO3vqZ4Yq07mO/
--KKSbepo07v7jMhNOSHf8VBFlTzzG5AHmxZUW0qjCkJBV8N1MiT9cIk81ZuSqOZu3
--A+aDAlOYPJe2WVpGskCme9HkJaHTeP87tQUsLqRsLgq/AXh5R58CAwEAAaMjMCEw
--DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQAD
--ggEBAKiGZ57rSAlL9slQ0FklVjpe+YrfZvmaXTRPl+9YhikoVI91u1r/qA9PrXKn
--cL6u66SU6kJwI5572uT1TpKO7jQLXJZV0LO17WuF3P7y44QnNb53Em2GYi8DD/gq
--X0Y1u8QzIxo4uomWiE73fnao2I9eErKNi/xCySaX/SLQ/9tcEgUyeLlTtJZ3feVF
--7K0llR+hSb0Wy/uWnP7qP59YsyCJl1H23j7IEVCTMsOQ4tyIK16+qRA+aVLtE9f5
--orsrOWWGJOdAn1nCJweKqhG1vd3GKGRW3Rf/iugCbvgJy0NFLfTpeJ4fJosC3A/K
--6K+pe9hNsi2kBPwC67QeVjnbqd4=
-+MIIDDjCCAfagAwIBAgIBAzANBgkqhkiG9w0BAQsFADA4MRMwEQYKCZImiZPyLGQB
-+GRYDbmV0MRQwEgYKCZImiZPyLGQBGRYEcHVtYTELMAkGA1UEAwwCQ0EwHhcNMjAw
-+ODAxMDAwMDAwWhcNMjQwODAxMDAwMDAwWjA4MRMwEQYKCZImiZPyLGQBGRYDbmV0
-+MRQwEgYKCZImiZPyLGQBGRYEcHVtYTELMAkGA1UEAwwCQ0EwggEiMA0GCSqGSIb3
-+DQEBAQUAA4IBDwAwggEKAoIBAQDIHxrFcS2JkRQbXLFosb32unVkVuwHSPSt6Dpl
-+2jUQHP/bceAx/d9waHYf8rlbCFAIoduZDOc7XCJUidgcG5NfLJyQpkkWOU8CGWH+
-+Ipl4AE8auYCcy/0T7BQqaRC41HPmrJG1CC40rqcY47lUO2haI+vj5TZFHNhAbRat
-+rR1iD1veis2gBZtrMzd4IlpvEHGv6ghfnSc20za4exmapjp/uAAIOXpeFX8QHumA
-+bty4dd+iHpKjDzUrhG9Qa5v28ii2K1AcbczUQ7FzSp2/GoRSjF+WY6i86N9Z1M97
-+2PEgy0IG5l6JHu1P0/rd00hN0h0Owzv3V5ldMLZap7+pVFQTAgMBAAGjIzAhMA8G
-+A1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IB
-+AQA3GWpy4bYLOHLENDTUBeclF6cDdYiautD6gxd1SDLMWOhAUF7ywwT87OAJdr1I
-++W1TUv5BRG21rNm1QsZfLbStdKA1mpiET/9nYN7m1YauL5hI3yD49TGuO9/sxcE5
-+zNW7D3VBVNq+pyT21/TvLAgxCNvjjm7byzyIOcoRUyZx8WhCf8nUT6cEShXqEg4Q
-+iUBSLI38tiQoZneuVzDRlXBY0PqoB19l2Kg9yThHjPTVhw5EAQSDKXCCvaxAbVw6
-+ZPLNnOdK6DvqEZ3GC5WlaHQdmLxmN4OfV6AEtpgqgGY9u8K1ylTr3ET7xLK7bhcA
-+oZsggEVZr1Ifx9BWIazRNwlw
- -----END CERTIFICATE-----
-diff --git a/examples/puma/client-certs/ca.key b/examples/puma/client-certs/ca.key
-index e229c7b91..59bc391a2 100644
---- a/examples/puma/client-certs/ca.key
-+++ b/examples/puma/client-certs/ca.key
-@@ -1,27 +1,27 @@
- -----BEGIN RSA PRIVATE KEY-----
--MIIEowIBAAKCAQEA3S7z+F4ZuSgUMOzHq6J0ToMo++Mg+dk8XNEIyTOs2Ah6r+F8
--Ai0gkA7SbxhmK+RRZ4Te63iJtIv45VO8tFYMv8vvfosgtTGsPZ+OgocctJUhRaXc
--fRWNgMTZEKJWS/E/iwCjsRh5xl6xO1vtbsN0CMfO0VkiX7BP6uIyXENGZjHCw49C
--0vT/AlkXzS5OkLb1Xjs1j0hN38D7XExuU8C5Ao7e+pnhirTuY78opJt6mjTu/uMy
--E05Id/xUEWVPPMbkAebFlRbSqMKQkFXw3UyJP1wiTzVm5Ko5m7cD5oMCU5g8l7ZZ
--WkayQKZ70eQlodN4/zu1BSwupGwuCr8BeHlHnwIDAQABAoIBABjXyj1OTHNYhhQM
--tEyZ3Zhn8PWByFVnyfje3a7DqBlHsogIuoYADZVApPAnfGpXpbEL4oHuMwFda2JO
--qnZS5/Gu9UJwXAceAiuVvUr55AaAbZFGFOLTxeX9tifBJBI5kZqKQtiEWEEop510
--MNHtEB5gWuF2sn6u7fsC1wc34zNdE/4hR1njsppIlJ1GP0ICQUI/YKybipF6+pI7
--+vg7bF5DU93/uUoRY83NjREeAswFE67OOHi592YIyr5TLu06NDqJ2EBneXyO63Q7
--pAakX84SI7k8p8t9XBW6D56pT23JYcrDXwayH1P+SAA4FdDhPlZlGPWjXqQc0biA
--l1HlfiECgYEA8bwVsukWSGE+XdRnilVATP4zTS7ZpcYzUufS9+pa5w0sVIkDScgL
--3YrB0rY7BS/kImOg+xrFz7ILCoIyjDCEVtly0Hc1aZw9SWu545lfFWcd7s7nN5nQ
--iM9jGxoAWu/VT2GKIfhxMK89CzLD1DGgqsiyYxmPMyplekupUEkkiHECgYEA6jxl
--uNddzzfKZKHEWS1Tax0hgchOaVMyML35ySz5kgw1tSO8G64eKtrSCq7wcSvb4uc3
--hz1yl5Ydxqa+1qX5Qi+UcoRhZZHqGTsbid1aiQJKltk4ImtlptBbX+NTvEDIDblQ
--fzse/a+upesutwaTchlXtuPG2F53UZeQ831GWQ8CgYAqKdtDDILVdxiwtwakS0Be
--7Yu3L6/IyWxUTpkuotLeMB8GU6ueJ+Vh6/zoqt5ahkLteKEwizfrhSuF1rXIXAIJ
--P/5VvCU12YmbD84pk6vRCN5gs/gCa7LC2iF4La3YLrLvGJ1GVZYwnrAwDte3YDyc
--7UqoHGIs031FuoK6vTdBEQKBgHG5bz3mOqKgGMDxFY6ihgzMcPc9FGzousaVhhAZ
--qPYyvWS7+9mImRb/dNlBBHY98B1jWz9rIxbcCIrpbGB05ucuiKltAoi45mrnmsA9
--23YHycUho7J6aDkskiClE4OkBD09iwqq3qoWwPnHjL/KDo5oJYEjZ+inPNE9gF/n
--o98bAoGBAMLZ7BYOXU1svCwuEz9RdAyXsrOX+Z9DW9i6WMVlfk9K1IxwpXYCvOjO
--J+wJuQtuNbwKqNPw1DUEp/25cDVoekRAxaKgYGlJFib8vEGtbQ7GQK9bDA11/sIz
--PQSfc92Y4+qpQ9WzhsZXip49itzBFgmN7/4eaohpvyHCFkVCZVpf
-+MIIEpgIBAAKCAQEAyB8axXEtiZEUG1yxaLG99rp1ZFbsB0j0reg6Zdo1EBz/23Hg
-+Mf3fcGh2H/K5WwhQCKHbmQznO1wiVInYHBuTXyyckKZJFjlPAhlh/iKZeABPGrmA
-+nMv9E+wUKmkQuNRz5qyRtQguNK6nGOO5VDtoWiPr4+U2RRzYQG0Wra0dYg9b3orN
-+oAWbazM3eCJabxBxr+oIX50nNtM2uHsZmqY6f7gACDl6XhV/EB7pgG7cuHXfoh6S
-+ow81K4RvUGub9vIotitQHG3M1EOxc0qdvxqEUoxflmOovOjfWdTPe9jxIMtCBuZe
-+iR7tT9P63dNITdIdDsM791eZXTC2Wqe/qVRUEwIDAQABAoIBAQCrFcxxV5yyqxEh
-+g1E4TBw3Ppj1u0n1wG1N7+ddA/uxVtl15hjhJEVNeEDkd0H3jVe+yYFPizR0DwRa
-+ea4D+Z84Eo+XKlH5ae0dwk2AUlwZt0npcwV9BvfJfF6RE1l0akzbvFSlC+VUrKu2
-+H5llZZSE24jjQCXxWAOYsKpeuE0ScsIvgKIW7i7sSKE8x8bRyEY6nF8ayfwLoDId
-+O1eIYM9bYt+y/K0MnZLuKxKRMXDiORSTu9ujR5NVmDkb4DJgVhkz8DcN9K9UV5FE
-+tRZzD13fOJS/RnKjoGCtJV4G8vzWvtqcaQaxxCCfYQS+XChqUExNxooOVQjlx+AE
-+HWrJ/oEhAoGBAPkrY5P6OfV7GOC5CxcI4wv955vf17rT85VSyqHRztiLv90IFi0B
-+snBjocJo466Xsi85QNkRHyW/DG0xuZ/lJyJyM79prOV0PXRlEr8loR3RT7OqK8KQ
-+nX4Ip7ELixT7Kspwh+p3S/Z2/9kR0XXJ8aJCb5Xz31YvswEew7Z7kbNHAoGBAM2b
-+gjw6BGzP9Ni9xTQKKK6NBimlsKqg/pnvEVSMb4lNNB/nPlVEzFUc5iFHX5luaaCr
-+dsaa7vOjUZ14aLQcuGTDrWKc82Vn2g6A+//TXbm0zWK5x1fctFdUxHPmBNiTO5xc
-++29cGv/laehyphkIfQsLsmnOeMvDkyNeX0L0JYbVAoGBAL4so5/5x+rYvTAni5NV
-+MRWiAPgzbJAn3S4HNqkzXVBhuVqWJXbMaMjnAjtDmyNSnKj2ZcxHCSLiIjXlUev8
-+FlZwG5borRGkGpOP4TMLIWGEs/RI2YVyowHi0TqLuOeWnB5OrS4DR3MheDzRILFq
-+JIbXdhtZOwio91LPjEjnH1lZAoGBAI5mnAa2cAYk6YGLvZ9TQeXSymfh17/1jSB0
-+EV6rfTxs+iL2d5d69MImJ8T4t99+Ny4OU08uUzzu6kHT+UB1e8heNiHMbk7XZJET
-+CHWgoJNUA8PSw5u4wjaSARX8Q3L0Vh7vzzzLX+/HplhVv3ArDt+tlD3vwH3v0GJ4
-+pCWtDqiZAoGBAMjf2InVEJsQD/uOFblpgzTxNXoWnYDA2udIpHOgcdw3+JhZzOXx
-+01WReomSBtuc0XStJdZKZbLuYgtG3XEJPA8rqS4SVm+M05XTCnDVkpENAZf14u8r
-+8dbPJUWzoVDkEuJespgixpJ18JAytDXvl5gzFp6Gr2O0Dd7arN/8IIP8
- -----END RSA PRIVATE KEY-----
-diff --git a/examples/puma/client-certs/client.crt b/examples/puma/client-certs/client.crt
-index bfb7f668f..9703ebdbd 100644
---- a/examples/puma/client-certs/client.crt
-+++ b/examples/puma/client-certs/client.crt
-@@ -1,19 +1,19 @@
- -----BEGIN CERTIFICATE-----
--MIIDAzCCAeugAwIBAgIBAzANBgkqhkiG9w0BAQUFADA4MRMwEQYKCZImiZPyLGQB
--GRYDbmV0MRQwEgYKCZImiZPyLGQBGRYEcHVtYTELMAkGA1UEAwwCY2EwIBcNMTQw
--MjAyMjAwODI3WhgPMjExNTAxMDkyMDA4MjdaMDwxEzARBgoJkiaJk/IsZAEZFgNu
--ZXQxFDASBgoJkiaJk/IsZAEZFgRwdW1hMQ8wDQYDVQQDDAZjbGllbnQwggEiMA0G
--CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGnFKNrNj9pvHIK+iUf1UoDJ0O7hpj
--jn7QWd65xnHWN9YF9RfBVRxg7HLcPls6GL4c+e5KQP1W0o4gSzwbUc3a/LyqkTEA
--dligEjXTkQY6tCn/51CuClynreQ98wdgQrayzobKhWMALG7IRLraprZmiQJpxWOF
--evd7WkF32AwSklZMEdWcLdI36swTV0UzuR9IDUnIh5GGPbikF/6hQ1E1+rL/sZkh
--czYNEniJGk2pD3MqJguTvYTF24k1KEOV5koSuAPnyl4E/dX9g3AIHWo8OhqVs/4P
--hrX6++qmrsVz9LIvPw3+SMAE3QU49J7uAANRQMBlxWhlbIpeFi8zNig7AgMBAAGj
--EjAQMA4GA1UdDwEB/wQEAwIEsDANBgkqhkiG9w0BAQUFAAOCAQEAtxbX3CfQgMwa
--CWYTjupyTC+KDajbkLLsNXw49PeTIj0FOjAdKA1zyEZcrxtaU+flJr8QHdI8HyZH
--hpofnOTSBg5k9y4Qz8gjI1Nsh0H8WU/d7F//2l2fUDOhVAb6JtTAKnMpU4snb0GD
--bxcO6QxfNh50Qdb7KoJH7baJ3aAnsRrLVGqQ7jH20iMu163j/pYw4dDskFMr65Le
--bMB3NeQ5pHwtYf2J5EliKCtH+Df/BTIl9u1vviZs84gA0Odai/YaMZWCqFiWqIax
--lkMHNSDWh2G++qMn9erLjRtYDAbIt3VhMncUpEBx3lBEIaVg7qyfpWQ4EkkkylH6
--WRv06vukVg==
-+MIIDBDCCAeygAwIBAgIBCzANBgkqhkiG9w0BAQsFADA4MRMwEQYKCZImiZPyLGQB
-+GRYDbmV0MRQwEgYKCZImiZPyLGQBGRYEcHVtYTELMAkGA1UEAwwCQ0EwHhcNMjAw
-+ODAxMDAwMDAwWhcNMjQwODAxMDAwMDAwWjA/MRMwEQYKCZImiZPyLGQBGRYDbmV0
-+MRQwEgYKCZImiZPyLGQBGRYEcHVtYTESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjAN
-+BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoywLJRT7wZM1P3Abg9NIT+NJ8TkS
-+IBz8ZgyyhSW1lU/tcsNEJakIl22XAeLEHfMknMzDqvU1G256hqM+/Tgohreat+yc
-+ofy+2OOu4un+44qIGX82i2PCt+afVvbGhPpHioyAJRDXZd9V4FtESH+6As7m+6MH
-+E4yX547E6XmmJ9lp8z9FnBMi1a6C01bI6mZhMuReLl2bS0FWjqrwNN3PpizBD+Vv
-+FbUIndC+UiD0kYPxTwSDCpEq/To0FrNCdAj94Y4oZVuvx8B1mHiqwkqmlOLUZslS
-+u7CFInqbswq5LnGFRIVSg3bu4bgCbCEmJhfqxp5MODT4VBXa2sCOnG7BBwIDAQAB
-+oxIwEDAOBgNVHQ8BAf8EBAMCBLAwDQYJKoZIhvcNAQELBQADggEBAApaKvnGiRqs
-+Vz4B06f/mDLmN7gb0e/evEypB2S06fp9f/oWWHXHCxpx9bKbiHFNNiinoc97/Spb
-+GzylHV/n9j8GEtZmJMiSJZubN8vpn1Jg0Usz3ZtAy0fe9ephjBIXPpwrsGF6Oz3u
-+U/b2zTpJX3oJ3Eq6Q9hLplYU3bNHfrw6PAbzbB91zVTFsqZUTctKrMRgp68FA4fw
-+VWQkb4QwLK1UVJIT/nR3v7nJDktgpR4mfdrtWbWxOGm/ed2oOilpqVhVN99P+bUn
-+3cFkQ6PSYK8En9jJhBMe/zQqpSyy09Tfi/Zy6nzZv0ah53bpeCFLZFi+0CU8HwPr
-+MuD1XQN72zg=
- -----END CERTIFICATE-----
-diff --git a/examples/puma/client-certs/client.key b/examples/puma/client-certs/client.key
-index a49704121..15820eed7 100644
---- a/examples/puma/client-certs/client.key
-+++ b/examples/puma/client-certs/client.key
-@@ -1,27 +1,27 @@
- -----BEGIN RSA PRIVATE KEY-----
--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
- -----END RSA PRIVATE KEY-----
-diff --git a/examples/puma/client-certs/client_expired.crt b/examples/puma/client-certs/client_expired.crt
-index d0accc885..cd20e0489 100644
---- a/examples/puma/client-certs/client_expired.crt
-+++ b/examples/puma/client-certs/client_expired.crt
-@@ -1,19 +1,19 @@
- -----BEGIN CERTIFICATE-----
--MIIDCTCCAfGgAwIBAgIBBDANBgkqhkiG9w0BAQUFADA4MRMwEQYKCZImiZPyLGQB
--GRYDbmV0MRQwEgYKCZImiZPyLGQBGRYEcHVtYTELMAkGA1UEAwwCY2EwHhcNMTQw
--MjAyMjAwODI3WhcNMTQwODA0MDgwODI3WjBEMRMwEQYKCZImiZPyLGQBGRYDbmV0
--MRQwEgYKCZImiZPyLGQBGRYEcHVtYTEXMBUGA1UEAwwOY2xpZW50LWV4cGlyZWQw
--ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZQSVfI4KNwus/+9gE9Rww
--+cehxzw80fNi4tmruSApitTIk1u1r1rYVexkBkVTtl6Fg/aNAAdsI4aATanyGj0m
--yRqEMxYMt8RtzAYHY6ZEJBm4WUAa44W7WNG2ZA/e0bCDq4Sn+hlPJw0e4iQimJqi
--8+iitgyTdicTKDR+9kTS3W/33PZqSwqqnN55m9n9A5FIKwd8fbPsO8k6xIhFS2sL
--KZ2TkAYLNXu2vFGJR7b37U8mYcHObB1p7U7WYJ2JCf21WZOC4iI25Xk7MFSUYPqb
--W/iV+41EcslbHwAZHEjqeNynKNlnZokVrviOFeFrHqXbVKp43027L3RZr/JXfxMl
--AgMBAAGjEjAQMA4GA1UdDwEB/wQEAwIEsDANBgkqhkiG9w0BAQUFAAOCAQEAdCLR
--jmHeQDrtl9w0cr8Vls+clhoWSDIEj2NC7PRUbDS5T0kAnF/N64n9RJFPS+4bpZaT
--c9v3DXzdaTTp7moUrwVc3EKVLV5EJcm+TcuUhbL2ZnRgFHggVaoePShBHkDJGLz9
--lR30KJnKsyFKEDEyD4rYtYvg98858EtkuxKLsD8efQ/9V8WDLAJJWTsJweEbEpIq
--GqblQnBeNrLZ7yS32NAM9jnB9wPsMXPZnAAV/o/U6TTwIO9ChApWX+qer1/mIoc7
--90/XhxEVw6EcXfGPnsLJ85n9FNGbWnLFRxvFAYcD0z6KQYxVHDiUAMSKqAkpENYO
--k3gVOw5YNxNpPmUrjw==
-+MIIDBDCCAeygAwIBAgIBFzANBgkqhkiG9w0BAQsFADA4MRMwEQYKCZImiZPyLGQB
-+GRYDbmV0MRQwEgYKCZImiZPyLGQBGRYEcHVtYTELMAkGA1UEAwwCQ0EwHhcNMTkw
-+ODAxMDAwMDAwWhcNMjAwODAxMDAwMDAwWjA/MRMwEQYKCZImiZPyLGQBGRYDbmV0
-+MRQwEgYKCZImiZPyLGQBGRYEcHVtYTESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjAN
-+BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoywLJRT7wZM1P3Abg9NIT+NJ8TkS
-+IBz8ZgyyhSW1lU/tcsNEJakIl22XAeLEHfMknMzDqvU1G256hqM+/Tgohreat+yc
-+ofy+2OOu4un+44qIGX82i2PCt+afVvbGhPpHioyAJRDXZd9V4FtESH+6As7m+6MH
-+E4yX547E6XmmJ9lp8z9FnBMi1a6C01bI6mZhMuReLl2bS0FWjqrwNN3PpizBD+Vv
-+FbUIndC+UiD0kYPxTwSDCpEq/To0FrNCdAj94Y4oZVuvx8B1mHiqwkqmlOLUZslS
-+u7CFInqbswq5LnGFRIVSg3bu4bgCbCEmJhfqxp5MODT4VBXa2sCOnG7BBwIDAQAB
-+oxIwEDAOBgNVHQ8BAf8EBAMCBLAwDQYJKoZIhvcNAQELBQADggEBAHDfDovSTCmM
-+sxDCfTGQUYwnvOohTP0hjUHB6BzNAPVKYoBiq064m/JoDFmOGGtF3CqhWqtE2psl
-+eOK8fA/QomyFaIAowhx8qrswMP7T/rRldAG+9QHBYZGkPtbB8evK6XqrMEQTf2Ux
-+FlN3p7BZl9rhtuManMb+Wud3HfLYjXn2nTRvkOTi93MP05Vrho8KegZ9Kj4wY1rK
-+gOnkbI6bv+1r9yjsZuUKPH/OjFkpmAoOab5hX5R5CmEefGAet2KPCNrApuwfvRHT
-+x9jVwtOYBHq3DVcBDBu+O38L+WlKGeXvUK4AzvxQaVUysCG3DA1zrvyI3Y8Jy2Jk
-+KfmWZWlvXlM=
- -----END CERTIFICATE-----
-diff --git a/examples/puma/client-certs/client_expired.key b/examples/puma/client-certs/client_expired.key
-index eadc5e8a8..15820eed7 100644
---- a/examples/puma/client-certs/client_expired.key
-+++ b/examples/puma/client-certs/client_expired.key
-@@ -1,27 +1,27 @@
- -----BEGIN RSA PRIVATE KEY-----
--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
- -----END RSA PRIVATE KEY-----
-diff --git a/examples/puma/client-certs/client_unknown.crt b/examples/puma/client-certs/client_unknown.crt
-index 359e33d6c..8cdfc87bb 100644
---- a/examples/puma/client-certs/client_unknown.crt
-+++ b/examples/puma/client-certs/client_unknown.crt
-@@ -1,19 +1,19 @@
- -----BEGIN CERTIFICATE-----
--MIIDEzCCAfugAwIBAgIBAjANBgkqhkiG9w0BAQUFADBAMRMwEQYKCZImiZPyLGQB
--GRYDbmV0MRQwEgYKCZImiZPyLGQBGRYEcHVtYTETMBEGA1UEAwwKY2EtdW5rbm93
--bjAgFw0xNDAyMDIyMDA4MjdaGA8yMTE1MDEwOTIwMDgyN1owRDETMBEGCgmSJomT
--8ixkARkWA25ldDEUMBIGCgmSJomT8ixkARkWBHB1bWExFzAVBgNVBAMMDmNsaWVu
--dC11bmtub3duMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0Ewf7nWJ
--WcHI3NB+gjz5jWnpNwnU47hjIWq+S41iIymN7FsNdssfzeGb3ZElcQAfofvNf75F
--6mE7YEpbKRU7t/Nptvx+Rd1YGOS2N/PWdj3IcJgvQ2guiU0aYkdB7lC1vlI0QzHT
--dte9pGK/ZPp/mvRZGwi9WmwlNhBwOzvdyRuLyi63dmZ8vgyZrfbmGhZYdhCZ77Uv
--i+VYqYv5X30I2gQkV6YQMj/AF5Fmt9a4TNGfIjXb6FKmNhlsDMduovrfQMh2umMK
--YYQ4A+Vi2yMAZkKeD5cogGLS8wmg76n7miPaKLVU9xTEf55IO+HjIBIqz6VG8qbg
--iBV4Lr6BkkaKTQIDAQABoxIwEDAOBgNVHQ8BAf8EBAMCBLAwDQYJKoZIhvcNAQEF
--BQADggEBAGGaA7fZLOqxx1wIIay0Ewni3ljzR+RAlpTHAh4x+NilcaQ2ils+JoGH
--/DCdX2iD5nevGVm1DANBhfAuFxXGGBjoOLqtg/sO7Rk51IV9WjDVB2rGeH3hoTCk
--Qi6Bazdlcvvs3SyFEKcJm2zXizR7O9I+tDv++F6bbaHSBWB6tB9g93pZuMR+smvR
--Ll2+/jRGPe1Pif1UFs5DR8QshpvxrIwCmO1vznLhDeA5Pde6CtahGJvi1Y25L1h0
--9l0LjMxxqgVh8h4A5AR8VufCcDiaT8lzCkz4G4jQYFhrJXmBn8Em6NZfdP/LmM9I
--0zEB2Y3lp32ng+WMyaqNh6nfpxEfBoY=
-+MIIDBTCCAe2gAwIBAgIBEzANBgkqhkiG9w0BAQsFADA5MRMwEQYKCZImiZPyLGQB
-+GRYDbmV0MRQwEgYKCZImiZPyLGQBGRYEcHVtYTEMMAoGA1UEAwwDQ0FVMB4XDTIw
-+MDgwMTAwMDAwMFoXDTI0MDgwMTAwMDAwMFowPzETMBEGCgmSJomT8ixkARkWA25l
-+dDEUMBIGCgmSJomT8ixkARkWBHB1bWExEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIw
-+DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKQo9ve3XI5fiKE5AKI3Qm7aeGwy
-+uIR5RBo58Na4saBSfCaKZvNwzuEimKN6S4ShUlV0egKwCs/KvzbhQJpIxVsLQCGs
-+AQDxdOGP1FyizQvzDhzL7BC2I/Dp3A5V6uXkxo1qTqoBdTYeJ/mdIVgZ7bgTnUdu
-+uY9KErU/ugR8MbqZyQel/04PSmkCTdhzP41w0xvmc7Jgab0vJ0oXU4knXIyKsLeq
-+BkL6fevPW4fdaU+ppXBvpsgWfACk/WZs+DyhPndcX7JNrcnYIIAJy75wivqw2RDB
-+m59XNhoDwbR21EkcZnlQL59pv4ASA7DrJs+tFoGqsCs7DyEioePNp6ZraSkCAwEA
-+AaMSMBAwDgYDVR0PAQH/BAQDAgSwMA0GCSqGSIb3DQEBCwUAA4IBAQBMbPmIekCi
-+TMLtclXtkhKUefb9hoALhABwRbTbzPjz+MGJX2BMwLt8bAs6AMY8jEazvfm9+G0m
-+1liBAGWFojSzAykNIq/zAG2tgDVolQp3x4JcyFDJ0cuR8DIdll2CCnLM2jP8Nek8
-+wSyuWDsm1U5kmos/dP/ialCvvCLHULoSCBhsyBFKmH2ViXdW09Wg4jSQ4RIToBBn
-+w/VbObeKA8NBUW6/7w6MS1oeFL3PlZJ205zVrZ68nqm/ckYyaBAdlQNTmlThNSQ5
-+eL7w2QgfYDM72Sk4/rjZsW0kH+V0ZqmIuyVBE6jo5EulGPLo2eQEfPmhEdbo5rFi
-+foV+QKM8z3K0
- -----END CERTIFICATE-----
-diff --git a/examples/puma/client-certs/client_unknown.key b/examples/puma/client-certs/client_unknown.key
-index 82825f77a..96b41acf9 100644
---- a/examples/puma/client-certs/client_unknown.key
-+++ b/examples/puma/client-certs/client_unknown.key
-@@ -1,27 +1,27 @@
- -----BEGIN RSA PRIVATE KEY-----
--MIIEpAIBAAKCAQEA0Ewf7nWJWcHI3NB+gjz5jWnpNwnU47hjIWq+S41iIymN7FsN
--dssfzeGb3ZElcQAfofvNf75F6mE7YEpbKRU7t/Nptvx+Rd1YGOS2N/PWdj3IcJgv
--Q2guiU0aYkdB7lC1vlI0QzHTdte9pGK/ZPp/mvRZGwi9WmwlNhBwOzvdyRuLyi63
--dmZ8vgyZrfbmGhZYdhCZ77Uvi+VYqYv5X30I2gQkV6YQMj/AF5Fmt9a4TNGfIjXb
--6FKmNhlsDMduovrfQMh2umMKYYQ4A+Vi2yMAZkKeD5cogGLS8wmg76n7miPaKLVU
--9xTEf55IO+HjIBIqz6VG8qbgiBV4Lr6BkkaKTQIDAQABAoIBAC41pSPWqWjjJ7ds
--/ZPRCR/JLjbKlJMMVdmU/7BtJidc0aJstLj06RJYiaaGy8Kc32elH/rF8GbFuVFs
--TXr4ve3aL0qsCytepmunWZFiI+LJZA0uhdWzaBeHpmHFIyhGeXtGa1e41wvXYrf0
--PDefpu1uZdIshy1nLn4m+W76ogI6FrcyUQ+XRN6f5x6af70Kfi414qf9NLOvajnl
--JCx90WpdwBp1jC8totKDp9kvILCymFnGBl93NUl8F3Tz7zLkh2SIhaKxQIHTc9g0
--LPNkd1Q5tIl/rG3lZ6vw2/UlCVB1NdLsItlJVIJhu6ChIrSXeoDg0GNlJFp7op6W
--jlJDoRUCgYEA67Nuzrv/lkVljRFDVw97DTiCbLL7SDXDH6Jf43+Bz6prGLqd4Nfd
--LTO7AdLGd5UTWB1Oj2U94pFXNFkucGv65ck6QAPZ4UrCk9lyjx/dN7d6CxUBDeu2
--4zPeHy/mAgkVmKSzEy5L2ERwoQqK8A/g6HtuThB87gtKUpnG+QSfz6sCgYEA4jyE
--kPRudqne0VXWL/Mhnrls2PNo4MDIOxUp+KcFLGY/44RIEoit3WLRDXULAgT3U20Z
--lY7nQJyU+/CaEH6rIpADp6VRPA0XJo7HCuMGEO7bk8AAXkXTplVs+XbsD0221AKl
--GRpS0CtcvHllHiwG8iL+zHAJzL4wbNY36L97decCgYB0UuHk9bN2Hlm3/UUWunUo
--WTNFIjARuzbJbgGU7WDLdHfWhINWbDKkFFu+0p9QdSpO2mfjLTwVjVVUaI8avK/e
--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
- -----END RSA PRIVATE KEY-----
-diff --git a/examples/puma/client-certs/generate.rb b/examples/puma/client-certs/generate.rb
-deleted file mode 100644
-index 3542057e2..000000000
---- a/examples/puma/client-certs/generate.rb
-+++ /dev/null
-@@ -1,78 +0,0 @@
--require "bundler/setup"
--require "puma"
--require "puma/minissl"
--
--case ARGV[0]
--
--when "s"
--
-- app = proc {|env|
-- p env['puma.peercert']
-- [200, {}, [ env['puma.peercert'] ]]
-- }
-- events = Puma::Events.new($stdout, $stderr)
-- server = Puma::Server.new(app, events)
--
-- context = Puma::MiniSSL::Context.new
-- context.key = "certs/server.key"
-- context.cert = "certs/server.crt"
-- context.ca = "certs/ca.crt"
-- #context.verify_mode = Puma::MiniSSL::VERIFY_NONE
-- #context.verify_mode = Puma::MiniSSL::VERIFY_PEER
-- context.verify_mode = Puma::MiniSSL::VERIFY_PEER | Puma::MiniSSL::VERIFY_FAIL_IF_NO_PEER_CERT
--
-- server.add_ssl_listener("127.0.0.1", 4000, context)
--
-- server.run
-- sleep
-- #server.stop(true)
--
--when "g"
--
-- def issue_cert(dn, key, serial, not_before, not_after, extensions, issuer, issuer_key, digest)
-- cert = OpenSSL::X509::Certificate.new
-- issuer = cert unless issuer
-- issuer_key = key unless issuer_key
-- cert.version = 2
-- cert.serial = serial
-- cert.subject = dn
-- cert.issuer = issuer.subject
-- cert.public_key = key.public_key
-- cert.not_before = not_before
-- cert.not_after = not_after
-- ef = OpenSSL::X509::ExtensionFactory.new
-- ef.subject_certificate = cert
-- ef.issuer_certificate = issuer
-- extensions.each {|oid, value, critical|
-- cert.add_extension(ef.create_extension(oid, value, critical))
-- }
-- cert.sign(issuer_key, digest)
-- cert
-- end
--
-- @ca_key = OpenSSL::PKey::RSA.generate(2048)
-- @svr_key = OpenSSL::PKey::RSA.generate(2048)
-- @cli_key = OpenSSL::PKey::RSA.generate(2048)
-- @ca = OpenSSL::X509::Name.parse("/DC=net/DC=client-cbhq/CN=CA")
-- @svr = OpenSSL::X509::Name.parse("/DC=net/DC=client-cbhq/CN=localhost")
-- @cli = OpenSSL::X509::Name.parse("/DC=net/DC=client-cbhq/CN=localhost")
-- now = Time.at(Time.now.to_i)
-- ca_exts = [
-- ["basicConstraints","CA:TRUE",true],
-- ["keyUsage","cRLSign,keyCertSign",true],
-- ]
-- ee_exts = [
-- #["keyUsage","keyEncipherment,digitalSignature",true],
-- ["keyUsage","keyEncipherment,dataEncipherment,digitalSignature",true],
-- ]
-- @ca_cert = issue_cert(@ca, @ca_key, 1, now, now+3600_000, ca_exts, nil, nil, OpenSSL::Digest::SHA1.new)
-- @svr_cert = issue_cert(@svr, @svr_key, 2, now, now+1800_000, ee_exts, @ca_cert, @ca_key, OpenSSL::Digest::SHA1.new)
-- @cli_cert = issue_cert(@cli, @cli_key, 3, now, now+1800_000, ee_exts, @ca_cert, @ca_key, OpenSSL::Digest::SHA1.new)
--
-- File.open("ca.crt","wb") {|f| f.print @ca_cert.to_pem }
-- File.open("ca.key","wb") {|f| f.print @ca_key.to_pem }
-- File.open("server.crt","wb") {|f| f.print @svr_cert.to_pem }
-- File.open("server.key","wb") {|f| f.print @svr_key.to_pem }
-- File.open("client1.crt","wb") {|f| f.print @cli_cert.to_pem }
-- File.open("client1.key","wb") {|f| f.print @cli_key.to_pem }
--end
-diff --git a/examples/puma/client-certs/generate_client_test.rb b/examples/puma/client-certs/generate_client_test.rb
-new file mode 100644
-index 000000000..da1b56a91
---- /dev/null
-+++ b/examples/puma/client-certs/generate_client_test.rb
-@@ -0,0 +1,133 @@
-+# frozen_string_literal: false
-+
-+=begin
-+run code to generate all certs
-+certs before date will be the first of the current month
-+expire in four years
-+
-+JRuby:
-+see https://github.com/puma/puma/commit/4ae0de4f4cc
-+after running this Ruby code, delete keystore.jks and server.p12, then
-+cd examples/puma/client-certs
-+openssl pkcs12 -chain -CAfile ./ca.crt -export -password pass:jruby_puma -inkey server.key -in server.crt -name server -out server.p12
-+keytool -importkeystore -srckeystore server.p12 -srcstoretype pkcs12 -srcstorepass jruby_puma -destkeystore keystore.jks -deststoretype JKS -storepass jruby_puma
-+keytool -importcert -alias ca -noprompt -trustcacerts -file ca.crt -keystore keystore.jks -storepass jruby_puma
-+=end
-+
-+require "openssl"
-+
-+module Generate
-+
-+ KEY_LEN = 2048
-+ SIGN_ALGORITHM = OpenSSL::Digest::SHA256
-+
-+ CA_EXTS = [
-+ ["basicConstraints","CA:TRUE",true],
-+ ["keyUsage","cRLSign,keyCertSign",true],
-+ ]
-+ EE_EXTS = [
-+ #["keyUsage","keyEncipherment,digitalSignature",true],
-+ ["keyUsage","keyEncipherment,dataEncipherment,digitalSignature",true],
-+ ]
-+
-+ class << self
-+ def run
-+ set_dates
-+ output_info
-+ setup_issue
-+ write_files
-+ end
-+
-+ private
-+
-+ def setup_issue
-+ ca = OpenSSL::X509::Name.parse "/DC=net/DC=puma/CN=CA"
-+ ca_u = OpenSSL::X509::Name.parse "/DC=net/DC=puma/CN=CAU"
-+ svr = OpenSSL::X509::Name.parse "/DC=net/DC=puma/CN=localhost"
-+ cli = OpenSSL::X509::Name.parse "/DC=net/DC=puma/CN=localhost"
-+ cli_u = OpenSSL::X509::Name.parse "/DC=net/DC=puma/CN=localhost"
-+
-+ [:@ca_key, :@svr_key, :@cli_key, :@ca_key_u, :@cli_key_u].each do |k|
-+ instance_variable_set k, OpenSSL::PKey::RSA.generate(KEY_LEN)
-+ end
-+
-+ @ca_cert = issue_cert ca , @ca_key , 3, @before, @after, CA_EXTS, nil , nil , SIGN_ALGORITHM.new
-+ @svr_cert = issue_cert svr, @svr_key, 7, @before, @after, EE_EXTS, @ca_cert, @ca_key, SIGN_ALGORITHM.new
-+ @cli_cert = issue_cert cli, @cli_key, 11, @before, @after, EE_EXTS, @ca_cert, @ca_key, SIGN_ALGORITHM.new
-+
-+ # unknown certs
-+ @ca_cert_u = issue_cert ca_u , @ca_key_u , 17, @before, @after, CA_EXTS, nil , nil , SIGN_ALGORITHM.new
-+ @cli_cert_u = issue_cert cli_u, @cli_key_u, 19, @before, @after, EE_EXTS, @ca_cert_u, @ca_key_u, SIGN_ALGORITHM.new
-+
-+ # expired cert is identical to client cert with different dates
-+ @cli_cert_exp = issue_cert cli, @cli_key, 23, @b_exp, @a_exp, EE_EXTS, @ca_cert, @ca_key, SIGN_ALGORITHM.new
-+ end
-+
-+ def issue_cert(dn, key, serial, not_before, not_after, extensions, issuer, issuer_key, digest)
-+ cert = OpenSSL::X509::Certificate.new
-+ issuer = cert unless issuer
-+ issuer_key = key unless issuer_key
-+ cert.version = 2
-+ cert.serial = serial
-+ cert.subject = dn
-+ cert.issuer = issuer.subject
-+ cert.public_key = key.public_key
-+ cert.not_before = not_before
-+ cert.not_after = not_after
-+ ef = OpenSSL::X509::ExtensionFactory.new
-+ ef.subject_certificate = cert
-+ ef.issuer_certificate = issuer
-+ extensions.each {|oid, value, critical|
-+ cert.add_extension(ef.create_extension(oid, value, critical))
-+ }
-+ cert.sign(issuer_key, digest)
-+ cert
-+ end
-+
-+ def write_files
-+ Dir.chdir __dir__ do
-+ File.write "ca.crt" , @ca_cert.to_pem , mode: 'wb'
-+ File.write "ca.key" , @ca_key.to_pem , mode: 'wb'
-+ File.write "server.crt", @svr_cert.to_pem, mode: 'wb'
-+ File.write "server.key", @svr_key.to_pem , mode: 'wb'
-+ File.write "client.crt", @cli_cert.to_pem, mode: 'wb'
-+ File.write "client.key", @cli_key.to_pem , mode: 'wb'
-+
-+ File.write "unknown_ca.crt", @ca_cert_u.to_pem, mode: 'wb'
-+ File.write "unknown_ca.key", @ca_key_u.to_pem , mode: 'wb'
-+
-+ File.write "client_unknown.crt", @cli_cert_u.to_pem, mode: 'wb'
-+ File.write "client_unknown.key", @cli_key_u.to_pem , mode: 'wb'
-+
-+ File.write "client_expired.crt", @cli_cert_exp.to_pem, mode: 'wb'
-+ File.write "client_expired.key", @cli_key.to_pem , mode: 'wb'
-+ end
-+ end
-+
-+ def set_dates
-+ now = Time.now.utc
-+ mo = now.month
-+ yr = now.year
-+ zone = '+00:00'
-+
-+ @before = Time.new yr , mo, 1, 0, 0, 0, zone
-+ @after = Time.new yr+4, mo, 1, 0, 0, 0, zone
-+
-+ @b_exp = Time.new yr-1, mo, 1, 0, 0, 0, zone
-+ @a_exp = Time.new yr , mo, 1, 0, 0, 0, zone
-+ end
-+
-+ def output_info
-+ puts ""
-+ puts " Key length: #{KEY_LEN}"
-+ puts "sign_algorithm: #{SIGN_ALGORITHM}"
-+ puts ""
-+ puts "Normal cert dates: #{@before} to #{@after}"
-+ puts ""
-+ puts "Expired cert dates: #{@b_exp} to #{@a_exp}"
-+ puts ""
-+ end
-+ end
-+end
-+
-+Generate.run
-diff --git a/examples/puma/client-certs/keystore.jks b/examples/puma/client-certs/keystore.jks
-index 6d734fadce1949b3b47e36b62749ca612fbaddf6..17654b4adbdde88929f2476da21ff50ef2899d0d 100644
-GIT binary patch
-literal 3740
-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
-A9RL6T
-
-literal 3743
-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
-E4T{|^s{jB1
-
-diff --git a/examples/puma/client-certs/run_server_with_certs.rb b/examples/puma/client-certs/run_server_with_certs.rb
-new file mode 100644
-index 000000000..6df57b678
---- /dev/null
-+++ b/examples/puma/client-certs/run_server_with_certs.rb
-@@ -0,0 +1,26 @@
-+require "bundler/setup"
-+require "puma"
-+require "puma/detect"
-+require "puma/puma_http11"
-+require "puma/minissl"
-+
-+app = proc {|env|
-+ p env['puma.peercert']
-+ [200, {}, [ env['puma.peercert'] ]]
-+}
-+events = Puma::Events.new($stdout, $stderr)
-+server = Puma::Server.new(app, events)
-+
-+context = Puma::MiniSSL::Context.new
-+context.key = "certs/server.key"
-+context.cert = "certs/server.crt"
-+context.ca = "certs/ca.crt"
-+#context.verify_mode = Puma::MiniSSL::VERIFY_NONE
-+#context.verify_mode = Puma::MiniSSL::VERIFY_PEER
-+context.verify_mode = Puma::MiniSSL::VERIFY_PEER | Puma::MiniSSL::VERIFY_FAIL_IF_NO_PEER_CERT
-+
-+server.add_ssl_listener("127.0.0.1", 4000, context)
-+
-+server.run
-+sleep
-+#server.stop(true)
-diff --git a/examples/puma/client-certs/server.crt b/examples/puma/client-certs/server.crt
-index 7fb2f9b8f..5c3c334ed 100644
---- a/examples/puma/client-certs/server.crt
-+++ b/examples/puma/client-certs/server.crt
-@@ -1,19 +1,19 @@
- -----BEGIN CERTIFICATE-----
--MIIDBjCCAe6gAwIBAgIBAjANBgkqhkiG9w0BAQUFADA4MRMwEQYKCZImiZPyLGQB
--GRYDbmV0MRQwEgYKCZImiZPyLGQBGRYEcHVtYTELMAkGA1UEAwwCY2EwIBcNMTQw
--MjAyMjAwODI3WhgPMjExNTAxMDkyMDA4MjdaMD8xEzARBgoJkiaJk/IsZAEZFgNu
--ZXQxFDASBgoJkiaJk/IsZAEZFgRwdW1hMRIwEAYDVQQDDAkxMjcuMC4wLjEwggEi
--MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDK2ioejidqPJzhGgYh9Nc/CD8g
--n/vFqchULvmG796R01Rx0Xk5v7OgWs4GMhvJ8o4soCxTmACyPStdemDlocdzZf2d
--yfv1alVVfBBwqSsiekiB7IiSvpyg5t3h8XqWJcKtP00tPEYmAkVuMbVSxQPrsEi5
--47kxu7zyiV0RavaZbODgxkupSjEr0DHa1h7pkip53ekz/rnoceVcvSnCdOahUVj6
--ZwMkOQtay/b6746ttbfQh1ygbqTbV/lcV9erldlDkqKG0gQ6gxaBcbIiom1p+ohu
--CcoTDGZu431KOU6ZygbGxaIEZY9Zbyg9Dp+o6Zyyd7UTY/0JcCWUq7O/XaN5AgMB
--AAGjEjAQMA4GA1UdDwEB/wQEAwIEsDANBgkqhkiG9w0BAQUFAAOCAQEAIfMqanJJ
--aVD6XuS3aj0I31L4RiPSfKhkPiuO+lqBGzZhUEKwnEqVWLosFF1SK8Inbu1c1uyP
--zRb0tB4nSO01L8Oc5kTfuN9lr3nNaWDpGksa/S5e9WndQk95XF3FLt7FJii8wWnM
--9xGW27lurskbpuZc1M7IkD5W90y2fF19qB8fY8B2RGovPJEsDKSZ7pwSozijGR4Q
--2iIY4Lk9/vYxEYMRixE2+exYiKTNfaPt+CgxHxXksn0LvbYYQTxUmDgvSxXdrnCc
--4Kb1BbxOmB8XF17aJuRdUJxDxlnQK5LpoUWGfW7jFPbfX4d3nzpxjPaxvr3peRQV
--DNtRoD9mFvocbQ==
-+MIIDBDCCAeygAwIBAgIBBzANBgkqhkiG9w0BAQsFADA4MRMwEQYKCZImiZPyLGQB
-+GRYDbmV0MRQwEgYKCZImiZPyLGQBGRYEcHVtYTELMAkGA1UEAwwCQ0EwHhcNMjAw
-+ODAxMDAwMDAwWhcNMjQwODAxMDAwMDAwWjA/MRMwEQYKCZImiZPyLGQBGRYDbmV0
-+MRQwEgYKCZImiZPyLGQBGRYEcHVtYTESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjAN
-+BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvXOg3gTrGJfVft9cSrfGRnEZezDB
-+L93fcLwJAoaXGxbEg1RW/fOrSpSNemuqOvbzczV7m5eYTf1lHPBJsndbYyijIR1+
-+Fp4tjFDp76SC3hxCIc3uYXIz0qQwSOAi1z15zobS4xF29jlsXWtfBl9fivjzdj/f
-+pbZ+JPYOrlcJAf6Xmr3xh//13rOI0ytBMlWf51z/iAZBLm2wvbt+nR7B6koAdTgM
-+Coe+gOtcLWYY5ApJ4qB9knGdxWoF5p7guHHw2aGTM0jyhgBowfVkFRiE2JUmODae
-+g+dHsd8ogWbqhGyZTredJF/NRrLKU0h+t7ldKHvXEZy4qyqQlvKoTpODqQIDAQAB
-+oxIwEDAOBgNVHQ8BAf8EBAMCBLAwDQYJKoZIhvcNAQELBQADggEBAI/bcQP4Hu9O
-+OtaaIjVxN8+9jXUOrMpSogmZ4bRKImispt9SA+sbxec7iOMM2pG3Py2yi0hWGzii
-+hSebWIsM1JuPj7ks9l8nGRxpGeInJwTkJorG4ZLEypoS2wW3fQZGx3o4da5V+U2Z
-+HEY0wQTbPBqqnyeZ16ZFNVCzw8y9l7y7CEFjvUO3sq0pne9r7Z+XVgjGyBdBYkJS
-+0kcqPBXFCMHrWH5UlacYlM5cqgoVztOp2STGmR3XR7a34oueeA10QSP+jzeYvWA1
-+wTYA762uU2ReCdujfNbf8V1tZWAH36KldM3hhDNWeveAGxxj1h2R9T/k2kHl/a7D
-+I3VdS59vjJY=
- -----END CERTIFICATE-----
-diff --git a/examples/puma/client-certs/server.key b/examples/puma/client-certs/server.key
-index c1c031430..75a358ff5 100644
---- a/examples/puma/client-certs/server.key
-+++ b/examples/puma/client-certs/server.key
-@@ -1,27 +1,27 @@
- -----BEGIN RSA PRIVATE KEY-----
--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
- -----END RSA PRIVATE KEY-----
-diff --git a/examples/puma/client-certs/server.p12 b/examples/puma/client-certs/server.p12
-index 6fb6ba6046db3096a51886b7d7c8d68c4367d0eb..6ac4d590e48c8f282f09ede85d9442789ab97822 100644
-GIT binary patch
-delta 3160
-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
-
-delta 3168
-zcmV-m44?DD8Oj+zFoF!m0s#Xsf((oX2`Yw2hW8Bt2LYgh41ENG40$ku40SMq2M-1b
-zDuzgg_YDCD2B3lm05F0E`~m?0FoFj4kw6`Peg;UfOd86m0s;sCfPx0dIXLWfJ@O*Q
-zXOr@cX{7|S&v}-fxF{`82>h~a+opZxf(`vsADK%+>{@O7h+TGwR<jB2zY`f@+T3dL
-z9a80;Vx6xgDik}yrEb#>F4B4+STMBiQu@fIzn>9Aj*YH4xZ=b=MCFDbD7o+FyzPa5
-zRCP?a=A(B`d#dl4!9+LNAV+a%nWm;SA*TQpu$gnlJ<W;-LBzA0+dOdWh0Qy#5Tzw5
-z44AbOusVCWYiT5}IdlK=@G2JIeT&LI$IB^NS<&9FF+Dv?_Fi)^zMy8VRTTyYj1d|_
-zRGg(Ffl=7N?kMgA8s%|s%=f^e3?<%w?c+4Hd5z+P^pACjk#jsrYw1cOF+C=HWWkI>
-zIg&H@r5r#eecv=0IV`Yg1X>?}BxvJv3B7Zg#9;j{AG%kIPAe^mL{yMP$cW@Tr-!+1
-zT6T)Bt^3HC%wbExc=Vi>z;hs}ql03H9k8oRWK@zYKyCEndZxmq_Z{ekxZYoX7QElH
-zx!_MjgoOO*Oh<^vYJYxt%<-UFPBJmDJNYtYLiV6g)d1Jwice2xbXyb^*#ibX-FXL~
-zn~<UO6I3ZR5`Eb^_m==Xs0wo`$O0lPL^tR|MM1)9vfM)~f^tefP8%OJ!6T4vlzTO~
-zSdnqPLOU1n<jJ=0l=zCH&$^#~n>qU?0d`#jQ1FHR1Q2oy1nYN#IqmqB(E%n}I|?=Z
-zwzROB*0hMDL#&n{19JJ2-;L6-N7kCuNu!)2yaiPm4`0FR|E+Sn;Ds6*fBKMXPZ&Ta
-z4^`nC2VX@J`;p}+Al2nSjMIPY<O(h*ykSHEv_2cM(O<oVi>&5)GDn4fSRH0^*RFtI
-z@px8`3p<FLu95F^?4Y&UVO*O}{eI=+1yOfTduK2rb<i`j2r9^m-D%V!<En@#FaWC+
-zK1ajKqWKr#gzg5_`omZ03?^YSj@lCvjq|Cgy}rOjrQH=S3e2n3vOiPMp6|U2y7teS
-zy@Q*VHEf;=c{~elv3AUVJp>O%I$i?h@_r#zlMJE*ML5t+-BBVF=T~+yg9-q%Cv*|1
-zx#egDjJ&kiaSbQJzPo&!)D#0XPq^lw7l5g@bu_mmCADO6nG78D6VqSH8<6o^933n=
-zv#c~jj5)R*;?Kir?(q6}g06RN+jJqS$#2z{znyiY={Hj|cI7dD^i>LS9^#<>caqs?
-zkK-cmwAs1-*c!IWs{8~LappfOOZIV3U?GS(vni9A!QypSbusxTE$f_ew1W72Q>%j>
-z*(%*G=7@E{jU5C2ZJk{Yz4U;ac12_C{<N6k{kov57__WevCu)-POrdi4SDC3w2ia=
-z+Q`olLlC;r@TOjWiEOyNhuS{MVdMrKc1ZyiqBjZ{X_rJDkPNM)0wz|4uo-f@Ao7e;
-zqr|Fx0Ez3BX3kt;5N;p+T?gShE(esA<Y#m_rqpoDvEBP^k!Q~=uAn!ZCk94vs_o%{
-zmd5L=eTWPdhk{hp6egA+cCbaY+z;@HXtHA9o1l<beLeVpgOrNJtxOGLA7<mp_g){U
-zVn0axafCqVjWgcVZTPmIfbjg|=}WiJf~z-oG?JnRwDP`V`&O>Ei53gmkNdh{Nm0s}
-zg$74_1;6f&%B@QQJW66|c>mI(`xm`7#uZJ|LC6mcG+mI2Lx;2*H3!*(Xuo*Sv}B3d
-zczeo2<ZH8kWY_yF2%nQRb^MBO$!Qet51ZDj4S~j`g2y+H&r3+}GF~xGVRj&NWbER*
-z!_fkH@n%8ZmZ_~Vy<%vXhi+`5;R`m|p5&ky=u|@(=3n~0R;=tMk@#U;D1+7m;tS97
-zE=QY9g7G-fYGR7o{nKQ-EXX_=e|6o@BQ3h`02L5_jkd9>#J*dy;#H9hEtNP)FFpHW
-zS6wRdog8FzwtuU}V3%$xaLDAlHPYr``!s&B70yGDh@(+$pjA{6WZ{)D<b%-A7rSd+
-zLW6RFas@3S9XJiL(V-k44F>|+O-AqTtrbut#Otmy|6c$nN6k1X8WhZnJo})9)5=jC
-z&<`SiTfE~mzIg?vv8;0t0|4+IAUlQ3KMX<It9ZmP+tj%<y36$1EffSXaL9Bh`bi4d
-zA6D%4cBgPc5mSa<QwQL*<bGbSD<RD5d-^b~>ukD}_~=i#1M{kVh7h;l?W`7s2svb0
-zfZH<`a44JrGi3TDlas<cY{CNLI%kq%ZO8a!+SCa1?5OEcOIsLnV?mj@&0RX|*2>Db
-zBNYckPoG%qsuL9DNx72;><h{Gp1xP`H%RlV)5u^Ytr9S{8r|bSc>XSTBTM3n+ZA=N
-z_MT%5mRaWW`~=@*8!BXZD@FU+atG;L|C22TMt?zbJq7q2(?J3P2ml0v1jr_owoLE{
-zK_KhViOy*rw%picJs63|UrmgQbZ@jOOQhdE?dQl#!8RGCDJ2T^T`3HG6~SmxWko?c
-zsLqeZ3h~p+5lV2%*<x-BsYNL&m<LLzss>h>ZWhSGpOB)CAVAlHX0<GRWanN2ad=T9
-zAAboSFXPLYw<bJ-Pki<RVgDkg1bDf;#HO|K3UPf4K|(?NM#-fVu{!`f5bri9;2V*-
-zRLEe&c3j+D$#{@GW`<tmsNz!a7x%*i_%)n3G3J0DljL%mQYNM!FhEEai5n%217`zO
-zkgMQ1Rf71i$P4K(1l&nb*BFF5(rdSTZ+{FkHScTN9ii9JvB<hUW{PM1j|pfkdpz};
-zkn)3#&9pFHRFv~Q2pz)MVM$<rP}bMkJ`{egkLw~g&d!@m30GVa3^kqfwMwroBo^zO
-zhBt26PI4udyVX!n(MshnC#!vAl$6Q4B|Zu;YY8!JwfOxm{2SFTCxF-tI2TuI;(vxT
-zm-$}$B7@gdk;iNhD@<0r*2FY@$$d6c&^3vYy(V@FrRr7u=tV|fu;hC;w+bn8%dZhV
-zFDg3e`xBv=6?L}frW_ccaZP8G;vxL*V5`9&)U{6i<IBm~fQo!6vsY~8YH$>#5&+Rn
-z>Co6;Pyj|9S#rp|k17|=m8lrL0e^N?X8si0m@q-b(aRimCDFObJ%iDX7I@r1H&%6+
-zLFQC%<{@nN0^W+!>qTu*ekigE=4L5)>>zZTuF-b%5V531bDEzGD>(8T6vB$6#32`&
-z0la&A>B2=6L{o%`Pbm4NkGKS@%SeQlQ51o!LBC6T!$`Q7C#FmE|DhQGa(`z$$--r^
-z9R?@RDPxKQDy~0IkXb#m+$!jE=4E}mK`$x8!=~id&<5$tU{AFol>h39Jjb0u;ao=G
-zv>02xr_1*0^TPco_9i07w@p*GUXweV&%@E^YsGGNi{=)I(%usO7>F|}R_J^m(#Gw4
-z@|!V)bGa{arDrn!+V{a;HGe1VQ<fNN9%la}uDRfGRbBSpg|&C|fcj)zNDOK%#L=zf
-zjijEk^(8p2tGT~V1lquo4SLtgC!a|V@YSe?bBAQG@{(zvBKf_TkWx|wkCVutax9^;
-z?OIb8chvXaFYad+#oJ$B4K8I4MrdZHA4S1FoR^2$lHf|!@T4D1zkl=$s0oA60g+u>
-zik-R^G}`bIB&n8!nyEBQ=#J@uzB(px;(>ja#JQR1rv4z}MxB_4qsK4T?5Ue(rOs#T
-z&k;U;+LM?xC4s@=VhMZpZqtR(%AE?))8^MW0^dPKw4_`yb9B{=$v#8v%ZZ1aO9tnK
-zrVg?PA=n(L2ZVnQ!ha<pA7Y*9JUX#m-vs`=@#+~OP<(4ubn1-;(2sw0xiPt8?QEf(
-zK)WF<i9F=d6b2>HP_v=RxDirt{5uI7=1orA5PFLjH_8gjivyV5SXnW!D?@B%*o8jK
-zHm9&WLX2g~mr8>xo~2YOKqr{)LmQqZ0x-$Kr6k(GIdjEi#bFK@0t9+1cBKTV9M$CC
-zBZcMGQRk*n4+H^wF1}1&V)oeeKh$0^pOaqOTg7OeAH0a32HUI{1cG$0g`5+Z`x4VC
-zq?E0K&A4t*69i&pX~}lw{2z#`v*PeeA?Y@zLbf53OAIha+G75S1jBWI1{xjO+aeA?
-zJ~BZ2FflM8FbM_)D-Ht!8U+9Z6a|mF_+n%f@{#20<#d@HFN=aNAOr||H;f;$_90UO
-G0tf)|Q2!DD
-
-diff --git a/examples/puma/client-certs/unknown_ca.crt b/examples/puma/client-certs/unknown_ca.crt
-index 43f25188d..419487f83 100644
---- a/examples/puma/client-certs/unknown_ca.crt
-+++ b/examples/puma/client-certs/unknown_ca.crt
-@@ -1,19 +1,19 @@
- -----BEGIN CERTIFICATE-----
--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
-+LVu0+VBx8eIwdLZplDfQ9sGUjCs=
- -----END CERTIFICATE-----
-diff --git a/examples/puma/client-certs/unknown_ca.key b/examples/puma/client-certs/unknown_ca.key
-index 50f0b3336..d9e3a6203 100644
---- a/examples/puma/client-certs/unknown_ca.key
-+++ b/examples/puma/client-certs/unknown_ca.key
-@@ -1,27 +1,27 @@
- -----BEGIN RSA PRIVATE KEY-----
--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
- -----END RSA PRIVATE KEY-----
-diff --git a/examples/puma/generate_server_test.rb b/examples/puma/generate_server_test.rb
-new file mode 100644
-index 000000000..086b5a778
---- /dev/null
-+++ b/examples/puma/generate_server_test.rb
-@@ -0,0 +1,56 @@
-+# frozen_string_literal: true
-+
-+=begin
-+regenerates cert_puma.pem and puma_keypair.pem
-+dates, key length & sign_algorithm are changed
-+
-+JRuby:
-+after running this file, delete server.p12 and keystore.jks, then (I think)
-+cd examples/puma
-+openssl pkcs12 -export -password pass:jruby_puma -inkey puma_keypair.pem -in cert_puma.pem -name puma -out server.p12
-+keytool -importkeystore -srckeystore server.p12 -srcstoretype pkcs12 -srcstorepass jruby_puma -destkeystore keystore.jks -deststoretype JKS -storepass jruby_puma
-+=end
-+
-+require 'openssl'
-+
-+module Generate
-+
-+ KEY_LEN = 2048
-+ SIGN_ALGORITHM = OpenSSL::Digest::SHA256
-+
-+ FNC = 'cert_puma.pem'
-+ FNK = 'puma_keypair.pem'
-+
-+ class << self
-+
-+ def run
-+ ca_key = OpenSSL::PKey::RSA.new KEY_LEN
-+ key = OpenSSL::PKey::RSA.new KEY_LEN
-+
-+ raw = File.read File.join(__dir__, FNC), mode: 'rb'
-+
-+ cert = OpenSSL::X509::Certificate.new raw
-+ puts "\nOld:", cert.to_text, ""
-+
-+ now = Time.now.utc
-+ mo = now.month
-+ yr = now.year
-+ zone = '+00:00'
-+
-+ cert.not_before = Time.new yr , mo, 1, 0, 0, 0, zone
-+ cert.not_after = Time.new yr+4, mo, 1, 0, 0, 0, zone
-+ cert.public_key = key.public_key
-+ cert.sign ca_key, SIGN_ALGORITHM.new
-+ puts "New:", cert.to_text, ""
-+
-+ Dir.chdir __dir__ do
-+ File.write FNC, cert.to_pem, mode: 'wb'
-+ File.write FNK, key.to_pem , mode: 'wb'
-+ end
-+ rescue => e
-+ puts "error: #{e.message}"
-+ end
-+ end
-+end
-+
-+Generate.run
-diff --git a/examples/puma/keystore.jks b/examples/puma/keystore.jks
-index 147ab20421da8299c1c8607e12538e4258986a61..f1909ecdc7dc10cf94055fc90ab7786f6fbff74e 100644
-GIT binary patch
-literal 2253
-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
-SHJ`dDUw{v?KO|H!dig&k>e!tC
-
-literal 2211
-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
-
-diff --git a/examples/puma/puma_keypair.pem b/examples/puma/puma_keypair.pem
-index 94cdcbcba..c8057c8f1 100644
---- a/examples/puma/puma_keypair.pem
-+++ b/examples/puma/puma_keypair.pem
-@@ -1,15 +1,27 @@
- -----BEGIN RSA PRIVATE KEY-----
--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
- -----END RSA PRIVATE KEY-----
-diff --git a/examples/puma/server.p12 b/examples/puma/server.p12
-new file mode 100644
-index 0000000000000000000000000000000000000000..f8ffc7fab80e9fcb289d7c2a7d63b552494406c2
-GIT binary patch
-literal 2550
-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
-Dcm}%~
-
-literal 0
-HcmV?d00001
-
-diff --git a/test/helpers/ssl.rb b/test/helpers/ssl.rb
-index cfa5fec4a..860d8db62 100644
---- a/test/helpers/ssl.rb
-+++ b/test/helpers/ssl.rb
-@@ -3,7 +3,7 @@ def ssl_query
- @ssl_query ||= if Puma.jruby?
- @keystore = File.expand_path "../../../examples/puma/keystore.jks", __FILE__
- @ssl_cipher_list = "TLS_DHE_RSA_WITH_DES_CBC_SHA,TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA"
-- "keystore=#{@keystore}&keystore-pass=pswd&ssl_cipher_list=#{@ssl_cipher_list}"
-+ "keystore=#{@keystore}&keystore-pass=jruby_puma&ssl_cipher_list=#{@ssl_cipher_list}"
- else
- @cert = File.expand_path "../../../examples/puma/cert_puma.pem", __FILE__
- @key = File.expand_path "../../../examples/puma/puma_keypair.pem", __FILE__
-
-From 4ab2bc4f72441248e95f7742350b3d18dae9aa54 Mon Sep 17 00:00:00 2001
-From: MSP-Greg <Greg.mpls@gmail.com>
-Date: Fri, 7 Aug 2020 16:34:24 -0500
-Subject: [PATCH 3/3] test_puma_server_ssl.rb, ssl.rb - misc updates, fixes for
- updated certs & JRuby
-
----
- test/helpers/ssl.rb | 6 ++--
- test/test_puma_server_ssl.rb | 54 +++++++++++++++++++-----------------
- 2 files changed, 32 insertions(+), 28 deletions(-)
-
-diff --git a/test/helpers/ssl.rb b/test/helpers/ssl.rb
-index 860d8db62..9847a7607 100644
---- a/test/helpers/ssl.rb
-+++ b/test/helpers/ssl.rb
-@@ -1,12 +1,12 @@
- module SSLHelper
- def ssl_query
- @ssl_query ||= if Puma.jruby?
-- @keystore = File.expand_path "../../../examples/puma/keystore.jks", __FILE__
-+ @keystore = File.expand_path "../../examples/puma/keystore.jks", __dir__
- @ssl_cipher_list = "TLS_DHE_RSA_WITH_DES_CBC_SHA,TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA"
- "keystore=#{@keystore}&keystore-pass=jruby_puma&ssl_cipher_list=#{@ssl_cipher_list}"
- else
-- @cert = File.expand_path "../../../examples/puma/cert_puma.pem", __FILE__
-- @key = File.expand_path "../../../examples/puma/puma_keypair.pem", __FILE__
-+ @cert = File.expand_path "../../examples/puma/cert_puma.pem", __dir__
-+ @key = File.expand_path "../../examples/puma/puma_keypair.pem", __dir__
- "key=#{@key}&cert=#{@cert}"
- end
- end
-diff --git a/test/test_puma_server_ssl.rb b/test/test_puma_server_ssl.rb
-index 584ab44f5..ecc3ddcf5 100644
---- a/test/test_puma_server_ssl.rb
-+++ b/test/test_puma_server_ssl.rb
-@@ -53,11 +53,11 @@ def start_server
- ctx = Puma::MiniSSL::Context.new
-
- if Puma.jruby?
-- ctx.keystore = File.expand_path "../../examples/puma/keystore.jks", __FILE__
-- ctx.keystore_pass = 'blahblah'
-+ ctx.keystore = File.expand_path "../examples/puma/keystore.jks", __dir__
-+ ctx.keystore_pass = 'jruby_puma'
- else
-- ctx.key = File.expand_path "../../examples/puma/puma_keypair.pem", __FILE__
-- ctx.cert = File.expand_path "../../examples/puma/cert_puma.pem", __FILE__
-+ ctx.key = File.expand_path "../examples/puma/puma_keypair.pem", __dir__
-+ ctx.cert = File.expand_path "../examples/puma/cert_puma.pem", __dir__
- end
-
- ctx.verify_mode = Puma::MiniSSL::VERIFY_NONE
-@@ -204,26 +204,30 @@ def test_http_rejection
- # client-side TLS authentication tests
- class TestPumaServerSSLClient < Minitest::Test
- parallelize_me!
-+
-+ CERT_PATH = File.expand_path "../examples/puma/client-certs", __dir__
-+
- def assert_ssl_client_error_match(error, subject=nil, &blk)
-- host = "127.0.0.1"
-+ host = "localhost"
- port = UniquePort.call
-
- app = lambda { |env| [200, {}, [env['rack.url_scheme']]] }
-
- ctx = Puma::MiniSSL::Context.new
- if Puma.jruby?
-- ctx.keystore = File.expand_path "../../examples/puma/client-certs/keystore.jks", __FILE__
-- ctx.keystore_pass = 'blahblah'
-+ ctx.keystore = "#{CERT_PATH}/keystore.jks"
-+ ctx.keystore_pass = 'jruby_puma'
- else
-- ctx.key = File.expand_path "../../examples/puma/client-certs/server.key", __FILE__
-- ctx.cert = File.expand_path "../../examples/puma/client-certs/server.crt", __FILE__
-- ctx.ca = File.expand_path "../../examples/puma/client-certs/ca.crt", __FILE__
-+ ctx.key = "#{CERT_PATH}/server.key"
-+ ctx.cert = "#{CERT_PATH}/server.crt"
-+ ctx.ca = "#{CERT_PATH}/ca.crt"
- end
- ctx.verify_mode = Puma::MiniSSL::VERIFY_PEER | Puma::MiniSSL::VERIFY_FAIL_IF_NO_PEER_CERT
-
- events = SSLEventsHelper.new STDOUT, STDERR
- server = Puma::Server.new app, events
- server.add_ssl_listener host, port, ctx
-+ host_addrs = server.binder.ios.map { |io| io.to_io.addr[2] }
- server.run
-
- http = Net::HTTP.new host, port
-@@ -246,11 +250,11 @@ def assert_ssl_client_error_match(error, subject=nil, &blk)
-
- sleep 0.1
- assert_equal !!error, client_error
-- # The JRuby MiniSSL implementation lacks error capturing currently, so we can't inspect the
-- # messages here
-+ # The JRuby MiniSSL implementation lacks error capturing currently,
-+ # so we can't inspect the messages here
- unless Puma.jruby?
- assert_match error, events.error.message if error
-- assert_equal host, events.addr if error
-+ assert_includes host_addrs, events.addr if error
- assert_equal subject, events.cert.subject.to_s if subject
- end
- ensure
-@@ -264,32 +268,32 @@ def test_verify_fail_if_no_client_cert
- end
-
- def test_verify_fail_if_client_unknown_ca
-- assert_ssl_client_error_match('self signed certificate in certificate chain', '/DC=net/DC=puma/CN=ca-unknown') do |http|
-- key = File.expand_path "../../examples/puma/client-certs/client_unknown.key", __FILE__
-- crt = File.expand_path "../../examples/puma/client-certs/client_unknown.crt", __FILE__
-+ assert_ssl_client_error_match('self signed certificate in certificate chain', '/DC=net/DC=puma/CN=CAU') do |http|
-+ key = "#{CERT_PATH}/client_unknown.key"
-+ crt = "#{CERT_PATH}/client_unknown.crt"
- http.key = OpenSSL::PKey::RSA.new File.read(key)
- http.cert = OpenSSL::X509::Certificate.new File.read(crt)
-- http.ca_file = File.expand_path "../../examples/puma/client-certs/unknown_ca.crt", __FILE__
-+ http.ca_file = "#{CERT_PATH}/unknown_ca.crt"
- end
- end
-
- def test_verify_fail_if_client_expired_cert
-- assert_ssl_client_error_match('certificate has expired', '/DC=net/DC=puma/CN=client-expired') do |http|
-- key = File.expand_path "../../examples/puma/client-certs/client_expired.key", __FILE__
-- crt = File.expand_path "../../examples/puma/client-certs/client_expired.crt", __FILE__
-+ assert_ssl_client_error_match('certificate has expired', '/DC=net/DC=puma/CN=localhost') do |http|
-+ key = "#{CERT_PATH}/client_expired.key"
-+ crt = "#{CERT_PATH}/client_expired.crt"
- http.key = OpenSSL::PKey::RSA.new File.read(key)
- http.cert = OpenSSL::X509::Certificate.new File.read(crt)
-- http.ca_file = File.expand_path "../../examples/puma/client-certs/ca.crt", __FILE__
-+ http.ca_file = "#{CERT_PATH}/ca.crt"
- end
- end
-
- def test_verify_client_cert
- assert_ssl_client_error_match(nil) do |http|
-- key = File.expand_path "../../examples/puma/client-certs/client.key", __FILE__
-- crt = File.expand_path "../../examples/puma/client-certs/client.crt", __FILE__
-+ key = "#{CERT_PATH}/client.key"
-+ crt = "#{CERT_PATH}/client.crt"
- http.key = OpenSSL::PKey::RSA.new File.read(key)
- http.cert = OpenSSL::X509::Certificate.new File.read(crt)
-- http.ca_file = File.expand_path "../../examples/puma/client-certs/ca.crt", __FILE__
-+ http.ca_file = "#{CERT_PATH}/ca.crt"
- http.verify_mode = OpenSSL::SSL::VERIFY_PEER
- end
- end
diff --git a/rubygem-puma.spec b/rubygem-puma.spec
index ee0d718..c6778f4 100644
--- a/rubygem-puma.spec
+++ b/rubygem-puma.spec
@@ -1,43 +1,39 @@
# Generated from puma-3.6.0.gem by gem2rpm -*- rpm-spec -*-
%global gem_name puma
+# For testing purposes
+#%%global prerelease
+
# Allow to use precompiled version of parser, because Ragel not always
# behaves correctly.
%bcond_without ragel
%bcond_without help2man
Name: rubygem-%{gem_name}
-Version: 4.3.6
-Release: 5%{?dist}
+Version: 5.5.2
+Release: 1%{?dist}
Summary: A simple, fast, threaded, and highly concurrent HTTP 1.1 server
License: BSD
URL: http://puma.io
Source0: https://rubygems.org/gems/%{gem_name}-%{version}.gem
# The puma gem doesn't ship with the test suite.
# git clone https://github.com/puma/puma --no-checkout
-# cd puma && git archive -v -o puma-4.3.6-tests.txz v4.3.6 test
-Source1: %{gem_name}-%{version}-tests.txz
+# cd puma && git archive -v -o puma-5.5.2-tests.txz v5.5.2 test
+Source1: %{gem_name}-%{version}%{?prerelease}-tests.txz
# The puma gem doesn't ship with the examples used in test suite.
-# git archive -v -o puma-4.3.6-examples.txz v4.3.6 examples
-Source3: %{gem_name}-%{version}-examples.txz
+# git archive -v -o puma-5.5.2-examples.txz v5.5.2 examples
+Source3: %{gem_name}-%{version}%{?prerelease}-examples.txz
# Set the default cipher list "PROFILE=SYSTEM".
# https://fedoraproject.org/wiki/Packaging:CryptoPolicies
Patch2: rubygem-puma-3.6.0-fedora-crypto-policy-cipher-list.patch
-# Don't exit Puma on test failure.
-# https://github.com/puma/puma/pull/2332
-Patch3: rubygem-puma-5.0.0-Report-pumactl-exit.patch
-# Fix SSL certificates.
-# https://github.com/puma/puma/pull/2333
-Patch4: rubygem-puma-5.0.0-Update-test-certs-and-code.patch
-
-# Git is needed just to apply Patch4.
-BuildRequires: %{_bindir}/git
+
BuildRequires: openssl-devel
BuildRequires: ruby(release)
BuildRequires: rubygems-devel
BuildRequires: ruby-devel
BuildRequires: rubygem(rack)
BuildRequires: rubygem(minitest)
+BuildRequires: rubygem(minitest-stub-const)
BuildRequires: rubygem(nio4r)
%if %{with ragel}
BuildRequires: %{_bindir}/ragel
@@ -66,15 +62,7 @@ BuildArch: noarch
Documentation for %{name}.
%prep
-%setup -q -T -n %{_builddir} -c %{_builddir} -a 1 -a 3
-
-%autosetup -N -S git -D -T -n %{_builddir}
-# %%autopatch must be used to apply binary patch. Unfortunately
-# `%%autopatch 3 4` does not work as expected:
-# https://github.com/rpm-software-management/rpm/pull/1776
-%autopatch -m 3 -M 4
-
-%setup -q -n %{gem_name}-%{version}
+%setup -q -n %{gem_name}-%{version}%{?prerelease} -b 1 -b 3
%patch2 -p1
@@ -93,11 +81,7 @@ ragel ext/puma_http11/http11_parser.rl -G2 -I ext/puma_http11 \
%endif
%build
-# Create the gem as gem install only works on a gem file
-gem build ../%{gem_name}-%{version}.gemspec
-
-# %%gem_install compiles any C extensions and installs the gem into ./%%gem_dir
-# by default, so that we can move it into the buildroot in %%install
+gem build ../%{gem_name}-%{version}%{?prerelease}.gemspec
%gem_install
%install
@@ -133,16 +117,42 @@ help2man --no-discard-stderr -N -s1 -o %{buildroot}%{_mandir}/man1/%{gem_name}.1
# Run the test suite
%check
pushd .%{gem_instdir}
-ln -s %{_builddir}/test .
+cp -a %{_builddir}/test .
ln -s %{_builddir}/examples .
-# We do not ship minitest-retry or minitest-proveit.
+# We do not ship minitest-retry, minitest-proveit.
sed -i -e "/require..minitest\/\(retry\|proveit\)./ s/^/#/" test/helper.rb
sed -i "/Minitest::Retry/ s/^/#/" test/helper.rb
sed -i '/prove_it!/ s/^/#/' test/helper.rb
# Increase timeout seconds to avoid the timeout for every test case on Koji.
-sed -i '/::Timeout.timeout/ s/60/600/' test/helper.rb
+# TimeoutEveryTestCase::TestTookTooLong: execution expired
+sed -i '/::Timeout.timeout/ s/45/300/' test/helper.rb
+
+# Tests use bundler
+mv test/test_preserve_bundler_env.rb{,.disable}
+mv test/test_worker_gem_independence.rb{,.disable}
+sed -i '/^\s*def test_prune_bundler_with_multiple_workers$/a\
+ skip' test/test_integration_pumactl.rb
+sed -i '/^\s*def test_prune_bundler_with_multiple_workers$/a\
+ skip' test/test_integration_cluster.rb
+
+# Tests require systemd (sd_notify gem)
+mv test/test_integration_systemd.rb{,.disable}
+
+# We don't have localhost gem in Fedora.
+mv test/test_puma_localhost_authority.rb{,.disable}
+
+# Disable unstable tests
+# TestIntegrationSingle#test_closed_listener
+# TestIntegrationSingle#test_puma_started_log_writing
+# TestIntegrationSingle#test_write_to_log
+# TestIntegrationCluster#test_refork
+# TestIntegrationCluster#test_hot_restart_does_not_drop_connections
+# e.g. Errno::EMFILE: Too many open files - /usr/bin/ruby
+mv test/test_integration_single.rb{,.disable}
+# https://github.com/puma/puma/issues/2209
+mv test/test_integration_cluster.rb{,.disable}
# Skip an unstable test on Koji.
# TestCLI#test_control failing with "pool_capacity": 0
@@ -164,22 +174,14 @@ sed -i '/^ def test_plugin$/a\
sed -i '/^ def test_verify_fail_if_client_unknown_ca$/a\
skip' test/test_puma_server_ssl.rb
-# Skip unstable tests on Koji.
-# test_integration_cluster.rb: not expected replies
-# https://github.com/puma/puma/issues/2209
-sed -i '/^ def test_usr1_all_respond_/a\
- skip' test/test_integration_cluster.rb
-
# Make binary exension available in Ruby load path.
# Enable verbose mode to check unstable tests easily.
-RUBYOPT="-Ilib:$(dirs +1 -l)%{gem_extdir_mri}" CI=1 ruby \
- -e 'Dir.glob "./test/**/test_*.rb", &method(:require)' \
+RUBYOPT="-Ilib:$(dirs +1 -l)%{gem_extdir_mri}" \
+CI=1 \
+LC_ALL=C.UTF-8 \
+ruby -e 'Dir.glob "./test/**/test_*.rb", &method(:require)' \
-- -v
-# Integration test
-# Make binary exension available in Ruby load path.
-RUBYOPT="-I$(dirs +1 -l)%{gem_extdir_mri}" ruby test/shell/run.rb
-
%if %{with help2man}
# Check `--help` output, using which man page is created
export RUBYOPT="-I%{buildroot}%{gem_extdir_mri}:%{buildroot}%{gem_libdir}"
@@ -210,6 +212,10 @@ popd
%{gem_instdir}/tools
%changelog
+* Wed Dec 22 2021 Pavel Valena <pvalena@redhat.com> - 5.5.2-1
+- Update to puma 5.5.2.
+ Resolves: rhbz#1880111
+
* Mon Nov 08 2021 Vít Ondruch <vondruch@redhat.com> - 4.3.6-5
- Fix FTBFS due to updated RPM.
Resolves: rhbz#1987946
diff --git a/sources b/sources
index 2d096ce..1647e5f 100644
--- a/sources
+++ b/sources
@@ -1,3 +1,3 @@
-SHA512 (puma-4.3.6-examples.txz) = 1d030f95b84dfaa7b43d8ca26a9eade69ada4b5ba9b06127345a4f2ebaa0b1ffe6f535e5c7d3b4c8bb81fc733d5e269739cde0a8765131e534a0ed7bbb71c7f6
-SHA512 (puma-4.3.6-tests.txz) = cf9a45eb6ebdc02a17032ae6218f21a00dcd822d39d042004b1e50cb30e00b853bf0c0e7b5c2c1b78170bf85f4b072ff2e803741d8d161423c24ebd36dcea8b8
-SHA512 (puma-4.3.6.gem) = 08fbcec8efcd77b4f953550f912ab218d5d31d203f60460422563930419719f3e5cac9fd1f875628008e699139eccb16eac75a4af1c75966c7ba42fadf9df3a6
+SHA512 (puma-5.5.2.gem) = dcc6d35bc4907ad3b6cfbfb902caa2ba763114c29fab6f60b3b46d5294f6e1744124ffea2e665b288889215ce6dcc547047246a8c96fc615c2c16fd156b85d71
+SHA512 (puma-5.5.2-tests.txz) = 3ccee0023a15860bafcdf9e007565d5b3536b6a0192a06cfe4d8144e35d477e7e7300bf638423b16dfe2f3ff9d5a31ebed467b9f8ebdad76a027b1f82181c279
+SHA512 (puma-5.5.2-examples.txz) = a514af3958610b299dad481263d88166bdbd268338d1bc8af7133e0ed0b1a610a2e813f649b5aa7d8e5d1b2353d42411214505529c6f9093357c36571b7bc8dd
On branch rebase
Your branch is up to date with 'pvalena/rebase'.
nothing to commit (use -u to show untracked files)
Everything up-to-date
Branch 'rebase' set up to track remote branch 'rebase' from 'pvalena'.
> Run copr build.
+ scripts/pkgs/cr-build.sh -c -t 30m rubygems
Created builds: 3193146
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment