puma 2.1.1 → 7.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. checksums.yaml +7 -0
  2. data/History.md +3273 -0
  3. data/LICENSE +23 -20
  4. data/README.md +388 -100
  5. data/bin/puma-wild +25 -0
  6. data/bin/pumactl +1 -1
  7. data/docs/architecture.md +74 -0
  8. data/docs/compile_options.md +55 -0
  9. data/docs/deployment.md +137 -0
  10. data/docs/fork_worker.md +41 -0
  11. data/docs/images/puma-connection-flow-no-reactor.png +0 -0
  12. data/docs/images/puma-connection-flow.png +0 -0
  13. data/docs/images/puma-general-arch.png +0 -0
  14. data/docs/java_options.md +54 -0
  15. data/docs/jungle/README.md +9 -0
  16. data/docs/jungle/rc.d/README.md +74 -0
  17. data/docs/jungle/rc.d/puma +61 -0
  18. data/docs/jungle/rc.d/puma.conf +10 -0
  19. data/docs/kubernetes.md +73 -0
  20. data/docs/nginx.md +5 -5
  21. data/docs/plugins.md +42 -0
  22. data/docs/rails_dev_mode.md +28 -0
  23. data/docs/restart.md +65 -0
  24. data/docs/signals.md +98 -0
  25. data/docs/stats.md +148 -0
  26. data/docs/systemd.md +253 -0
  27. data/docs/testing_benchmarks_local_files.md +150 -0
  28. data/docs/testing_test_rackup_ci_files.md +36 -0
  29. data/ext/puma_http11/PumaHttp11Service.java +2 -2
  30. data/ext/puma_http11/extconf.rb +59 -2
  31. data/ext/puma_http11/http11_parser.c +319 -487
  32. data/ext/puma_http11/http11_parser.h +15 -13
  33. data/ext/puma_http11/http11_parser.java.rl +27 -43
  34. data/ext/puma_http11/http11_parser.rl +27 -24
  35. data/ext/puma_http11/http11_parser_common.rl +8 -8
  36. data/ext/puma_http11/mini_ssl.c +696 -38
  37. data/ext/puma_http11/no_ssl/PumaHttp11Service.java +15 -0
  38. data/ext/puma_http11/org/jruby/puma/Http11.java +145 -113
  39. data/ext/puma_http11/org/jruby/puma/Http11Parser.java +139 -172
  40. data/ext/puma_http11/org/jruby/puma/MiniSSL.java +413 -193
  41. data/ext/puma_http11/puma_http11.c +183 -175
  42. data/lib/puma/app/status.rb +77 -29
  43. data/lib/puma/binder.rb +349 -119
  44. data/lib/puma/cli.rb +164 -769
  45. data/lib/puma/client.rb +591 -132
  46. data/lib/puma/cluster/worker.rb +183 -0
  47. data/lib/puma/cluster/worker_handle.rb +127 -0
  48. data/lib/puma/cluster.rb +634 -0
  49. data/lib/puma/cluster_accept_loop_delay.rb +91 -0
  50. data/lib/puma/commonlogger.rb +115 -0
  51. data/lib/puma/configuration.rb +370 -202
  52. data/lib/puma/const.rb +266 -115
  53. data/lib/puma/control_cli.rb +219 -120
  54. data/lib/puma/detect.rb +45 -2
  55. data/lib/puma/dsl.rb +1496 -0
  56. data/lib/puma/error_logger.rb +115 -0
  57. data/lib/puma/events.rb +44 -60
  58. data/lib/puma/io_buffer.rb +48 -5
  59. data/lib/puma/jruby_restart.rb +2 -51
  60. data/lib/puma/json_serialization.rb +96 -0
  61. data/lib/puma/launcher/bundle_pruner.rb +104 -0
  62. data/lib/puma/launcher.rb +502 -0
  63. data/lib/puma/log_writer.rb +147 -0
  64. data/lib/puma/minissl/context_builder.rb +96 -0
  65. data/lib/puma/minissl.rb +355 -37
  66. data/lib/puma/null_io.rb +79 -12
  67. data/lib/puma/plugin/systemd.rb +90 -0
  68. data/lib/puma/plugin/tmp_restart.rb +36 -0
  69. data/lib/puma/plugin.rb +111 -0
  70. data/lib/puma/rack/builder.rb +297 -0
  71. data/lib/puma/rack/urlmap.rb +93 -0
  72. data/lib/puma/rack_default.rb +21 -4
  73. data/lib/puma/reactor.rb +102 -133
  74. data/lib/puma/request.rb +703 -0
  75. data/lib/puma/runner.rb +211 -0
  76. data/lib/puma/sd_notify.rb +146 -0
  77. data/lib/puma/server.rb +544 -436
  78. data/lib/puma/single.rb +72 -0
  79. data/lib/puma/state_file.rb +69 -0
  80. data/lib/puma/thread_pool.rb +282 -56
  81. data/lib/puma/util.rb +125 -0
  82. data/lib/puma.rb +80 -6
  83. data/lib/rack/handler/puma.rb +125 -47
  84. data/tools/Dockerfile +26 -0
  85. data/tools/trickletest.rb +44 -0
  86. metadata +77 -148
  87. data/COPYING +0 -55
  88. data/Gemfile +0 -10
  89. data/History.txt +0 -291
  90. data/Manifest.txt +0 -60
  91. data/Rakefile +0 -121
  92. data/TODO +0 -5
  93. data/docs/config.md +0 -0
  94. data/ext/puma_http11/ext_help.h +0 -15
  95. data/ext/puma_http11/io_buffer.c +0 -154
  96. data/lib/puma/accept_nonblock.rb +0 -23
  97. data/lib/puma/capistrano.rb +0 -34
  98. data/lib/puma/compat.rb +0 -11
  99. data/lib/puma/daemon_ext.rb +0 -20
  100. data/lib/puma/delegation.rb +0 -11
  101. data/lib/puma/java_io_buffer.rb +0 -45
  102. data/lib/puma/rack_patch.rb +0 -25
  103. data/puma.gemspec +0 -45
  104. data/test/test_app_status.rb +0 -88
  105. data/test/test_cli.rb +0 -171
  106. data/test/test_config.rb +0 -16
  107. data/test/test_http10.rb +0 -27
  108. data/test/test_http11.rb +0 -126
  109. data/test/test_integration.rb +0 -154
  110. data/test/test_iobuffer.rb +0 -38
  111. data/test/test_minissl.rb +0 -25
  112. data/test/test_null_io.rb +0 -31
  113. data/test/test_persistent.rb +0 -238
  114. data/test/test_puma_server.rb +0 -207
  115. data/test/test_rack_handler.rb +0 -10
  116. data/test/test_rack_server.rb +0 -141
  117. data/test/test_thread_pool.rb +0 -146
  118. data/test/test_unix_socket.rb +0 -39
  119. data/test/test_ws.rb +0 -89
  120. data/tools/jungle/init.d/README.md +0 -54
  121. data/tools/jungle/init.d/puma +0 -332
  122. data/tools/jungle/init.d/run-puma +0 -3
  123. data/tools/jungle/upstart/README.md +0 -61
  124. data/tools/jungle/upstart/puma-manager.conf +0 -31
  125. data/tools/jungle/upstart/puma.conf +0 -52
