puma 4.3.6 → 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.

Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +31 -0
  3. data/LICENSE +0 -0
  4. data/README.md +0 -0
  5. data/bin/puma-wild +0 -0
  6. data/docs/architecture.md +0 -0
  7. data/docs/deployment.md +0 -0
  8. data/docs/images/puma-connection-flow-no-reactor.png +0 -0
  9. data/docs/images/puma-connection-flow.png +0 -0
  10. data/docs/images/puma-general-arch.png +0 -0
  11. data/docs/nginx.md +0 -0
  12. data/docs/plugins.md +0 -0
  13. data/docs/restart.md +0 -0
  14. data/docs/signals.md +0 -0
  15. data/docs/systemd.md +0 -0
  16. data/docs/tcp_mode.md +0 -0
  17. data/ext/puma_http11/PumaHttp11Service.java +0 -0
  18. data/ext/puma_http11/ext_help.h +0 -0
  19. data/ext/puma_http11/extconf.rb +9 -1
  20. data/ext/puma_http11/http11_parser.c +23 -10
  21. data/ext/puma_http11/http11_parser.h +0 -0
  22. data/ext/puma_http11/http11_parser.java.rl +0 -0
  23. data/ext/puma_http11/http11_parser.rl +0 -0
  24. data/ext/puma_http11/http11_parser_common.rl +1 -1
  25. data/ext/puma_http11/io_buffer.c +0 -0
  26. data/ext/puma_http11/mini_ssl.c +82 -47
  27. data/ext/puma_http11/org/jruby/puma/Http11.java +0 -0
  28. data/ext/puma_http11/org/jruby/puma/Http11Parser.java +48 -46
  29. data/ext/puma_http11/org/jruby/puma/IOBuffer.java +0 -0
  30. data/ext/puma_http11/org/jruby/puma/MiniSSL.java +0 -0
  31. data/ext/puma_http11/puma_http11.c +0 -0
  32. data/lib/puma/accept_nonblock.rb +0 -0
  33. data/lib/puma/app/status.rb +0 -0
  34. data/lib/puma/binder.rb +0 -0
  35. data/lib/puma/cli.rb +0 -0
  36. data/lib/puma/client.rb +74 -19
  37. data/lib/puma/cluster.rb +0 -0
  38. data/lib/puma/commonlogger.rb +0 -0
  39. data/lib/puma/configuration.rb +0 -0
  40. data/lib/puma/const.rb +6 -4
  41. data/lib/puma/control_cli.rb +0 -0
  42. data/lib/puma/detect.rb +0 -0
  43. data/lib/puma/dsl.rb +0 -0
  44. data/lib/puma/events.rb +0 -0
  45. data/lib/puma/io_buffer.rb +0 -0
  46. data/lib/puma/jruby_restart.rb +0 -0
  47. data/lib/puma/launcher.rb +0 -0
  48. data/lib/puma/minissl/context_builder.rb +0 -0
  49. data/lib/puma/minissl.rb +0 -0
  50. data/lib/puma/null_io.rb +0 -0
  51. data/lib/puma/plugin/tmp_restart.rb +0 -0
  52. data/lib/puma/plugin.rb +0 -0
  53. data/lib/puma/rack/builder.rb +0 -0
  54. data/lib/puma/rack/urlmap.rb +0 -0
  55. data/lib/puma/rack_default.rb +0 -0
  56. data/lib/puma/reactor.rb +0 -0
  57. data/lib/puma/runner.rb +0 -0
  58. data/lib/puma/server.rb +30 -13
  59. data/lib/puma/single.rb +0 -0
  60. data/lib/puma/state_file.rb +0 -0
  61. data/lib/puma/tcp_logger.rb +0 -0
  62. data/lib/puma/thread_pool.rb +0 -0
  63. data/lib/puma/util.rb +0 -0
  64. data/lib/puma.rb +0 -0
  65. data/lib/rack/handler/puma.rb +0 -0
  66. data/tools/docker/Dockerfile +0 -0
  67. data/tools/jungle/README.md +0 -0
  68. data/tools/jungle/init.d/README.md +0 -0
  69. data/tools/jungle/rc.d/README.md +0 -0
  70. data/tools/jungle/rc.d/puma.conf +0 -0
  71. data/tools/jungle/upstart/README.md +0 -0
  72. data/tools/jungle/upstart/puma-manager.conf +0 -0
  73. data/tools/jungle/upstart/puma.conf +0 -0
  74. data/tools/trickletest.rb +0 -0
  75. metadata +3 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d378ab70a4eac21fe4bf571b95b655d6cbc590b2b91ac323f849986bf8f7ad6c
