puma 4.3.9 → 4.3.12
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 +15 -0
- data/LICENSE +0 -0
- data/README.md +0 -0
- data/bin/puma-wild +0 -0
- data/docs/architecture.md +0 -0
- data/docs/deployment.md +0 -0
- data/docs/images/puma-connection-flow-no-reactor.png +0 -0
- data/docs/images/puma-connection-flow.png +0 -0
- data/docs/images/puma-general-arch.png +0 -0
- data/docs/nginx.md +0 -0
- data/docs/plugins.md +0 -0
- data/docs/restart.md +0 -0
- data/docs/signals.md +0 -0
- data/docs/systemd.md +0 -0
- data/docs/tcp_mode.md +0 -0
- data/ext/puma_http11/PumaHttp11Service.java +0 -0
- data/ext/puma_http11/ext_help.h +0 -0
- data/ext/puma_http11/extconf.rb +8 -0
- data/ext/puma_http11/http11_parser.c +22 -16
- data/ext/puma_http11/http11_parser.h +0 -0
- data/ext/puma_http11/http11_parser.java.rl +0 -0
- data/ext/puma_http11/http11_parser.rl +0 -0
- data/ext/puma_http11/http11_parser_common.rl +1 -1
- data/ext/puma_http11/io_buffer.c +0 -0
- data/ext/puma_http11/mini_ssl.c +82 -47
- data/ext/puma_http11/org/jruby/puma/Http11.java +0 -0
- data/ext/puma_http11/org/jruby/puma/Http11Parser.java +48 -46
- data/ext/puma_http11/org/jruby/puma/IOBuffer.java +0 -0
- data/ext/puma_http11/org/jruby/puma/MiniSSL.java +0 -0
- data/ext/puma_http11/puma_http11.c +0 -0
- data/lib/puma/accept_nonblock.rb +0 -0
- data/lib/puma/app/status.rb +0 -0
- data/lib/puma/binder.rb +0 -0
- data/lib/puma/cli.rb +0 -0
- data/lib/puma/client.rb +54 -11
- data/lib/puma/cluster.rb +0 -0
- data/lib/puma/commonlogger.rb +0 -0
- data/lib/puma/configuration.rb +0 -0
- data/lib/puma/const.rb +6 -4
- data/lib/puma/control_cli.rb +0 -0
- data/lib/puma/detect.rb +0 -0
- data/lib/puma/dsl.rb +0 -0
- data/lib/puma/events.rb +0 -0
- data/lib/puma/io_buffer.rb +0 -0
- data/lib/puma/jruby_restart.rb +0 -0
- data/lib/puma/launcher.rb +0 -0
- data/lib/puma/minissl/context_builder.rb +0 -0
- data/lib/puma/minissl.rb +0 -0
- data/lib/puma/null_io.rb +0 -0
- data/lib/puma/plugin/tmp_restart.rb +0 -0
- data/lib/puma/plugin.rb +0 -0
- data/lib/puma/rack/builder.rb +0 -0
- data/lib/puma/rack/urlmap.rb +0 -0
- data/lib/puma/rack_default.rb +0 -0
- data/lib/puma/reactor.rb +0 -0
- data/lib/puma/runner.rb +0 -0
- data/lib/puma/server.rb +16 -4
- data/lib/puma/single.rb +0 -0
- data/lib/puma/state_file.rb +0 -0
- data/lib/puma/tcp_logger.rb +0 -0
- data/lib/puma/thread_pool.rb +0 -0
- data/lib/puma/util.rb +0 -0
- data/lib/puma.rb +0 -0
- data/lib/rack/handler/puma.rb +0 -0
- data/tools/docker/Dockerfile +0 -0
- data/tools/jungle/README.md +0 -0
- data/tools/jungle/init.d/README.md +0 -0
- data/tools/jungle/rc.d/README.md +0 -0
- data/tools/jungle/rc.d/puma.conf +0 -0
- data/tools/jungle/upstart/README.md +0 -0
- data/tools/jungle/upstart/puma-manager.conf +0 -0
- data/tools/jungle/upstart/puma.conf +0 -0
- data/tools/trickletest.rb +0 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 55de061927f854a6aa5886c0ef6573a6a95306afadf4eb156fbf3e59d54f3574
|
4
|
+
data.tar.gz: 9b58b994708cae549af93d92568f5111eb831404f9f189662ea73ff5c914ece3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a5208ba5fc102a2d5df875490bf99afdf95aa2614a82503806aedf13dcf58c61cd62551aece57762bc6c54f5ae71a3517efb4b17d4d9eace27f99270ec1b9f6e
|
7
|
+
data.tar.gz: 5555c0290a7db01cdddfb19555caaa9b4d20085ef28297d436f3f37c2e5732d53f754d2ced9f76ffbc061c20e401ae68fd4819e630e12f17d335e6464dc42615
|
data/History.md
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
## 4.3.12 / 2022-03-30
|
2
|
+
|
3
|
+
* Security
|
4
|
+
* Close several HTTP Request Smuggling exploits (CVE-2022-24790)
|
5
|
+
|
6
|
+
## 4.3.11 / 2022-02-11
|
7
|
+
|
8
|
+
* Security
|
9
|
+
* Always close the response body (GHSA-rmj8-8hhh-gv5h)
|
10
|
+
|
11
|
+
## 4.3.10 / 2021-10-12
|
12
|
+
|
13
|
+
* Bugfixes
|
14
|
+
* Allow UTF-8 in HTTP header values
|
15
|
+
|
1
16
|
## 4.3.9 / 2021-10-12
|
2
17
|
|
3
18
|
* Security
|
data/LICENSE
CHANGED
File without changes
|
data/README.md
CHANGED
File without changes
|
data/bin/puma-wild
CHANGED
File without changes
|
data/docs/architecture.md
CHANGED
File without changes
|
data/docs/deployment.md
CHANGED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
data/docs/nginx.md
CHANGED
File without changes
|
data/docs/plugins.md
CHANGED
File without changes
|
data/docs/restart.md
CHANGED
File without changes
|
data/docs/signals.md
CHANGED
File without changes
|
data/docs/systemd.md
CHANGED
File without changes
|
data/docs/tcp_mode.md
CHANGED
File without changes
|
File without changes
|
data/ext/puma_http11/ext_help.h
CHANGED
File without changes
|
data/ext/puma_http11/extconf.rb
CHANGED
@@ -22,6 +22,14 @@ unless ENV["DISABLE_SSL"]
|
|
22
22
|
# with versions after 1.1.1
|
23
23
|
have_func "TLS_server_method" , "openssl/ssl.h"
|
24
24
|
have_macro "SSL_CTX_set_min_proto_version", "openssl/ssl.h"
|
25
|
+
|
26
|
+
# Random.bytes available in Ruby 2.5 and later, Random::DEFAULT deprecated in 3.0
|
27
|
+
if Random.respond_to?(:bytes)
|
28
|
+
$defs.push("-DHAVE_RANDOM_BYTES")
|
29
|
+
puts "checking for Random.bytes... yes"
|
30
|
+
else
|
31
|
+
puts "checking for Random.bytes... no"
|
32
|
+
end
|
25
33
|
end
|
26
34
|
end
|
27
35
|
|
@@ -428,13 +428,16 @@ st18:
|
|
428
428
|
case 18:
|
429
429
|
#line 428 "ext/puma_http11/http11_parser.c"
|
430
430
|
switch( (*p) ) {
|
431
|
-
case 9: goto tr25;
|
432
431
|
case 13: goto tr26;
|
433
432
|
case 32: goto tr27;
|
433
|
+
case 127: goto st0;
|
434
434
|
}
|
435
|
-
if (
|
436
|
-
|
437
|
-
|
435
|
+
if ( (*p) > 8 ) {
|
436
|
+
if ( 10 <= (*p) && (*p) <= 31 )
|
437
|
+
goto st0;
|
438
|
+
} else if ( (*p) >= 0 )
|
439
|
+
goto st0;
|
440
|
+
goto tr25;
|
438
441
|
tr25:
|
439
442
|
#line 44 "ext/puma_http11/http11_parser.rl"
|
440
443
|
{ MARK(mark, p); }
|
@@ -443,14 +446,17 @@ st19:
|
|
443
446
|
if ( ++p == pe )
|
444
447
|
goto _test_eof19;
|
445
448
|
case 19:
|
446
|
-
#line
|
449
|
+
#line 448 "ext/puma_http11/http11_parser.c"
|
447
450
|
switch( (*p) ) {
|
448
|
-
case 9: goto st19;
|
449
451
|
case 13: goto tr29;
|
452
|
+
case 127: goto st0;
|
450
453
|
}
|
451
|
-
if (
|
452
|
-
|
453
|
-
|
454
|
+
if ( (*p) > 8 ) {
|
455
|
+
if ( 10 <= (*p) && (*p) <= 31 )
|
456
|
+
goto st0;
|
457
|
+
} else if ( (*p) >= 0 )
|
458
|
+
goto st0;
|
459
|
+
goto st19;
|
454
460
|
tr9:
|
455
461
|
#line 51 "ext/puma_http11/http11_parser.rl"
|
456
462
|
{
|
@@ -493,7 +499,7 @@ st20:
|
|
493
499
|
if ( ++p == pe )
|
494
500
|
goto _test_eof20;
|
495
501
|
case 20:
|
496
|
-
#line
|
502
|
+
#line 501 "ext/puma_http11/http11_parser.c"
|
497
503
|
switch( (*p) ) {
|
498
504
|
case 32: goto tr31;
|
499
505
|
case 60: goto st0;
|
@@ -514,7 +520,7 @@ st21:
|
|
514
520
|
if ( ++p == pe )
|
515
521
|
goto _test_eof21;
|
516
522
|
case 21:
|
517
|
-
#line
|
523
|
+
#line 522 "ext/puma_http11/http11_parser.c"
|
518
524
|
switch( (*p) ) {
|
519
525
|
case 32: goto tr33;
|
520
526
|
case 60: goto st0;
|
@@ -535,7 +541,7 @@ st22:
|
|
535
541
|
if ( ++p == pe )
|
536
542
|
goto _test_eof22;
|
537
543
|
case 22:
|
538
|
-
#line
|
544
|
+
#line 543 "ext/puma_http11/http11_parser.c"
|
539
545
|
switch( (*p) ) {
|
540
546
|
case 43: goto st22;
|
541
547
|
case 58: goto st23;
|
@@ -560,7 +566,7 @@ st23:
|
|
560
566
|
if ( ++p == pe )
|
561
567
|
goto _test_eof23;
|
562
568
|
case 23:
|
563
|
-
#line
|
569
|
+
#line 568 "ext/puma_http11/http11_parser.c"
|
564
570
|
switch( (*p) ) {
|
565
571
|
case 32: goto tr8;
|
566
572
|
case 34: goto st0;
|
@@ -580,7 +586,7 @@ st24:
|
|
580
586
|
if ( ++p == pe )
|
581
587
|
goto _test_eof24;
|
582
588
|
case 24:
|
583
|
-
#line
|
589
|
+
#line 588 "ext/puma_http11/http11_parser.c"
|
584
590
|
switch( (*p) ) {
|
585
591
|
case 32: goto tr37;
|
586
592
|
case 34: goto st0;
|
@@ -603,7 +609,7 @@ st25:
|
|
603
609
|
if ( ++p == pe )
|
604
610
|
goto _test_eof25;
|
605
611
|
case 25:
|
606
|
-
#line
|
612
|
+
#line 611 "ext/puma_http11/http11_parser.c"
|
607
613
|
switch( (*p) ) {
|
608
614
|
case 32: goto tr41;
|
609
615
|
case 34: goto st0;
|
@@ -623,7 +629,7 @@ st26:
|
|
623
629
|
if ( ++p == pe )
|
624
630
|
goto _test_eof26;
|
625
631
|
case 26:
|
626
|
-
#line
|
632
|
+
#line 631 "ext/puma_http11/http11_parser.c"
|
627
633
|
switch( (*p) ) {
|
628
634
|
case 32: goto tr44;
|
629
635
|
case 34: goto st0;
|
File without changes
|
File without changes
|
File without changes
|
@@ -43,7 +43,7 @@
|
|
43
43
|
|
44
44
|
field_name = ( token -- ":" )+ >start_field $snake_upcase_field %write_field;
|
45
45
|
|
46
|
-
field_value = (
|
46
|
+
field_value = ( (any -- CTL) | "\t" )* >start_value %write_value;
|
47
47
|
|
48
48
|
message_header = field_name ":" " "* field_value :> CRLF;
|
49
49
|
|
data/ext/puma_http11/io_buffer.c
CHANGED
File without changes
|
data/ext/puma_http11/mini_ssl.c
CHANGED
@@ -62,44 +62,65 @@ ms_conn* engine_alloc(VALUE klass, VALUE* obj) {
|
|
62
62
|
return conn;
|
63
63
|
}
|
64
64
|
|
65
|
-
DH *
|
66
|
-
/* `openssl dhparam
|
65
|
+
DH *get_dh2048(void) {
|
66
|
+
/* `openssl dhparam -C 2048`
|
67
67
|
* -----BEGIN DH PARAMETERS-----
|
68
|
-
*
|
69
|
-
*
|
70
|
-
*
|
68
|
+
* MIIBCAKCAQEAjmh1uQHdTfxOyxEbKAV30fUfzqMDF/ChPzjfyzl2jcrqQMhrk76o
|
69
|
+
* 2NPNXqxHwsddMZ1RzvU8/jl+uhRuPWjXCFZbhET4N1vrviZM3VJhV8PPHuiVOACO
|
70
|
+
* y32jFd+Szx4bo2cXSK83hJ6jRd+0asP1awWjz9/06dFkrILCXMIfQLo0D8rqmppn
|
71
|
+
* EfDDAwuudCpM9kcDmBRAm9JsKbQ6gzZWjkc5+QWSaQofojIHbjvj3xzguaCJn+oQ
|
72
|
+
* vHWM+hsAnaOgEwCyeZ3xqs+/5lwSbkE/tqJW98cEZGygBUVo9jxZRZx6KOfjpdrb
|
73
|
+
* yenO9LJr/qtyrZB31WJbqxI0m0AKTAO8UwIBAg==
|
71
74
|
* -----END DH PARAMETERS-----
|
72
75
|
*/
|
73
|
-
static unsigned char
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
76
|
+
static unsigned char dh2048_p[] = {
|
77
|
+
0x8E, 0x68, 0x75, 0xB9, 0x01, 0xDD, 0x4D, 0xFC, 0x4E, 0xCB,
|
78
|
+
0x11, 0x1B, 0x28, 0x05, 0x77, 0xD1, 0xF5, 0x1F, 0xCE, 0xA3,
|
79
|
+
0x03, 0x17, 0xF0, 0xA1, 0x3F, 0x38, 0xDF, 0xCB, 0x39, 0x76,
|
80
|
+
0x8D, 0xCA, 0xEA, 0x40, 0xC8, 0x6B, 0x93, 0xBE, 0xA8, 0xD8,
|
81
|
+
0xD3, 0xCD, 0x5E, 0xAC, 0x47, 0xC2, 0xC7, 0x5D, 0x31, 0x9D,
|
82
|
+
0x51, 0xCE, 0xF5, 0x3C, 0xFE, 0x39, 0x7E, 0xBA, 0x14, 0x6E,
|
83
|
+
0x3D, 0x68, 0xD7, 0x08, 0x56, 0x5B, 0x84, 0x44, 0xF8, 0x37,
|
84
|
+
0x5B, 0xEB, 0xBE, 0x26, 0x4C, 0xDD, 0x52, 0x61, 0x57, 0xC3,
|
85
|
+
0xCF, 0x1E, 0xE8, 0x95, 0x38, 0x00, 0x8E, 0xCB, 0x7D, 0xA3,
|
86
|
+
0x15, 0xDF, 0x92, 0xCF, 0x1E, 0x1B, 0xA3, 0x67, 0x17, 0x48,
|
87
|
+
0xAF, 0x37, 0x84, 0x9E, 0xA3, 0x45, 0xDF, 0xB4, 0x6A, 0xC3,
|
88
|
+
0xF5, 0x6B, 0x05, 0xA3, 0xCF, 0xDF, 0xF4, 0xE9, 0xD1, 0x64,
|
89
|
+
0xAC, 0x82, 0xC2, 0x5C, 0xC2, 0x1F, 0x40, 0xBA, 0x34, 0x0F,
|
90
|
+
0xCA, 0xEA, 0x9A, 0x9A, 0x67, 0x11, 0xF0, 0xC3, 0x03, 0x0B,
|
91
|
+
0xAE, 0x74, 0x2A, 0x4C, 0xF6, 0x47, 0x03, 0x98, 0x14, 0x40,
|
92
|
+
0x9B, 0xD2, 0x6C, 0x29, 0xB4, 0x3A, 0x83, 0x36, 0x56, 0x8E,
|
93
|
+
0x47, 0x39, 0xF9, 0x05, 0x92, 0x69, 0x0A, 0x1F, 0xA2, 0x32,
|
94
|
+
0x07, 0x6E, 0x3B, 0xE3, 0xDF, 0x1C, 0xE0, 0xB9, 0xA0, 0x89,
|
95
|
+
0x9F, 0xEA, 0x10, 0xBC, 0x75, 0x8C, 0xFA, 0x1B, 0x00, 0x9D,
|
96
|
+
0xA3, 0xA0, 0x13, 0x00, 0xB2, 0x79, 0x9D, 0xF1, 0xAA, 0xCF,
|
97
|
+
0xBF, 0xE6, 0x5C, 0x12, 0x6E, 0x41, 0x3F, 0xB6, 0xA2, 0x56,
|
98
|
+
0xF7, 0xC7, 0x04, 0x64, 0x6C, 0xA0, 0x05, 0x45, 0x68, 0xF6,
|
99
|
+
0x3C, 0x59, 0x45, 0x9C, 0x7A, 0x28, 0xE7, 0xE3, 0xA5, 0xDA,
|
100
|
+
0xDB, 0xC9, 0xE9, 0xCE, 0xF4, 0xB2, 0x6B, 0xFE, 0xAB, 0x72,
|
101
|
+
0xAD, 0x90, 0x77, 0xD5, 0x62, 0x5B, 0xAB, 0x12, 0x34, 0x9B,
|
102
|
+
0x40, 0x0A, 0x4C, 0x03, 0xBC, 0x53
|
85
103
|
};
|
86
|
-
static unsigned char
|
104
|
+
static unsigned char dh2048_g[] = { 0x02 };
|
87
105
|
|
88
106
|
DH *dh;
|
107
|
+
#if !(OPENSSL_VERSION_NUMBER < 0x10100005L || defined(LIBRESSL_VERSION_NUMBER))
|
108
|
+
BIGNUM *p, *g;
|
109
|
+
#endif
|
110
|
+
|
89
111
|
dh = DH_new();
|
90
112
|
|
91
113
|
#if OPENSSL_VERSION_NUMBER < 0x10100005L || defined(LIBRESSL_VERSION_NUMBER)
|
92
|
-
dh->p = BN_bin2bn(
|
93
|
-
dh->g = BN_bin2bn(
|
114
|
+
dh->p = BN_bin2bn(dh2048_p, sizeof(dh2048_p), NULL);
|
115
|
+
dh->g = BN_bin2bn(dh2048_g, sizeof(dh2048_g), NULL);
|
94
116
|
|
95
117
|
if ((dh->p == NULL) || (dh->g == NULL)) {
|
96
118
|
DH_free(dh);
|
97
119
|
return NULL;
|
98
120
|
}
|
99
121
|
#else
|
100
|
-
|
101
|
-
|
102
|
-
g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL);
|
122
|
+
p = BN_bin2bn(dh2048_p, sizeof(dh2048_p), NULL);
|
123
|
+
g = BN_bin2bn(dh2048_g, sizeof(dh2048_g), NULL);
|
103
124
|
|
104
125
|
if (p == NULL || g == NULL || !DH_set0_pqg(dh, p, NULL, g)) {
|
105
126
|
DH_free(dh);
|
@@ -139,7 +160,7 @@ static int engine_verify_callback(int preverify_ok, X509_STORE_CTX* ctx) {
|
|
139
160
|
}
|
140
161
|
|
141
162
|
VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
|
142
|
-
VALUE obj;
|
163
|
+
VALUE obj, session_id_bytes;
|
143
164
|
SSL_CTX* ctx;
|
144
165
|
SSL* ssl;
|
145
166
|
int min, ssl_options;
|
@@ -198,7 +219,7 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
|
|
198
219
|
else {
|
199
220
|
min = TLS1_VERSION;
|
200
221
|
}
|
201
|
-
|
222
|
+
|
202
223
|
SSL_CTX_set_min_proto_version(ctx, min);
|
203
224
|
|
204
225
|
SSL_CTX_set_options(ctx, ssl_options);
|
@@ -226,7 +247,21 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
|
|
226
247
|
SSL_CTX_set_cipher_list(ctx, "HIGH:!aNULL@STRENGTH");
|
227
248
|
}
|
228
249
|
|
229
|
-
|
250
|
+
// Random.bytes available in Ruby 2.5 and later, Random::DEFAULT deprecated in 3.0
|
251
|
+
session_id_bytes = rb_funcall(
|
252
|
+
#ifdef HAVE_RANDOM_BYTES
|
253
|
+
rb_cRandom,
|
254
|
+
#else
|
255
|
+
rb_const_get(rb_cRandom, rb_intern_const("DEFAULT")),
|
256
|
+
#endif
|
257
|
+
rb_intern_const("bytes"),
|
258
|
+
1, ULL2NUM(SSL_MAX_SSL_SESSION_ID_LENGTH));
|
259
|
+
|
260
|
+
SSL_CTX_set_session_id_context(ctx,
|
261
|
+
(unsigned char *) RSTRING_PTR(session_id_bytes),
|
262
|
+
SSL_MAX_SSL_SESSION_ID_LENGTH);
|
263
|
+
|
264
|
+
DH *dh = get_dh2048();
|
230
265
|
SSL_CTX_set_tmp_dh(ctx, dh);
|
231
266
|
|
232
267
|
#if OPENSSL_VERSION_NUMBER < 0x10002000L
|
@@ -493,27 +528,27 @@ void Init_mini_ssl(VALUE puma) {
|
|
493
528
|
#else
|
494
529
|
rb_define_const(mod, "OPENSSL_LIBRARY_VERSION", rb_str_new2(SSLeay_version(SSLEAY_VERSION)));
|
495
530
|
#endif
|
496
|
-
|
497
|
-
#if defined(OPENSSL_NO_SSL3) || defined(OPENSSL_NO_SSL3_METHOD)
|
498
|
-
/* True if SSL3 is not available */
|
499
|
-
rb_define_const(mod, "OPENSSL_NO_SSL3", Qtrue);
|
500
|
-
#else
|
501
|
-
rb_define_const(mod, "OPENSSL_NO_SSL3", Qfalse);
|
502
|
-
#endif
|
503
|
-
|
504
|
-
#if defined(OPENSSL_NO_TLS1) || defined(OPENSSL_NO_TLS1_METHOD)
|
505
|
-
/* True if TLS1 is not available */
|
506
|
-
rb_define_const(mod, "OPENSSL_NO_TLS1", Qtrue);
|
507
|
-
#else
|
508
|
-
rb_define_const(mod, "OPENSSL_NO_TLS1", Qfalse);
|
509
|
-
#endif
|
510
|
-
|
511
|
-
#if defined(OPENSSL_NO_TLS1_1) || defined(OPENSSL_NO_TLS1_1_METHOD)
|
512
|
-
/* True if TLS1_1 is not available */
|
513
|
-
rb_define_const(mod, "OPENSSL_NO_TLS1_1", Qtrue);
|
514
|
-
#else
|
515
|
-
rb_define_const(mod, "OPENSSL_NO_TLS1_1", Qfalse);
|
516
|
-
#endif
|
531
|
+
|
532
|
+
#if defined(OPENSSL_NO_SSL3) || defined(OPENSSL_NO_SSL3_METHOD)
|
533
|
+
/* True if SSL3 is not available */
|
534
|
+
rb_define_const(mod, "OPENSSL_NO_SSL3", Qtrue);
|
535
|
+
#else
|
536
|
+
rb_define_const(mod, "OPENSSL_NO_SSL3", Qfalse);
|
537
|
+
#endif
|
538
|
+
|
539
|
+
#if defined(OPENSSL_NO_TLS1) || defined(OPENSSL_NO_TLS1_METHOD)
|
540
|
+
/* True if TLS1 is not available */
|
541
|
+
rb_define_const(mod, "OPENSSL_NO_TLS1", Qtrue);
|
542
|
+
#else
|
543
|
+
rb_define_const(mod, "OPENSSL_NO_TLS1", Qfalse);
|
544
|
+
#endif
|
545
|
+
|
546
|
+
#if defined(OPENSSL_NO_TLS1_1) || defined(OPENSSL_NO_TLS1_1_METHOD)
|
547
|
+
/* True if TLS1_1 is not available */
|
548
|
+
rb_define_const(mod, "OPENSSL_NO_TLS1_1", Qtrue);
|
549
|
+
#else
|
550
|
+
rb_define_const(mod, "OPENSSL_NO_TLS1_1", Qfalse);
|
551
|
+
#endif
|
517
552
|
|
518
553
|
rb_define_singleton_method(mod, "check", noop, 0);
|
519
554
|
|
File without changes
|
@@ -34,9 +34,9 @@ private static short[] init__puma_parser_key_offsets_0()
|
|
34
34
|
{
|
35
35
|
return new short [] {
|
36
36
|
0, 0, 8, 17, 27, 29, 30, 31, 32, 33, 34, 36,
|
37
|
-
39, 41, 44, 45, 61, 62, 78,
|
38
|
-
|
39
|
-
|
37
|
+
39, 41, 44, 45, 61, 62, 78, 85, 91, 99, 107, 117,
|
38
|
+
125, 134, 142, 150, 159, 168, 177, 186, 195, 204, 213, 222,
|
39
|
+
231, 240, 249, 258, 267, 276, 285, 294, 303, 312, 313
|
40
40
|
};
|
41
41
|
}
|
42
42
|
|
@@ -52,26 +52,27 @@ private static char[] init__puma_parser_trans_keys_0()
|
|
52
52
|
46, 48, 57, 48, 57, 13, 48, 57, 10, 13, 33, 124,
|
53
53
|
126, 35, 39, 42, 43, 45, 46, 48, 57, 65, 90, 94,
|
54
54
|
122, 10, 33, 58, 124, 126, 35, 39, 42, 43, 45, 46,
|
55
|
-
48, 57, 65, 90, 94, 122,
|
56
|
-
|
57
|
-
60, 62, 127, 0, 31, 34, 35, 43,
|
58
|
-
57, 65, 90, 97, 122, 32, 34, 35,
|
59
|
-
31, 32, 34, 35, 60, 62, 63, 127,
|
60
|
-
|
61
|
-
|
62
|
-
36, 95, 45, 46, 48, 57, 65, 90,
|
63
|
-
46, 48, 57, 65, 90, 32, 36, 95,
|
64
|
-
65, 90, 32, 36, 95, 45, 46, 48,
|
65
|
-
36, 95, 45, 46, 48, 57, 65, 90,
|
66
|
-
46, 48, 57, 65, 90, 32, 36, 95,
|
67
|
-
65, 90, 32, 36, 95, 45, 46, 48,
|
68
|
-
36, 95, 45, 46, 48, 57, 65, 90,
|
69
|
-
46, 48, 57, 65, 90, 32, 36, 95,
|
70
|
-
65, 90, 32, 36, 95, 45, 46, 48,
|
71
|
-
36, 95, 45, 46, 48, 57, 65, 90,
|
72
|
-
46, 48, 57, 65, 90, 32, 36, 95,
|
73
|
-
65, 90, 32, 36, 95, 45, 46, 48,
|
74
|
-
36, 95, 45, 46, 48, 57, 65, 90,
|
55
|
+
48, 57, 65, 90, 94, 122, 13, 32, 127, 0, 8, 10,
|
56
|
+
31, 13, 127, 0, 8, 10, 31, 32, 60, 62, 127, 0,
|
57
|
+
31, 34, 35, 32, 60, 62, 127, 0, 31, 34, 35, 43,
|
58
|
+
58, 45, 46, 48, 57, 65, 90, 97, 122, 32, 34, 35,
|
59
|
+
60, 62, 127, 0, 31, 32, 34, 35, 60, 62, 63, 127,
|
60
|
+
0, 31, 32, 34, 35, 60, 62, 127, 0, 31, 32, 34,
|
61
|
+
35, 60, 62, 127, 0, 31, 32, 36, 95, 45, 46, 48,
|
62
|
+
57, 65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90,
|
63
|
+
32, 36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95,
|
64
|
+
45, 46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48,
|
65
|
+
57, 65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90,
|
66
|
+
32, 36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95,
|
67
|
+
45, 46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48,
|
68
|
+
57, 65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90,
|
69
|
+
32, 36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95,
|
70
|
+
45, 46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48,
|
71
|
+
57, 65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90,
|
72
|
+
32, 36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95,
|
73
|
+
45, 46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48,
|
74
|
+
57, 65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90,
|
75
|
+
32, 0
|
75
76
|
};
|
76
77
|
}
|
77
78
|
|
@@ -95,7 +96,7 @@ private static byte[] init__puma_parser_range_lengths_0()
|
|
95
96
|
{
|
96
97
|
return new byte [] {
|
97
98
|
0, 3, 3, 3, 0, 0, 0, 0, 0, 0, 1, 1,
|
98
|
-
1, 1, 0, 6, 0, 6,
|
99
|
+
1, 1, 0, 6, 0, 6, 2, 2, 2, 2, 4, 1,
|
99
100
|
1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
100
101
|
3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0
|
101
102
|
};
|
@@ -108,9 +109,9 @@ private static short[] init__puma_parser_index_offsets_0()
|
|
108
109
|
{
|
109
110
|
return new short [] {
|
110
111
|
0, 0, 6, 13, 21, 24, 26, 28, 30, 32, 34, 36,
|
111
|
-
39, 41, 44, 46, 57, 59, 70,
|
112
|
-
|
113
|
-
|
112
|
+
39, 41, 44, 46, 57, 59, 70, 76, 81, 88, 95, 102,
|
113
|
+
110, 119, 127, 135, 142, 149, 156, 163, 170, 177, 184, 191,
|
114
|
+
198, 205, 212, 219, 226, 233, 240, 247, 254, 261, 263
|
114
115
|
};
|
115
116
|
}
|
116
117
|
|
@@ -125,23 +126,24 @@ private static byte[] init__puma_parser_indicies_0()
|
|
125
126
|
10, 1, 11, 1, 12, 1, 13, 1, 14, 1, 15, 1,
|
126
127
|
16, 15, 1, 17, 1, 18, 17, 1, 19, 1, 20, 21,
|
127
128
|
21, 21, 21, 21, 21, 21, 21, 21, 1, 22, 1, 23,
|
128
|
-
24, 23, 23, 23, 23, 23, 23, 23, 23, 1,
|
129
|
-
|
130
|
-
1, 31, 32, 1, 1, 1, 1, 1, 33, 34,
|
131
|
-
34, 34, 34, 1, 8, 1, 9, 1, 1, 1,
|
132
|
-
|
133
|
-
1, 1, 1, 1, 41, 43, 1, 45, 1, 1,
|
134
|
-
|
135
|
-
47, 47, 1, 2, 48, 48, 48, 48, 48, 1,
|
136
|
-
|
137
|
-
|
138
|
-
52, 1, 2, 53, 53, 53, 53, 53, 1, 2,
|
139
|
-
54, 54, 54, 1, 2, 55, 55, 55, 55, 55,
|
140
|
-
|
141
|
-
|
142
|
-
59, 59, 1, 2, 60, 60, 60, 60, 60, 1,
|
143
|
-
|
144
|
-
|
129
|
+
24, 23, 23, 23, 23, 23, 23, 23, 23, 1, 26, 27,
|
130
|
+
1, 1, 1, 25, 29, 1, 1, 1, 28, 30, 1, 1,
|
131
|
+
1, 1, 1, 31, 32, 1, 1, 1, 1, 1, 33, 34,
|
132
|
+
35, 34, 34, 34, 34, 1, 8, 1, 9, 1, 1, 1,
|
133
|
+
1, 35, 36, 1, 38, 1, 1, 39, 1, 1, 37, 40,
|
134
|
+
1, 42, 1, 1, 1, 1, 41, 43, 1, 45, 1, 1,
|
135
|
+
1, 1, 44, 2, 46, 46, 46, 46, 46, 1, 2, 47,
|
136
|
+
47, 47, 47, 47, 1, 2, 48, 48, 48, 48, 48, 1,
|
137
|
+
2, 49, 49, 49, 49, 49, 1, 2, 50, 50, 50, 50,
|
138
|
+
50, 1, 2, 51, 51, 51, 51, 51, 1, 2, 52, 52,
|
139
|
+
52, 52, 52, 1, 2, 53, 53, 53, 53, 53, 1, 2,
|
140
|
+
54, 54, 54, 54, 54, 1, 2, 55, 55, 55, 55, 55,
|
141
|
+
1, 2, 56, 56, 56, 56, 56, 1, 2, 57, 57, 57,
|
142
|
+
57, 57, 1, 2, 58, 58, 58, 58, 58, 1, 2, 59,
|
143
|
+
59, 59, 59, 59, 1, 2, 60, 60, 60, 60, 60, 1,
|
144
|
+
2, 61, 61, 61, 61, 61, 1, 2, 62, 62, 62, 62,
|
145
|
+
62, 1, 2, 63, 63, 63, 63, 63, 1, 2, 1, 1,
|
146
|
+
0
|
145
147
|
};
|
146
148
|
}
|
147
149
|
|
@@ -217,7 +219,7 @@ static final int puma_parser_en_main = 1;
|
|
217
219
|
cs = puma_parser_start;
|
218
220
|
}
|
219
221
|
|
220
|
-
// line
|
222
|
+
// line 88 "ext/puma_http11/http11_parser.java.rl"
|
221
223
|
|
222
224
|
body_start = 0;
|
223
225
|
content_len = 0;
|
@@ -420,7 +422,7 @@ case 5:
|
|
420
422
|
break; }
|
421
423
|
}
|
422
424
|
|
423
|
-
// line
|
425
|
+
// line 114 "ext/puma_http11/http11_parser.java.rl"
|
424
426
|
|
425
427
|
parser.cs = cs;
|
426
428
|
parser.nread += (p - off);
|
File without changes
|
File without changes
|
File without changes
|
data/lib/puma/accept_nonblock.rb
CHANGED
File without changes
|
data/lib/puma/app/status.rb
CHANGED
File without changes
|
data/lib/puma/binder.rb
CHANGED
File without changes
|
data/lib/puma/cli.rb
CHANGED
File without changes
|
data/lib/puma/client.rb
CHANGED
@@ -23,6 +23,8 @@ module Puma
|
|
23
23
|
|
24
24
|
class ConnectionError < RuntimeError; end
|
25
25
|
|
26
|
+
class HttpParserError501 < IOError; end
|
27
|
+
|
26
28
|
# An instance of this class represents a unique request from a client.
|
27
29
|
# For example, this could be a web request from a browser or from CURL.
|
28
30
|
#
|
@@ -35,7 +37,21 @@ module Puma
|
|
35
37
|
# Instances of this class are responsible for knowing if
|
36
38
|
# the header and body are fully buffered via the `try_to_finish` method.
|
37
39
|
# They can be used to "time out" a response via the `timeout_at` reader.
|
40
|
+
#
|
38
41
|
class Client
|
42
|
+
|
43
|
+
# this tests all values but the last, which must be chunked
|
44
|
+
ALLOWED_TRANSFER_ENCODING = %w[compress deflate gzip].freeze
|
45
|
+
|
46
|
+
# chunked body validation
|
47
|
+
CHUNK_SIZE_INVALID = /[^\h]/.freeze
|
48
|
+
CHUNK_VALID_ENDING = "\r\n".freeze
|
49
|
+
|
50
|
+
# Content-Length header value validation
|
51
|
+
CONTENT_LENGTH_VALUE_INVALID = /[^\d]/.freeze
|
52
|
+
|
53
|
+
TE_ERR_MSG = 'Invalid Transfer-Encoding'
|
54
|
+
|
39
55
|
# The object used for a request with no body. All requests with
|
40
56
|
# no body share this one object since it has no state.
|
41
57
|
EmptyBody = NullIO.new
|
@@ -284,16 +300,27 @@ module Puma
|
|
284
300
|
body = @parser.body
|
285
301
|
|
286
302
|
te = @env[TRANSFER_ENCODING2]
|
287
|
-
|
288
303
|
if te
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
304
|
+
te_lwr = te.downcase
|
305
|
+
if te.include? ','
|
306
|
+
te_ary = te_lwr.split ','
|
307
|
+
te_count = te_ary.count CHUNKED
|
308
|
+
te_valid = te_ary[0..-2].all? { |e| ALLOWED_TRANSFER_ENCODING.include? e }
|
309
|
+
if te_ary.last == CHUNKED && te_count == 1 && te_valid
|
310
|
+
@env.delete TRANSFER_ENCODING2
|
311
|
+
return setup_chunked_body body
|
312
|
+
elsif te_count >= 1
|
313
|
+
raise HttpParserError , "#{TE_ERR_MSG}, multiple chunked: '#{te}'"
|
314
|
+
elsif !te_valid
|
315
|
+
raise HttpParserError501, "#{TE_ERR_MSG}, unknown value: '#{te}'"
|
294
316
|
end
|
295
|
-
elsif
|
296
|
-
|
317
|
+
elsif te_lwr == CHUNKED
|
318
|
+
@env.delete TRANSFER_ENCODING2
|
319
|
+
return setup_chunked_body body
|
320
|
+
elsif ALLOWED_TRANSFER_ENCODING.include? te_lwr
|
321
|
+
raise HttpParserError , "#{TE_ERR_MSG}, single value must be chunked: '#{te}'"
|
322
|
+
else
|
323
|
+
raise HttpParserError501 , "#{TE_ERR_MSG}, unknown value: '#{te}'"
|
297
324
|
end
|
298
325
|
end
|
299
326
|
|
@@ -301,7 +328,12 @@ module Puma
|
|
301
328
|
|
302
329
|
cl = @env[CONTENT_LENGTH]
|
303
330
|
|
304
|
-
|
331
|
+
if cl
|
332
|
+
# cannot contain characters that are not \d
|
333
|
+
if cl =~ CONTENT_LENGTH_VALUE_INVALID
|
334
|
+
raise HttpParserError, "Invalid Content-Length: #{cl.inspect}"
|
335
|
+
end
|
336
|
+
else
|
305
337
|
@buffer = body.empty? ? nil : body
|
306
338
|
@body = EmptyBody
|
307
339
|
set_ready
|
@@ -450,7 +482,13 @@ module Puma
|
|
450
482
|
while !io.eof?
|
451
483
|
line = io.gets
|
452
484
|
if line.end_with?("\r\n")
|
453
|
-
|
485
|
+
# Puma doesn't process chunk extensions, but should parse if they're
|
486
|
+
# present, which is the reason for the semicolon regex
|
487
|
+
chunk_hex = line.strip[/\A[^;]+/]
|
488
|
+
if chunk_hex =~ CHUNK_SIZE_INVALID
|
489
|
+
raise HttpParserError, "Invalid chunk size: '#{chunk_hex}'"
|
490
|
+
end
|
491
|
+
len = chunk_hex.to_i(16)
|
454
492
|
if len == 0
|
455
493
|
@in_last_chunk = true
|
456
494
|
@body.rewind
|
@@ -481,7 +519,12 @@ module Puma
|
|
481
519
|
|
482
520
|
case
|
483
521
|
when got == len
|
484
|
-
|
522
|
+
# proper chunked segment must end with "\r\n"
|
523
|
+
if part.end_with? CHUNK_VALID_ENDING
|
524
|
+
write_chunk(part[0..-3]) # to skip the ending \r\n
|
525
|
+
else
|
526
|
+
raise HttpParserError, "Chunk size mismatch"
|
527
|
+
end
|
485
528
|
when got <= len - 2
|
486
529
|
write_chunk(part)
|
487
530
|
@partial_part_left = len - part.size
|
data/lib/puma/cluster.rb
CHANGED
File without changes
|
data/lib/puma/commonlogger.rb
CHANGED
File without changes
|
data/lib/puma/configuration.rb
CHANGED
File without changes
|
data/lib/puma/const.rb
CHANGED
@@ -76,7 +76,7 @@ module Puma
|
|
76
76
|
508 => 'Loop Detected',
|
77
77
|
510 => 'Not Extended',
|
78
78
|
511 => 'Network Authentication Required'
|
79
|
-
}
|
79
|
+
}.freeze
|
80
80
|
|
81
81
|
# For some HTTP status codes the client only expects headers.
|
82
82
|
#
|
@@ -85,7 +85,7 @@ module Puma
|
|
85
85
|
204 => true,
|
86
86
|
205 => true,
|
87
87
|
304 => true
|
88
|
-
}
|
88
|
+
}.freeze
|
89
89
|
|
90
90
|
# Frequently used constants when constructing requests or responses. Many times
|
91
91
|
# the constant just refers to a string with the same contents. Using these constants
|
@@ -100,7 +100,7 @@ module Puma
|
|
100
100
|
# too taxing on performance.
|
101
101
|
module Const
|
102
102
|
|
103
|
-
PUMA_VERSION = VERSION = "4.3.
|
103
|
+
PUMA_VERSION = VERSION = "4.3.12".freeze
|
104
104
|
CODE_NAME = "Mysterious Traveller".freeze
|
105
105
|
PUMA_SERVER_STRING = ['puma', PUMA_VERSION, CODE_NAME].join(' ').freeze
|
106
106
|
|
@@ -144,9 +144,11 @@ module Puma
|
|
144
144
|
408 => "HTTP/1.1 408 Request Timeout\r\nConnection: close\r\nServer: Puma #{PUMA_VERSION}\r\n\r\n".freeze,
|
145
145
|
# Indicate that there was an internal error, obviously.
|
146
146
|
500 => "HTTP/1.1 500 Internal Server Error\r\n\r\n".freeze,
|
147
|
+
# Incorrect or invalid header value
|
148
|
+
501 => "HTTP/1.1 501 Not Implemented\r\n\r\n".freeze,
|
147
149
|
# A common header for indicating the server is too busy. Not used yet.
|
148
150
|
503 => "HTTP/1.1 503 Service Unavailable\r\n\r\nBUSY".freeze
|
149
|
-
}
|
151
|
+
}.freeze
|
150
152
|
|
151
153
|
# The basic max request size we'll try to read.
|
152
154
|
CHUNK_SIZE = 16 * 1024
|
data/lib/puma/control_cli.rb
CHANGED
File without changes
|
data/lib/puma/detect.rb
CHANGED
File without changes
|
data/lib/puma/dsl.rb
CHANGED
File without changes
|
data/lib/puma/events.rb
CHANGED
File without changes
|
data/lib/puma/io_buffer.rb
CHANGED
File without changes
|
data/lib/puma/jruby_restart.rb
CHANGED
File without changes
|
data/lib/puma/launcher.rb
CHANGED
File without changes
|
File without changes
|
data/lib/puma/minissl.rb
CHANGED
File without changes
|
data/lib/puma/null_io.rb
CHANGED
File without changes
|
File without changes
|
data/lib/puma/plugin.rb
CHANGED
File without changes
|
data/lib/puma/rack/builder.rb
CHANGED
File without changes
|
data/lib/puma/rack/urlmap.rb
CHANGED
File without changes
|
data/lib/puma/rack_default.rb
CHANGED
File without changes
|
data/lib/puma/reactor.rb
CHANGED
File without changes
|
data/lib/puma/runner.rb
CHANGED
File without changes
|
data/lib/puma/server.rb
CHANGED
@@ -320,6 +320,10 @@ module Puma
|
|
320
320
|
client.write_error(400)
|
321
321
|
client.close
|
322
322
|
|
323
|
+
@events.parse_error self, client.env, e
|
324
|
+
rescue HttpParserError501 => e
|
325
|
+
client.write_error(501)
|
326
|
+
client.close
|
323
327
|
@events.parse_error self, client.env, e
|
324
328
|
rescue ConnectionError, EOFError
|
325
329
|
client.close
|
@@ -530,7 +534,12 @@ module Puma
|
|
530
534
|
client.write_error(400)
|
531
535
|
|
532
536
|
@events.parse_error self, client.env, e
|
537
|
+
rescue HttpParserError501 => e
|
538
|
+
lowlevel_error(e, client.env)
|
539
|
+
|
540
|
+
client.write_error(501)
|
533
541
|
|
542
|
+
@events.parse_error self, client.env, e
|
534
543
|
# Server error
|
535
544
|
rescue StandardError => e
|
536
545
|
lowlevel_error(e, client.env)
|
@@ -873,11 +882,14 @@ module Puma
|
|
873
882
|
end
|
874
883
|
|
875
884
|
ensure
|
876
|
-
|
885
|
+
begin
|
886
|
+
uncork_socket client
|
877
887
|
|
878
|
-
|
879
|
-
|
880
|
-
|
888
|
+
body.close
|
889
|
+
req.tempfile.unlink if req.tempfile
|
890
|
+
ensure
|
891
|
+
res_body.close if res_body.respond_to? :close
|
892
|
+
end
|
881
893
|
|
882
894
|
after_reply.each { |o| o.call }
|
883
895
|
end
|
data/lib/puma/single.rb
CHANGED
File without changes
|
data/lib/puma/state_file.rb
CHANGED
File without changes
|
data/lib/puma/tcp_logger.rb
CHANGED
File without changes
|
data/lib/puma/thread_pool.rb
CHANGED
File without changes
|
data/lib/puma/util.rb
CHANGED
File without changes
|
data/lib/puma.rb
CHANGED
File without changes
|
data/lib/rack/handler/puma.rb
CHANGED
File without changes
|
data/tools/docker/Dockerfile
CHANGED
File without changes
|
data/tools/jungle/README.md
CHANGED
File without changes
|
File without changes
|
data/tools/jungle/rc.d/README.md
CHANGED
File without changes
|
data/tools/jungle/rc.d/puma.conf
CHANGED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
data/tools/trickletest.rb
CHANGED
File without changes
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: puma
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.3.
|
4
|
+
version: 4.3.12
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Evan Phoenix
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 1980-01-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nio4r
|
@@ -136,7 +136,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
136
136
|
- !ruby/object:Gem::Version
|
137
137
|
version: '0'
|
138
138
|
requirements: []
|
139
|
-
rubygems_version: 3.2.
|
139
|
+
rubygems_version: 3.2.26
|
140
140
|
signing_key:
|
141
141
|
specification_version: 4
|
142
142
|
summary: Puma is a simple, fast, threaded, and highly concurrent HTTP 1.1 server for
|