@@ -1,11 +1,13 @@
1
1
  /**
2
2
  * Copyright (c) 2005 Zed A. Shaw
3
3
  * You can redistribute it and/or modify it under the same terms as Ruby.
4
+ * License 3-clause BSD
4
5
  */
5
6
 
6
7
  #ifndef http11_parser_h
7
8
  #define http11_parser_h
8
9
 
10
+ #define RSTRING_NOT_MODIFIED 1
9
11
  #include "ruby.h"
10
12
 
11
13
  #include <sys/types.h>
@@ -16,19 +18,19 @@
16
18
 
17
19
  #define BUFFER_LEN 1024
18
20
 
19
- struct http_parser;
21
+ struct puma_parser;
20
22
 
21
- typedef void (*element_cb)(struct http_parser* hp,
23
+ typedef void (*element_cb)(struct puma_parser* hp,
22
24
  const char *at, size_t length);
23
25
 
24
- typedef void (*field_cb)(struct http_parser* hp,
26
+ typedef void (*field_cb)(struct puma_parser* hp,
25
27
  const char *field, size_t flen,
26
28
  const char *value, size_t vlen);
27
29
 
28
- typedef struct http_parser {
30
+ typedef struct puma_parser {
29
31
  int cs;
30
- size_t body_start;
31
32
  int content_len;
33
+ size_t body_start;
32
34
  size_t nread;
33
35
  size_t mark;
34
36
  size_t field_start;
@@ -44,20 +46,20 @@ typedef struct http_parser {
44
46
  element_cb fragment;
45
47
  element_cb request_path;
46
48
  element_cb query_string;
47
- element_cb http_version;
49
+ element_cb server_protocol;
48
50
  element_cb header_done;
49
51
 
50
52
  char buf[BUFFER_LEN];
51
53
 
52
- } http_parser;
54
+ } puma_parser;
53
55
 
54
- int http_parser_init(http_parser *parser);
55
- int http_parser_finish(http_parser *parser);
56
- size_t http_parser_execute(http_parser *parser, const char *data,
56
+ int puma_parser_init(puma_parser *parser);
57
+ int puma_parser_finish(puma_parser *parser);
58
+ size_t puma_parser_execute(puma_parser *parser, const char *data,
57
59
  size_t len, size_t off);
58
- int http_parser_has_error(http_parser *parser);
59
- int http_parser_is_finished(http_parser *parser);
60
+ int puma_parser_has_error(puma_parser *parser);
61
+ int puma_parser_is_finished(puma_parser *parser);
60
62
 
61
- #define http_parser_nread(parser) (parser)->nread
63
+ #define puma_parser_nread(parser) (parser)->nread
62
64
 
63
65
  #endif
@@ -1,5 +1,7 @@
1
1
  package org.jruby.puma;
2
2
 
3
+ import org.jruby.Ruby;
4
+ import org.jruby.RubyHash;
3
5
  import org.jruby.util.ByteList;
4
6
 
5
7
  public class Http11Parser {
@@ -7,8 +9,8 @@ public class Http11Parser {
7
9
  /** Machine **/
8
10
 
9
11
  %%{
10
-
11
- machine http_parser;
12
+
13
+ machine puma_parser;
12
14
 
13
15
  action mark {parser.mark = fpc; }
14
16
 
@@ -19,60 +21,51 @@ public class Http11Parser {
19
21
  }
20
22
 
21
23
  action start_value { parser.mark = fpc; }
22
- action write_value {
23
- if(parser.http_field != null) {
24
- parser.http_field.call(parser.data, parser.field_start, parser.field_len, parser.mark, fpc-parser.mark);
25
- }
24
+ action write_value {
25
+ Http11.http_field(runtime, parser.data, parser.buffer, parser.field_start, parser.field_len, parser.mark, fpc-parser.mark);
26
26
  }
27
- action request_method {
28
- if(parser.request_method != null)
29
- parser.request_method.call(parser.data, parser.mark, fpc-parser.mark);
27
+ action request_method {
28
+ Http11.request_method(runtime, parser.data, parser.buffer, parser.mark, fpc-parser.mark);
30
29
  }
31
- action request_uri {
32
- if(parser.request_uri != null)
33
- parser.request_uri.call(parser.data, parser.mark, fpc-parser.mark);
30
+ action request_uri {
31
+ Http11.request_uri(runtime, parser.data, parser.buffer, parser.mark, fpc-parser.mark);
34
32
  }
35
- action fragment {
36
- if(parser.fragment != null)
37
- parser.fragment.call(parser.data, parser.mark, fpc-parser.mark);
33
+ action fragment {
34
+ Http11.fragment(runtime, parser.data, parser.buffer, parser.mark, fpc-parser.mark);
38
35
  }
39
36
 
40
37
  action start_query {parser.query_start = fpc; }
41
- action query_string {
42
- if(parser.query_string != null)
43
- parser.query_string.call(parser.data, parser.query_start, fpc-parser.query_start);
38
+ action query_string {
39
+ Http11.query_string(runtime, parser.data, parser.buffer, parser.query_start, fpc-parser.query_start);
44
40
  }
45
41
 
46
- action http_version {
47
- if(parser.http_version != null)
48
- parser.http_version.call(parser.data, parser.mark, fpc-parser.mark);
42
+ action server_protocol {
43
+ Http11.server_protocol(runtime, parser.data, parser.buffer, parser.mark, fpc-parser.mark);
49
44
  }
50
45
 
51
46
  action request_path {
52
- if(parser.request_path != null)
53
- parser.request_path.call(parser.data, parser.mark, fpc-parser.mark);
47
+ Http11.request_path(runtime, parser.data, parser.buffer, parser.mark, fpc-parser.mark);
54
48
  }
55
49
 
56
50
  action done {
57
- parser.body_start = fpc + 1;
58
- if(parser.header_done != null)
59
- parser.header_done.call(parser.data, fpc + 1, pe - fpc - 1);
51
+ parser.body_start = fpc + 1;
52
+ http.header_done(runtime, parser.data, parser.buffer, fpc + 1, pe - fpc - 1);
60
53
  fbreak;
61
54
  }
62
55
 
63
- include http_parser_common "http11_parser_common.rl";
56
+ include puma_parser_common "http11_parser_common.rl";
64
57
 
65
58
  }%%
66
59
 
67
60
  /** Data **/
68
- %% write data;
61
+ %% write data noentry;
69
62
 
70
63
  public static interface ElementCB {
71
- public void call(Object data, int at, int length);
64
+ public void call(Ruby runtime, RubyHash data, ByteList buffer, int at, int length);
72
65
  }
73
66
 
74
67
  public static interface FieldCB {
75
- public void call(Object data, int field, int flen, int value, int vlen);
68
+ public void call(Ruby runtime, RubyHash data, ByteList buffer, int field, int flen, int value, int vlen);
76
69
  }
77
70
 
78
71
  public static class HttpParser {
@@ -85,18 +78,9 @@ public class Http11Parser {
85
78
  int field_len;
86
79
  int query_start;
87
80
 
88
- Object data;
81
+ RubyHash data;
89
82
  ByteList buffer;
90
83
 
91
- public FieldCB http_field;
92
- public ElementCB request_method;
93
- public ElementCB request_uri;
94
- public ElementCB fragment;
95
- public ElementCB request_path;
96
- public ElementCB query_string;
97
- public ElementCB http_version;
98
- public ElementCB header_done;
99
-
100
84
  public void init() {
101
85
  cs = 0;
102
86
 
@@ -113,7 +97,7 @@ public class Http11Parser {
113
97
 
114
98
  public final HttpParser parser = new HttpParser();
115
99
 
116
- public int execute(ByteList buffer, int off) {
100
+ public int execute(Ruby runtime, Http11 http, ByteList buffer, int off) {
117
101
  int p, pe;
118
102
  int cs = parser.cs;
119
103
  int len = buffer.length();
@@ -152,10 +136,10 @@ public class Http11Parser {
152
136
  }
153
137
 
154
138
  public boolean has_error() {
155
- return parser.cs == http_parser_error;
139
+ return parser.cs == puma_parser_error;
156
140
  }
157
141
 
158
142
  public boolean is_finished() {
159
- return parser.cs == http_parser_first_final;
143
+ return parser.cs == puma_parser_first_final;
160
144
  }
161
145
  }
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * Copyright (c) 2005 Zed A. Shaw
3
3
  * You can redistribute it and/or modify it under the same terms as Ruby.
4
+ * License 3-clause BSD
4
5
  */
5
6
  #include "http11_parser.h"
6
7
  #include <stdio.h>
@@ -11,12 +12,14 @@
11
12
 
12
13
  /*
13
14
  * capitalizes all lower-case ASCII characters,
14
- * converts dashes to underscores.
15
+ * converts dashes to underscores, and underscores to commas.
15
16
  */
16
17
  static void snake_upcase_char(char *c)
17
18
  {
18
19
  if (*c >= 'a' && *c <= 'z')
19
20
  *c &= ~0x20;
21
+ else if (*c == '_')
22
+ *c = ',';
20
23
  else if (*c == '-')
21
24
  *c = '_';
22
25
  }
@@ -28,15 +31,15 @@ static void snake_upcase_char(char *c)
28
31
  /** Machine **/
29
32
 
30
33
  %%{
31
-
32
- machine http_parser;
34
+
35
+ machine puma_parser;
33
36
 
34
37
  action mark { MARK(mark, fpc); }
35
38
 
36
39
 
37
40
  action start_field { MARK(field_start, fpc); }
38
41
  action snake_upcase_field { snake_upcase_char((char *)fpc); }
39
- action write_field {
42
+ action write_field {
40
43
  parser->field_len = LEN(field_start, fpc);
41
44
  }
42
45
 
@@ -44,10 +47,10 @@ static void snake_upcase_char(char *c)
44
47
  action write_value {
45
48
  parser->http_field(parser, PTR_TO(field_start), parser->field_len, PTR_TO(mark), LEN(mark, fpc));
46
49
  }
47
- action request_method {
50
+ action request_method {
48
51
  parser->request_method(parser, PTR_TO(mark), LEN(mark, fpc));
49
52
  }
50
- action request_uri {
53
+ action request_uri {
51
54
  parser->request_uri(parser, PTR_TO(mark), LEN(mark, fpc));
52
55
  }
53
56
  action fragment {
@@ -55,32 +58,32 @@ static void snake_upcase_char(char *c)
55
58
  }
56
59
 
57
60
  action start_query { MARK(query_start, fpc); }
58
- action query_string {
61
+ action query_string {
59
62
  parser->query_string(parser, PTR_TO(query_start), LEN(query_start, fpc));
60
63
  }
61
64
 
62
- action http_version {
63
- parser->http_version(parser, PTR_TO(mark), LEN(mark, fpc));
65
+ action server_protocol {
66
+ parser->server_protocol(parser, PTR_TO(mark), LEN(mark, fpc));
64
67
  }
65
68
 
66
69
  action request_path {
67
70
  parser->request_path(parser, PTR_TO(mark), LEN(mark,fpc));
68
71
  }
69
72
 
70
- action done {
71
- parser->body_start = fpc - buffer + 1;
73
+ action done {
74
+ parser->body_start = fpc - buffer + 1;
72
75
  parser->header_done(parser, fpc + 1, pe - fpc - 1);
73
76
  fbreak;
74
77
  }
75
78
 
76
- include http_parser_common "http11_parser_common.rl";
79
+ include puma_parser_common "http11_parser_common.rl";
77
80
 
78
81
  }%%
79
82
 
80
83
  /** Data **/
81
- %% write data;
84
+ %% write data noentry;
82
85
 
83
- int http_parser_init(http_parser *parser) {
86
+ int puma_parser_init(puma_parser *parser) {
84
87
  int cs = 0;
85
88
  %% write init;
86
89
  parser->cs = cs;
@@ -98,7 +101,7 @@ int http_parser_init(http_parser *parser) {
98
101
 
99
102
 
100
103
  /** exec **/
101
- size_t http_parser_execute(http_parser *parser, const char *buffer, size_t len, size_t off) {
104
+ size_t puma_parser_execute(puma_parser *parser, const char *buffer, size_t len, size_t off) {
102
105
  const char *p, *pe;
103
106
  int cs = parser->cs;
104
107
 
@@ -108,11 +111,11 @@ size_t http_parser_execute(http_parser *parser, const char *buffer, size_t len,
108
111
  pe = buffer+len;
109
112
 
110
113
  /* assert(*pe == '\0' && "pointer does not end on NUL"); */
111
- assert(pe - p == len - off && "pointers aren't same distance");
114
+ assert((size_t) (pe - p) == len - off && "pointers aren't same distance");
112
115
 
113
116
  %% write exec;
114
117
 
115
- if (!http_parser_has_error(parser))
118
+ if (!puma_parser_has_error(parser))
116
119
  parser->cs = cs;
117
120
  parser->nread += p - (buffer + off);
118
121
 
@@ -126,21 +129,21 @@ size_t http_parser_execute(http_parser *parser, const char *buffer, size_t len,
126
129
  return(parser->nread);
127
130
  }
128
131
 
129
- int http_parser_finish(http_parser *parser)
132
+ int puma_parser_finish(puma_parser *parser)
130
133
  {
131
- if (http_parser_has_error(parser) ) {
134
+ if (puma_parser_has_error(parser) ) {
132
135
  return -1;
133
- } else if (http_parser_is_finished(parser) ) {
136
+ } else if (puma_parser_is_finished(parser) ) {
134
137
  return 1;
135
138
  } else {
136
139
  return 0;
137
140
  }
138
141
  }
139
142
 
140
- int http_parser_has_error(http_parser *parser) {
141
- return parser->cs == http_parser_error;
143
+ int puma_parser_has_error(puma_parser *parser) {
144
+ return parser->cs == puma_parser_error;
142
145
  }
143
146
 
144
- int http_parser_is_finished(http_parser *parser) {
145
- return parser->cs >= http_parser_first_final;
147
+ int puma_parser_is_finished(puma_parser *parser) {
148
+ return parser->cs >= puma_parser_first_final;
146
149
  }
@@ -1,6 +1,6 @@
1
1
  %%{
2
-
3
- machine http_parser_common;
2
+
3
+ machine puma_parser_common;
4
4
 
5
5
  #### HTTP PROTOCOL GRAMMAR
6
6
  # line endings
@@ -15,8 +15,8 @@
15
15
  national = any -- (alpha | digit | reserved | extra | safe | unsafe);
16
16
  unreserved = (alpha | digit | safe | extra | national);
17
17
  escape = ("%" xdigit xdigit);
18
- uchar = (unreserved | escape);
19
- pchar = (uchar | ":" | "@" | "&" | "=" | "+");
18
+ uchar = (unreserved | escape | "%");
19
+ pchar = (uchar | ":" | "@" | "&" | "=" | "+" | ";");
20
20
  tspecials = ("(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\\" | "\"" | "/" | "[" | "]" | "?" | "=" | "{" | "}" | " " | "\t");
21
21
 
22
22
  # elements
@@ -30,7 +30,7 @@
30
30
  query = ( uchar | reserved )* %query_string ;
31
31
  param = ( pchar | "/" )* ;
32
32
  params = ( param ( ";" param )* ) ;
33
- rel_path = ( path? %request_path (";" params)? ) ("?" %start_query query)?;
33
+ rel_path = ( path? %request_path ) ("?" %start_query query)?;
34
34
  absolute_path = ( "/"+ rel_path );
35
35
 
36
36
  Request_URI = ( "*" | absolute_uri | absolute_path ) >mark %request_uri;
@@ -38,12 +38,12 @@
38
38
  Method = ( upper | digit | safe ){1,20} >mark %request_method;
39
39
 
40
40
  http_number = ( digit+ "." digit+ ) ;
41
- HTTP_Version = ( "HTTP/" http_number ) >mark %http_version ;
42
- Request_Line = ( Method " " Request_URI ("#" Fragment){0,1} " " HTTP_Version CRLF ) ;
41
+ Server_Protocol = ( "HTTP/" http_number ) >mark %server_protocol ;
42
+ Request_Line = ( Method " " Request_URI ("#" Fragment){0,1} " " Server_Protocol CRLF ) ;
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