4
- data.tar.gz: 1b288cc39f5d80119dde26e844490e572b5f1043060060a1a1d70180743123c3
3
+ metadata.gz: 55de061927f854a6aa5886c0ef6573a6a95306afadf4eb156fbf3e59d54f3574
4
+ data.tar.gz: 9b58b994708cae549af93d92568f5111eb831404f9f189662ea73ff5c914ece3
5
5
  SHA512:
6
- metadata.gz: b63ddad40bdeae9c86d62af5bf044238e273cbf8e95ff944d7b0a736dd39532dfe3b562a77c97b14f86d8e3f916b7cb94ccdbf898e75c4088d075d20e83744d5
7
- data.tar.gz: abc975210626407c096848540f068a9731ecdc5191327b3ad87355ef4b88b6ac2605ccc7e31ca5398cd787cf9a34efdffc501afe61a2542cc322768af7b26830
6
+ metadata.gz: a5208ba5fc102a2d5df875490bf99afdf95aa2614a82503806aedf13dcf58c61cd62551aece57762bc6c54f5ae71a3517efb4b17d4d9eace27f99270ec1b9f6e
7
+ data.tar.gz: 5555c0290a7db01cdddfb19555caaa9b4d20085ef28297d436f3f37c2e5732d53f754d2ced9f76ffbc061c20e401ae68fd4819e630e12f17d335e6464dc42615
data/History.md CHANGED
@@ -1,8 +1,39 @@
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
+
16
+ ## 4.3.9 / 2021-10-12
17
+
18
+ * Security
19
+ * Do not allow LF as a line ending in a header (CVE-2021-41136)
20
+
21
+ ## 4.3.8 / 2021-05-11
22
+
23
+ * Security
24
+ * Close keepalive connections after the maximum number of fast inlined requests (#2625)
25
+
26
+ ## 4.3.7 / 2020-11-30
27
+
28
+ * Bugfixes
29
+ * Backport set CONTENT_LENGTH for chunked requests (Originally: #2287, backport: #2496)
30
+
1
31
  ## 4.3.6 / 2020-09-05
2
32
 
3
33
  * Bugfixes
4
34
  * Explicitly include ctype.h to fix compilation warning and build error on macOS with Xcode 12 (#2304)
5
35
  * Don't require json at boot (#2269)
36
+ * Set `CONTENT_LENGTH` for chunked requests (#2287)
6
37
 
7
38
  ## 4.3.4/4.3.5 and 3.12.5/3.12.6 / 2020-05-22
8
39
 
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
File without changes
@@ -1,7 +1,7 @@
1
1
  require 'mkmf'
2
2
 
3
3
  dir_config("puma_http11")
4
- if RUBY_PLATFORM[/mingw32/]
4
+ if $mingw && RUBY_VERSION >= '2.4'
5
5
  append_cflags '-D_FORTIFY_SOURCE=2'
6
6
  append_ldflags '-fstack-protector'
7
7
  have_library 'ssp'
@@ -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
 
@@ -430,7 +430,13 @@ case 18:
430
430
  switch( (*p) ) {
431
431
  case 13: goto tr26;
432
432
  case 32: goto tr27;
433
+ case 127: goto st0;
433
434
  }
435
+ if ( (*p) > 8 ) {
436
+ if ( 10 <= (*p) && (*p) <= 31 )
437
+ goto st0;
438
+ } else if ( (*p) >= 0 )
439
+ goto st0;
434
440
  goto tr25;
435
441
  tr25:
436
442
  #line 44 "ext/puma_http11/http11_parser.rl"
@@ -440,9 +446,16 @@ st19:
440
446
  if ( ++p == pe )
441
447
  goto _test_eof19;
442
448
  case 19:
443
- #line 442 "ext/puma_http11/http11_parser.c"
444
- if ( (*p) == 13 )
445
- goto tr29;
449
+ #line 448 "ext/puma_http11/http11_parser.c"
450
+ switch( (*p) ) {
451
+ case 13: goto tr29;
452
+ case 127: goto st0;
453
+ }
454
+ if ( (*p) > 8 ) {
455
+ if ( 10 <= (*p) && (*p) <= 31 )
456
+ goto st0;
457
+ } else if ( (*p) >= 0 )
458
+ goto st0;
446
459
  goto st19;
447
460
  tr9:
448
461
  #line 51 "ext/puma_http11/http11_parser.rl"
@@ -486,7 +499,7 @@ st20:
486
499
  if ( ++p == pe )
487
500
  goto _test_eof20;
488
501
  case 20:
489
- #line 488 "ext/puma_http11/http11_parser.c"
502
+ #line 501 "ext/puma_http11/http11_parser.c"
490
503
  switch( (*p) ) {
491
504
  case 32: goto tr31;
492
505
  case 60: goto st0;
@@ -507,7 +520,7 @@ st21:
507
520
  if ( ++p == pe )
508
521
  goto _test_eof21;
509
522
  case 21:
510
- #line 509 "ext/puma_http11/http11_parser.c"
523
+ #line 522 "ext/puma_http11/http11_parser.c"
511
524
  switch( (*p) ) {
512
525
  case 32: goto tr33;
513
526
  case 60: goto st0;
@@ -528,7 +541,7 @@ st22:
528
541
  if ( ++p == pe )
529
542
  goto _test_eof22;
530
543
  case 22:
531
- #line 530 "ext/puma_http11/http11_parser.c"
544
+ #line 543 "ext/puma_http11/http11_parser.c"
532
545
  switch( (*p) ) {
533
546
  case 43: goto st22;
534
547
  case 58: goto st23;
@@ -553,7 +566,7 @@ st23:
553
566
  if ( ++p == pe )
554
567
  goto _test_eof23;
555
568
  case 23:
556
- #line 555 "ext/puma_http11/http11_parser.c"
569
+ #line 568 "ext/puma_http11/http11_parser.c"
557
570
  switch( (*p) ) {
558
571
  case 32: goto tr8;
559
572
  case 34: goto st0;
@@ -573,7 +586,7 @@ st24:
573
586
  if ( ++p == pe )
574
587
  goto _test_eof24;
575
588
  case 24:
576
- #line 575 "ext/puma_http11/http11_parser.c"
589
+ #line 588 "ext/puma_http11/http11_parser.c"
577
590
  switch( (*p) ) {
578
591
  case 32: goto tr37;
579
592
  case 34: goto st0;
@@ -596,7 +609,7 @@ st25:
596
609
  if ( ++p == pe )
597
610
  goto _test_eof25;
598
611
  case 25:
599
- #line 598 "ext/puma_http11/http11_parser.c"
612
+ #line 611 "ext/puma_http11/http11_parser.c"
600
613
  switch( (*p) ) {
601
614
  case 32: goto tr41;
602
615
  case 34: goto st0;
@@ -616,7 +629,7 @@ st26:
616
629
  if ( ++p == pe )
617
630
  goto _test_eof26;
618
631
  case 26:
619
- #line 618 "ext/puma_http11/http11_parser.c"
632
+ #line 631 "ext/puma_http11/http11_parser.c"
620
633
  switch( (*p) ) {
621
634
  case 32: goto tr44;
622
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 = any* >start_value %write_value;
46
+ field_value = ( (any -- CTL) | "\t" )* >start_value %write_value;
47
47
 
48
48
  message_header = field_name ":" " "* field_value :> CRLF;
49
49
 
File without changes
@@ -62,44 +62,65 @@ ms_conn* engine_alloc(VALUE klass, VALUE* obj) {
62
62
  return conn;
63
63
  }
64
64
 
65
- DH *get_dh1024() {
66
- /* `openssl dhparam 1024 -C`
65
+ DH *get_dh2048(void) {
66
+ /* `openssl dhparam -C 2048`
67
67
  * -----BEGIN DH PARAMETERS-----
68
- * MIGHAoGBALPwcEv0OstmQCZdfHw0N5r+07lmXMxkpQacy1blwj0LUqC+Divp6pBk
69
- * usTJ9W2/dOYr1X7zi6yXNLp4oLzc/31PUL3D9q8CpGS7vPz5gijKSw9BwCTT5z9+
70
- * KF9v46qw8XqT5HHV87sWFlGQcVFq+pEkA2kPikkKZ/X/CCcpCAV7AgEC
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 dh1024_p[] = {
74
- 0xB3,0xF0,0x70,0x4B,0xF4,0x3A,0xCB,0x66,0x40,0x26,0x5D,0x7C,
75
- 0x7C,0x34,0x37,0x9A,0xFE,0xD3,0xB9,0x66,0x5C,0xCC,0x64,0xA5,
76
- 0x06,0x9C,0xCB,0x56,0xE5,0xC2,0x3D,0x0B,0x52,0xA0,0xBE,0x0E,
77
- 0x2B,0xE9,0xEA,0x90,0x64,0xBA,0xC4,0xC9,0xF5,0x6D,0xBF,0x74,
78
- 0xE6,0x2B,0xD5,0x7E,0xF3,0x8B,0xAC,0x97,0x34,0xBA,0x78,0xA0,
79
- 0xBC,0xDC,0xFF,0x7D,0x4F,0x50,0xBD,0xC3,0xF6,0xAF,0x02,0xA4,
80
- 0x64,0xBB,0xBC,0xFC,0xF9,0x82,0x28,0xCA,0x4B,0x0F,0x41,0xC0,
81
- 0x24,0xD3,0xE7,0x3F,0x7E,0x28,0x5F,0x6F,0xE3,0xAA,0xB0,0xF1,
82
- 0x7A,0x93,0xE4,0x71,0xD5,0xF3,0xBB,0x16,0x16,0x51,0x90,0x71,
83
- 0x51,0x6A,0xFA,0x91,0x24,0x03,0x69,0x0F,0x8A,0x49,0x0A,0x67,
84
- 0xF5,0xFF,0x08,0x27,0x29,0x08,0x05,0x7B
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 dh1024_g[] = { 0x02 };
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(dh1024_p, sizeof(dh1024_p), NULL);
93
- dh->g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL);
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
- BIGNUM *p, *g;
101
- p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL);
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
- DH *dh = get_dh1024();
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, 80, 81, 89, 97, 107,
38
- 115, 124, 132, 140, 149, 158, 167, 176, 185, 194, 203, 212,
39
- 221, 230, 239, 248, 257, 266, 275, 284, 293, 302, 303
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, 13, 32, 13, 32, 60, 62,
56
- 127, 0, 31, 34, 35, 32, 60, 62, 127, 0, 31, 34,
57
- 35, 43, 58, 45, 46, 48, 57, 65, 90, 97, 122, 32,
58
- 34, 35, 60, 62, 127, 0, 31, 32, 34, 35, 60, 62,
59
- 63, 127, 0, 31, 32, 34, 35, 60, 62, 127, 0, 31,
60
- 32, 34, 35, 60, 62, 127, 0, 31, 32, 36, 95, 45,
61
- 46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48, 57,
62
- 65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90, 32,
63
- 36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95, 45,
64
- 46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48, 57,
65
- 65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90, 32,
66
- 36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95, 45,
67
- 46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48, 57,
68
- 65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90, 32,
69
- 36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95, 45,
70
- 46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48, 57,
71
- 65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90, 32,
72
- 36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95, 45,
73
- 46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48, 57,
74
- 65, 90, 32, 0
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
 
@@ -82,7 +83,7 @@ private static byte[] init__puma_parser_single_lengths_0()
82
83
  {
83
84
  return new byte [] {
84
85
  0, 2, 3, 4, 2, 1, 1, 1, 1, 1, 0, 1,
85
- 0, 1, 1, 4, 1, 4, 2, 1, 4, 4, 2, 6,
86
+ 0, 1, 1, 4, 1, 4, 3, 2, 4, 4, 2, 6,
86
87
  7, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3,
87
88
  3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 0
88
89
  };
@@ -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, 0, 0, 2, 2, 4, 1,
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, 73, 75, 82, 89, 96,
112
- 104, 113, 121, 129, 136, 143, 150, 157, 164, 171, 178, 185,
113
- 192, 199, 206, 213, 220, 227, 234, 241, 248, 255, 257
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
 
@@ -126,22 +127,23 @@ private static byte[] init__puma_parser_indicies_0()
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
129
  24, 23, 23, 23, 23, 23, 23, 23, 23, 1, 26, 27,
129
- 25, 29, 28, 30, 1, 1, 1, 1, 1, 31, 32, 1,
130
- 1, 1, 1, 1, 33, 34, 35, 34, 34, 34, 34, 1,
131
- 8, 1, 9, 1, 1, 1, 1, 35, 36, 1, 38, 1,
132
- 1, 39, 1, 1, 37, 40, 1, 42, 1, 1, 1, 1,
133
- 41, 43, 1, 45, 1, 1, 1, 1, 44, 2, 46, 46,
134
- 46, 46, 46, 1, 2, 47, 47, 47, 47, 47, 1, 2,
135
- 48, 48, 48, 48, 48, 1, 2, 49, 49, 49, 49, 49,
136
- 1, 2, 50, 50, 50, 50, 50, 1, 2, 51, 51, 51,
137
- 51, 51, 1, 2, 52, 52, 52, 52, 52, 1, 2, 53,
138
- 53, 53, 53, 53, 1, 2, 54, 54, 54, 54, 54, 1,
139
- 2, 55, 55, 55, 55, 55, 1, 2, 56, 56, 56, 56,
140
- 56, 1, 2, 57, 57, 57, 57, 57, 1, 2, 58, 58,
141
- 58, 58, 58, 1, 2, 59, 59, 59, 59, 59, 1, 2,
142
- 60, 60, 60, 60, 60, 1, 2, 61, 61, 61, 61, 61,
143
- 1, 2, 62, 62, 62, 62, 62, 1, 2, 63, 63, 63,
144
- 63, 63, 1, 2, 1, 1, 0
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 90 "ext/puma_http11/http11_parser.java.rl"
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 116 "ext/puma_http11/http11_parser.java.rl"
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
File without changes
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
@@ -153,7 +169,7 @@ module Puma
153
169
 
154
170
  begin
155
171
  data = @io.read_nonblock(CHUNK_SIZE)
156
- rescue Errno::EAGAIN
172
+ rescue IO::WaitReadable
157
173
  return false
158
174
  rescue SystemCallError, IOError, EOFError
159
175
  raise ConnectionError, "Connection error detected during read"
@@ -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
- if te.include?(",")
290
- te.split(",").each do |part|
291
- if CHUNKED.casecmp(part.strip) == 0
292
- return setup_chunked_body(body)
293
- end
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 CHUNKED.casecmp(te) == 0
296
- return setup_chunked_body(body)
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
- unless cl
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
@@ -351,7 +383,7 @@ module Puma
351
383
 
352
384
  begin
353
385
  chunk = @io.read_nonblock(want)
354
- rescue Errno::EAGAIN
386
+ rescue IO::WaitReadable
355
387
  return false
356
388
  rescue SystemCallError, IOError
357
389
  raise ConnectionError, "Connection error detected during read"
@@ -397,7 +429,10 @@ module Puma
397
429
  raise EOFError
398
430
  end
399
431
 
400
- return true if decode_chunk(chunk)
432
+ if decode_chunk(chunk)
433
+ @env[CONTENT_LENGTH] = @chunked_content_length
434
+ return true
435
+ end
401
436
  end
402
437
  end
403
438
 
@@ -410,19 +445,28 @@ module Puma
410
445
  @body.binmode
411
446
  @tempfile = @body
412
447
 
413
- return decode_chunk(body)
448
+ @chunked_content_length = 0
449
+
450
+ if decode_chunk(body)
451
+ @env[CONTENT_LENGTH] = @chunked_content_length
452
+ return true
453
+ end
454
+ end
455
+
456
+ def write_chunk(str)
457
+ @chunked_content_length += @body.write(str)
414
458
  end
415
459
 
416
460
  def decode_chunk(chunk)
417
461
  if @partial_part_left > 0
418
462
  if @partial_part_left <= chunk.size
419
463
  if @partial_part_left > 2
420
- @body << chunk[0..(@partial_part_left-3)] # skip the \r\n
464
+ write_chunk(chunk[0..(@partial_part_left-3)]) # skip the \r\n
421
465
  end
422
466
  chunk = chunk[@partial_part_left..-1]
423
467
  @partial_part_left = 0
424
468
  else
425
- @body << chunk if @partial_part_left > 2 # don't include the last \r\n
469
+ write_chunk(chunk) if @partial_part_left > 2 # don't include the last \r\n
426
470
  @partial_part_left -= chunk.size
427
471
  return false
428
472
  end
@@ -438,7 +482,13 @@ module Puma
438
482
  while !io.eof?
439
483
  line = io.gets
440
484
  if line.end_with?("\r\n")
441
- len = line.strip.to_i(16)
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)
442
492
  if len == 0
443
493
  @in_last_chunk = true
444
494
  @body.rewind
@@ -469,12 +519,17 @@ module Puma
469
519
 
470
520
  case
471
521
  when got == len
472
- @body << part[0..-3] # to skip the ending \r\n
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
473
528
  when got <= len - 2
474
- @body << part
529
+ write_chunk(part)
475
530
  @partial_part_left = len - part.size
476
531
  when got == len - 1 # edge where we get just \r but not \n
477
- @body << part[0..-2]
532
+ write_chunk(part[0..-2])
478
533
  @partial_part_left = len - part.size
479
534
  end
480
535
  else
data/lib/puma/cluster.rb CHANGED
File without changes
File without changes
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.6".freeze
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
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
File without changes
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
File without changes
File without changes
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
@@ -483,15 +487,20 @@ module Puma
483
487
 
484
488
  requests += 1
485
489
 
486
- check_for_more_data = @status == :run
490
+ # Closing keepalive sockets after they've made a reasonable
491
+ # number of requests allows Puma to service many connections
492
+ # fairly, even when the number of concurrent connections exceeds
493
+ # the size of the threadpool. It also allows cluster mode Pumas
494
+ # to keep load evenly distributed across workers, because clients
495
+ # are randomly assigned a new worker when opening a new connection.
496
+ #
497
+ # Previously, Puma would kick connections in this conditional back
498
+ # to the reactor. However, because this causes the todo set to increase
499
+ # in size, the wait_until_full mutex would never unlock, leaving
500
+ # any additional connections unserviced.
501
+ break if requests >= MAX_FAST_INLINE
487
502
 
488
- if requests >= MAX_FAST_INLINE
489
- # This will mean that reset will only try to use the data it already
490
- # has buffered and won't try to read more data. What this means is that
491
- # every client, independent of their request speed, gets treated like a slow
492
- # one once every MAX_FAST_INLINE requests.
493
- check_for_more_data = false
494
- end
503
+ check_for_more_data = @status == :run
495
504
 
496
505
  unless client.reset(check_for_more_data)
497
506
  close_socket = false
@@ -525,7 +534,12 @@ module Puma
525
534
  client.write_error(400)
526
535
 
527
536
  @events.parse_error self, client.env, e
537
+ rescue HttpParserError501 => e
538
+ lowlevel_error(e, client.env)
539
+
540
+ client.write_error(501)
528
541
 
542
+ @events.parse_error self, client.env, e
529
543
  # Server error
530
544
  rescue StandardError => e
531
545
  lowlevel_error(e, client.env)
@@ -694,7 +708,7 @@ module Puma
694
708
  to_add = {}
695
709
  end
696
710
 
697
- to_add[k.gsub(",", "_")] = v
711
+ to_add[k.tr(",", "_")] = v
698
712
  end
699
713
  end
700
714
 
@@ -868,11 +882,14 @@ module Puma
868
882
  end
869
883
 
870
884
  ensure
871
- uncork_socket client
885
+ begin
886
+ uncork_socket client
872
887
 
873
- body.close
874
- req.tempfile.unlink if req.tempfile
875
- res_body.close if res_body.respond_to? :close
888
+ body.close
889
+ req.tempfile.unlink if req.tempfile
890
+ ensure
891
+ res_body.close if res_body.respond_to? :close
892
+ end
876
893
 
877
894
  after_reply.each { |o| o.call }
878
895
  end
data/lib/puma/single.rb CHANGED
File without changes
File without changes
File without changes
File without changes
data/lib/puma/util.rb CHANGED
File without changes
data/lib/puma.rb CHANGED
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
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.6
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: 2020-09-05 00:00:00.000000000 Z
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.1.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