puma 3.12.0 → 5.3.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of puma might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/History.md +1413 -439
- data/LICENSE +23 -20
- data/README.md +131 -60
- data/bin/puma-wild +3 -9
- data/docs/architecture.md +24 -19
- data/docs/compile_options.md +19 -0
- data/docs/deployment.md +38 -13
- data/docs/fork_worker.md +33 -0
- data/docs/jungle/README.md +9 -0
- data/{tools → docs}/jungle/rc.d/README.md +1 -1
- data/{tools → docs}/jungle/rc.d/puma +2 -2
- data/{tools → docs}/jungle/rc.d/puma.conf +0 -0
- data/docs/kubernetes.md +66 -0
- data/docs/nginx.md +1 -1
- data/docs/plugins.md +20 -10
- data/docs/rails_dev_mode.md +29 -0
- data/docs/restart.md +47 -22
- data/docs/signals.md +7 -6
- data/docs/stats.md +142 -0
- data/docs/systemd.md +48 -70
- data/ext/puma_http11/PumaHttp11Service.java +2 -2
- data/ext/puma_http11/ext_help.h +1 -1
- data/ext/puma_http11/extconf.rb +27 -0
- data/ext/puma_http11/http11_parser.c +84 -109
- data/ext/puma_http11/http11_parser.h +1 -1
- data/ext/puma_http11/http11_parser.java.rl +22 -38
- data/ext/puma_http11/http11_parser.rl +4 -2
- data/ext/puma_http11/http11_parser_common.rl +3 -3
- data/ext/puma_http11/mini_ssl.c +262 -87
- data/ext/puma_http11/no_ssl/PumaHttp11Service.java +15 -0
- data/ext/puma_http11/org/jruby/puma/Http11.java +108 -116
- data/ext/puma_http11/org/jruby/puma/Http11Parser.java +89 -106
- data/ext/puma_http11/org/jruby/puma/MiniSSL.java +92 -22
- data/ext/puma_http11/puma_http11.c +34 -50
- data/lib/puma/app/status.rb +68 -49
- data/lib/puma/binder.rb +197 -144
- data/lib/puma/cli.rb +17 -15
- data/lib/puma/client.rb +257 -226
- data/lib/puma/cluster/worker.rb +176 -0
- data/lib/puma/cluster/worker_handle.rb +90 -0
- data/lib/puma/cluster.rb +223 -212
- data/lib/puma/commonlogger.rb +4 -2
- data/lib/puma/configuration.rb +58 -51
- data/lib/puma/const.rb +41 -19
- data/lib/puma/control_cli.rb +117 -73
- data/lib/puma/detect.rb +26 -3
- data/lib/puma/dsl.rb +531 -123
- data/lib/puma/error_logger.rb +104 -0
- data/lib/puma/events.rb +57 -31
- data/lib/puma/io_buffer.rb +9 -5
- data/lib/puma/jruby_restart.rb +2 -58
- data/lib/puma/json.rb +96 -0
- data/lib/puma/launcher.rb +182 -70
- data/lib/puma/minissl/context_builder.rb +79 -0
- data/lib/puma/minissl.rb +149 -48
- data/lib/puma/null_io.rb +15 -1
- data/lib/puma/plugin/tmp_restart.rb +2 -0
- data/lib/puma/plugin.rb +8 -12
- data/lib/puma/queue_close.rb +26 -0
- data/lib/puma/rack/builder.rb +4 -5
- data/lib/puma/rack/urlmap.rb +2 -0
- data/lib/puma/rack_default.rb +2 -0
- data/lib/puma/reactor.rb +87 -316
- data/lib/puma/request.rb +456 -0
- data/lib/puma/runner.rb +33 -52
- data/lib/puma/server.rb +288 -679
- data/lib/puma/single.rb +13 -67
- data/lib/puma/state_file.rb +10 -3
- data/lib/puma/systemd.rb +46 -0
- data/lib/puma/thread_pool.rb +131 -81
- data/lib/puma/util.rb +14 -6
- data/lib/puma.rb +54 -0
- data/lib/rack/handler/puma.rb +8 -6
- data/tools/Dockerfile +16 -0
- data/tools/trickletest.rb +0 -1
- metadata +45 -29
- data/ext/puma_http11/io_buffer.c +0 -155
- data/lib/puma/accept_nonblock.rb +0 -23
- data/lib/puma/compat.rb +0 -14
- data/lib/puma/convenient.rb +0 -23
- data/lib/puma/daemon_ext.rb +0 -31
- data/lib/puma/delegation.rb +0 -11
- data/lib/puma/java_io_buffer.rb +0 -45
- data/lib/puma/rack/backports/uri/common_193.rb +0 -33
- data/lib/puma/tcp_logger.rb +0 -39
- data/tools/jungle/README.md +0 -19
- data/tools/jungle/init.d/README.md +0 -61
- data/tools/jungle/init.d/puma +0 -421
- data/tools/jungle/init.d/run-puma +0 -18
- data/tools/jungle/upstart/README.md +0 -61
- data/tools/jungle/upstart/puma-manager.conf +0 -31
- data/tools/jungle/upstart/puma.conf +0 -69
@@ -2,6 +2,8 @@
|
|
2
2
|
// line 1 "ext/puma_http11/http11_parser.java.rl"
|
3
3
|
package org.jruby.puma;
|
4
4
|
|
5
|
+
import org.jruby.Ruby;
|
6
|
+
import org.jruby.RubyHash;
|
5
7
|
import org.jruby.util.ByteList;
|
6
8
|
|
7
9
|
public class Http11Parser {
|
@@ -9,12 +11,12 @@ public class Http11Parser {
|
|
9
11
|
/** Machine **/
|
10
12
|
|
11
13
|
|
12
|
-
// line
|
14
|
+
// line 58 "ext/puma_http11/http11_parser.java.rl"
|
13
15
|
|
14
16
|
|
15
17
|
/** Data **/
|
16
18
|
|
17
|
-
// line
|
19
|
+
// line 20 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
|
18
20
|
private static byte[] init__puma_parser_actions_0()
|
19
21
|
{
|
20
22
|
return new byte [] {
|
@@ -33,8 +35,8 @@ private static short[] init__puma_parser_key_offsets_0()
|
|
33
35
|
return new short [] {
|
34
36
|
0, 0, 8, 17, 27, 29, 30, 31, 32, 33, 34, 36,
|
35
37
|
39, 41, 44, 45, 61, 62, 78, 80, 81, 89, 97, 107,
|
36
|
-
115,
|
37
|
-
|
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
|
38
40
|
};
|
39
41
|
}
|
40
42
|
|
@@ -53,24 +55,23 @@ private static char[] init__puma_parser_trans_keys_0()
|
|
53
55
|
48, 57, 65, 90, 94, 122, 13, 32, 13, 32, 60, 62,
|
54
56
|
127, 0, 31, 34, 35, 32, 60, 62, 127, 0, 31, 34,
|
55
57
|
35, 43, 58, 45, 46, 48, 57, 65, 90, 97, 122, 32,
|
56
|
-
34, 35, 60, 62, 127, 0, 31, 32, 34, 35,
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
32, 0
|
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
|
74
75
|
};
|
75
76
|
}
|
76
77
|
|
@@ -82,8 +83,8 @@ private static byte[] init__puma_parser_single_lengths_0()
|
|
82
83
|
return new byte [] {
|
83
84
|
0, 2, 3, 4, 2, 1, 1, 1, 1, 1, 0, 1,
|
84
85
|
0, 1, 1, 4, 1, 4, 2, 1, 4, 4, 2, 6,
|
85
|
-
|
86
|
-
3, 3, 3, 3, 3, 3, 3, 3, 3,
|
86
|
+
7, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
87
|
+
3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 0
|
87
88
|
};
|
88
89
|
}
|
89
90
|
|
@@ -95,8 +96,8 @@ private static byte[] init__puma_parser_range_lengths_0()
|
|
95
96
|
return new byte [] {
|
96
97
|
0, 3, 3, 3, 0, 0, 0, 0, 0, 0, 1, 1,
|
97
98
|
1, 1, 0, 6, 0, 6, 0, 0, 2, 2, 4, 1,
|
98
|
-
1, 1, 1,
|
99
|
-
3, 3, 3, 3, 3, 3, 3, 3, 3,
|
99
|
+
1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
100
|
+
3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0
|
100
101
|
};
|
101
102
|
}
|
102
103
|
|
@@ -108,8 +109,8 @@ private static short[] init__puma_parser_index_offsets_0()
|
|
108
109
|
return new short [] {
|
109
110
|
0, 0, 6, 13, 21, 24, 26, 28, 30, 32, 34, 36,
|
110
111
|
39, 41, 44, 46, 57, 59, 70, 73, 75, 82, 89, 96,
|
111
|
-
104,
|
112
|
-
|
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
|
113
114
|
};
|
114
115
|
}
|
115
116
|
|
@@ -127,21 +128,20 @@ private static byte[] init__puma_parser_indicies_0()
|
|
127
128
|
24, 23, 23, 23, 23, 23, 23, 23, 23, 1, 26, 27,
|
128
129
|
25, 29, 28, 30, 1, 1, 1, 1, 1, 31, 32, 1,
|
129
130
|
1, 1, 1, 1, 33, 34, 35, 34, 34, 34, 34, 1,
|
130
|
-
8, 1, 9, 1, 1, 1, 1, 35, 36, 1, 38,
|
131
|
-
1,
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
1, 2, 1, 1, 0
|
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
|
145
145
|
};
|
146
146
|
}
|
147
147
|
|
@@ -151,12 +151,12 @@ private static final byte _puma_parser_indicies[] = init__puma_parser_indicies_0
|
|
151
151
|
private static byte[] init__puma_parser_trans_targs_0()
|
152
152
|
{
|
153
153
|
return new byte [] {
|
154
|
-
2, 0, 3,
|
155
|
-
8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
|
154
|
+
2, 0, 3, 27, 4, 22, 24, 23, 5, 20, 6, 7,
|
155
|
+
8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 46, 17,
|
156
156
|
18, 19, 14, 18, 19, 14, 5, 21, 5, 21, 22, 23,
|
157
|
-
5, 24, 20, 25, 26,
|
158
|
-
|
159
|
-
|
157
|
+
5, 24, 20, 25, 5, 26, 20, 5, 26, 20, 28, 29,
|
158
|
+
30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
|
159
|
+
42, 43, 44, 45
|
160
160
|
};
|
161
161
|
}
|
162
162
|
|
@@ -169,9 +169,9 @@ private static byte[] init__puma_parser_trans_actions_0()
|
|
169
169
|
1, 0, 11, 0, 1, 1, 1, 1, 13, 13, 1, 0,
|
170
170
|
0, 0, 0, 0, 0, 0, 19, 0, 0, 28, 23, 3,
|
171
171
|
5, 7, 31, 7, 0, 9, 25, 1, 15, 0, 0, 0,
|
172
|
-
37, 0, 37, 21,
|
173
|
-
|
174
|
-
0, 0, 0, 0
|
172
|
+
37, 0, 37, 21, 40, 17, 40, 34, 0, 34, 0, 0,
|
173
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
174
|
+
0, 0, 0, 0
|
175
175
|
};
|
176
176
|
}
|
177
177
|
|
@@ -179,17 +179,18 @@ private static final byte _puma_parser_trans_actions[] = init__puma_parser_trans
|
|
179
179
|
|
180
180
|
|
181
181
|
static final int puma_parser_start = 1;
|
182
|
-
static final int puma_parser_first_final =
|
182
|
+
static final int puma_parser_first_final = 46;
|
183
183
|
static final int puma_parser_error = 0;
|
184
184
|
|
185
|
-
|
185
|
+
|
186
|
+
// line 62 "ext/puma_http11/http11_parser.java.rl"
|
186
187
|
|
187
188
|
public static interface ElementCB {
|
188
|
-
public void call(
|
189
|
+
public void call(Ruby runtime, RubyHash data, ByteList buffer, int at, int length);
|
189
190
|
}
|
190
191
|
|
191
192
|
public static interface FieldCB {
|
192
|
-
public void call(
|
193
|
+
public void call(Ruby runtime, RubyHash data, ByteList buffer, int field, int flen, int value, int vlen);
|
193
194
|
}
|
194
195
|
|
195
196
|
public static class HttpParser {
|
@@ -202,28 +203,19 @@ static final int puma_parser_error = 0;
|
|
202
203
|
int field_len;
|
203
204
|
int query_start;
|
204
205
|
|
205
|
-
|
206
|
+
RubyHash data;
|
206
207
|
ByteList buffer;
|
207
208
|
|
208
|
-
public FieldCB http_field;
|
209
|
-
public ElementCB request_method;
|
210
|
-
public ElementCB request_uri;
|
211
|
-
public ElementCB fragment;
|
212
|
-
public ElementCB request_path;
|
213
|
-
public ElementCB query_string;
|
214
|
-
public ElementCB http_version;
|
215
|
-
public ElementCB header_done;
|
216
|
-
|
217
209
|
public void init() {
|
218
210
|
cs = 0;
|
219
211
|
|
220
|
-
|
221
|
-
// line
|
212
|
+
|
213
|
+
// line 214 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
|
222
214
|
{
|
223
215
|
cs = puma_parser_start;
|
224
216
|
}
|
225
217
|
|
226
|
-
// line
|
218
|
+
// line 88 "ext/puma_http11/http11_parser.java.rl"
|
227
219
|
|
228
220
|
body_start = 0;
|
229
221
|
content_len = 0;
|
@@ -236,7 +228,7 @@ static final int puma_parser_error = 0;
|
|
236
228
|
|
237
229
|
public final HttpParser parser = new HttpParser();
|
238
230
|
|
239
|
-
public int execute(ByteList buffer, int off) {
|
231
|
+
public int execute(Ruby runtime, Http11 http, ByteList buffer, int off) {
|
240
232
|
int p, pe;
|
241
233
|
int cs = parser.cs;
|
242
234
|
int len = buffer.length();
|
@@ -249,8 +241,8 @@ static final int puma_parser_error = 0;
|
|
249
241
|
byte[] data = buffer.bytes();
|
250
242
|
parser.buffer = buffer;
|
251
243
|
|
252
|
-
|
253
|
-
// line
|
244
|
+
|
245
|
+
// line 246 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
|
254
246
|
{
|
255
247
|
int _klen;
|
256
248
|
int _trans = 0;
|
@@ -331,91 +323,82 @@ case 1:
|
|
331
323
|
switch ( _puma_parser_actions[_acts++] )
|
332
324
|
{
|
333
325
|
case 0:
|
334
|
-
// line
|
326
|
+
// line 15 "ext/puma_http11/http11_parser.java.rl"
|
335
327
|
{parser.mark = p; }
|
336
328
|
break;
|
337
329
|
case 1:
|
338
|
-
// line
|
330
|
+
// line 17 "ext/puma_http11/http11_parser.java.rl"
|
339
331
|
{ parser.field_start = p; }
|
340
332
|
break;
|
341
333
|
case 2:
|
342
|
-
// line
|
334
|
+
// line 18 "ext/puma_http11/http11_parser.java.rl"
|
343
335
|
{ /* FIXME stub */ }
|
344
336
|
break;
|
345
337
|
case 3:
|
346
|
-
// line
|
347
|
-
{
|
338
|
+
// line 19 "ext/puma_http11/http11_parser.java.rl"
|
339
|
+
{
|
348
340
|
parser.field_len = p-parser.field_start;
|
349
341
|
}
|
350
342
|
break;
|
351
343
|
case 4:
|
352
|
-
// line
|
344
|
+
// line 23 "ext/puma_http11/http11_parser.java.rl"
|
353
345
|
{ parser.mark = p; }
|
354
346
|
break;
|
355
347
|
case 5:
|
356
|
-
// line
|
348
|
+
// line 24 "ext/puma_http11/http11_parser.java.rl"
|
357
349
|
{
|
358
|
-
|
359
|
-
parser.http_field.call(parser.data, parser.field_start, parser.field_len, parser.mark, p-parser.mark);
|
360
|
-
}
|
350
|
+
Http11.http_field(runtime, parser.data, parser.buffer, parser.field_start, parser.field_len, parser.mark, p-parser.mark);
|
361
351
|
}
|
362
352
|
break;
|
363
353
|
case 6:
|
364
354
|
// line 27 "ext/puma_http11/http11_parser.java.rl"
|
365
355
|
{
|
366
|
-
|
367
|
-
parser.request_method.call(parser.data, parser.mark, p-parser.mark);
|
356
|
+
Http11.request_method(runtime, parser.data, parser.buffer, parser.mark, p-parser.mark);
|
368
357
|
}
|
369
358
|
break;
|
370
359
|
case 7:
|
371
|
-
// line
|
360
|
+
// line 30 "ext/puma_http11/http11_parser.java.rl"
|
372
361
|
{
|
373
|
-
|
374
|
-
parser.request_uri.call(parser.data, parser.mark, p-parser.mark);
|
362
|
+
Http11.request_uri(runtime, parser.data, parser.buffer, parser.mark, p-parser.mark);
|
375
363
|
}
|
376
364
|
break;
|
377
365
|
case 8:
|
378
|
-
// line
|
366
|
+
// line 33 "ext/puma_http11/http11_parser.java.rl"
|
379
367
|
{
|
380
|
-
|
381
|
-
parser.fragment.call(parser.data, parser.mark, p-parser.mark);
|
368
|
+
Http11.fragment(runtime, parser.data, parser.buffer, parser.mark, p-parser.mark);
|
382
369
|
}
|
383
370
|
break;
|
384
371
|
case 9:
|
385
|
-
// line
|
372
|
+
// line 37 "ext/puma_http11/http11_parser.java.rl"
|
386
373
|
{parser.query_start = p; }
|
387
374
|
break;
|
388
375
|
case 10:
|
389
|
-
// line
|
376
|
+
// line 38 "ext/puma_http11/http11_parser.java.rl"
|
390
377
|
{
|
391
|
-
|
392
|
-
parser.query_string.call(parser.data, parser.query_start, p-parser.query_start);
|
378
|
+
Http11.query_string(runtime, parser.data, parser.buffer, parser.query_start, p-parser.query_start);
|
393
379
|
}
|
394
380
|
break;
|
395
381
|
case 11:
|
396
|
-
// line
|
382
|
+
// line 42 "ext/puma_http11/http11_parser.java.rl"
|
397
383
|
{
|
398
|
-
|
399
|
-
parser.http_version.call(parser.data, parser.mark, p-parser.mark);
|
384
|
+
Http11.http_version(runtime, parser.data, parser.buffer, parser.mark, p-parser.mark);
|
400
385
|
}
|
401
386
|
break;
|
402
387
|
case 12:
|
403
|
-
// line
|
388
|
+
// line 46 "ext/puma_http11/http11_parser.java.rl"
|
404
389
|
{
|
405
|
-
|
406
|
-
parser.request_path.call(parser.data, parser.mark, p-parser.mark);
|
390
|
+
Http11.request_path(runtime, parser.data, parser.buffer, parser.mark, p-parser.mark);
|
407
391
|
}
|
408
392
|
break;
|
409
393
|
case 13:
|
410
|
-
// line
|
411
|
-
{
|
394
|
+
// line 50 "ext/puma_http11/http11_parser.java.rl"
|
395
|
+
{
|
412
396
|
parser.body_start = p + 1;
|
413
|
-
|
414
|
-
parser.header_done.call(parser.data, p + 1, pe - p - 1);
|
397
|
+
http.header_done(runtime, parser.data, parser.buffer, p + 1, pe - p - 1);
|
415
398
|
{ p += 1; _goto_targ = 5; if (true) continue _goto;}
|
416
399
|
}
|
417
400
|
break;
|
418
|
-
// line
|
401
|
+
// line 402 "ext/puma_http11/org/jruby/puma/Http11Parser.java"
|
419
402
|
}
|
420
403
|
}
|
421
404
|
}
|
@@ -435,11 +418,11 @@ case 5:
|
|
435
418
|
break; }
|
436
419
|
}
|
437
420
|
|
438
|
-
// line
|
421
|
+
// line 114 "ext/puma_http11/http11_parser.java.rl"
|
439
422
|
|
440
423
|
parser.cs = cs;
|
441
424
|
parser.nread += (p - off);
|
442
|
-
|
425
|
+
|
443
426
|
assert p <= pe : "buffer overflow after parsing execute";
|
444
427
|
assert parser.nread <= len : "nread longer than length";
|
445
428
|
assert parser.body_start <= len : "body starts after buffer end";
|
@@ -22,7 +22,9 @@ import javax.net.ssl.SSLException;
|
|
22
22
|
import javax.net.ssl.SSLPeerUnverifiedException;
|
23
23
|
import javax.net.ssl.SSLSession;
|
24
24
|
import java.io.FileInputStream;
|
25
|
+
import java.io.InputStream;
|
25
26
|
import java.io.IOException;
|
27
|
+
import java.nio.Buffer;
|
26
28
|
import java.nio.ByteBuffer;
|
27
29
|
import java.security.KeyManagementException;
|
28
30
|
import java.security.KeyStore;
|
@@ -31,6 +33,8 @@ import java.security.NoSuchAlgorithmException;
|
|
31
33
|
import java.security.UnrecoverableKeyException;
|
32
34
|
import java.security.cert.CertificateEncodingException;
|
33
35
|
import java.security.cert.CertificateException;
|
36
|
+
import java.util.concurrent.ConcurrentHashMap;
|
37
|
+
import java.util.Map;
|
34
38
|
|
35
39
|
import static javax.net.ssl.SSLEngineResult.Status;
|
36
40
|
import static javax.net.ssl.SSLEngineResult.HandshakeStatus;
|
@@ -65,7 +69,7 @@ public class MiniSSL extends RubyObject {
|
|
65
69
|
|
66
70
|
public void clear() { buffer.clear(); }
|
67
71
|
public void compact() { buffer.compact(); }
|
68
|
-
public void flip() { buffer.flip(); }
|
72
|
+
public void flip() { ((Buffer) buffer).flip(); }
|
69
73
|
public boolean hasRemaining() { return buffer.hasRemaining(); }
|
70
74
|
public int position() { return buffer.position(); }
|
71
75
|
|
@@ -89,7 +93,7 @@ public class MiniSSL extends RubyObject {
|
|
89
93
|
public void resize(int newCapacity) {
|
90
94
|
if (newCapacity > buffer.capacity()) {
|
91
95
|
ByteBuffer dstTmp = ByteBuffer.allocate(newCapacity);
|
92
|
-
|
96
|
+
flip();
|
93
97
|
dstTmp.put(buffer);
|
94
98
|
buffer = dstTmp;
|
95
99
|
} else {
|
@@ -101,7 +105,7 @@ public class MiniSSL extends RubyObject {
|
|
101
105
|
* Drains the buffer to a ByteList, or returns null for an empty buffer
|
102
106
|
*/
|
103
107
|
public ByteList asByteList() {
|
104
|
-
|
108
|
+
flip();
|
105
109
|
if (!buffer.hasRemaining()) {
|
106
110
|
buffer.clear();
|
107
111
|
return null;
|
@@ -119,6 +123,8 @@ public class MiniSSL extends RubyObject {
|
|
119
123
|
}
|
120
124
|
|
121
125
|
private SSLEngine engine;
|
126
|
+
private boolean closed;
|
127
|
+
private boolean handshake;
|
122
128
|
private MiniSSLBuffer inboundNetData;
|
123
129
|
private MiniSSLBuffer outboundAppData;
|
124
130
|
private MiniSSLBuffer outboundNetData;
|
@@ -127,10 +133,39 @@ public class MiniSSL extends RubyObject {
|
|
127
133
|
super(runtime, klass);
|
128
134
|
}
|
129
135
|
|
136
|
+
private static Map<String, KeyManagerFactory> keyManagerFactoryMap = new ConcurrentHashMap<String, KeyManagerFactory>();
|
137
|
+
private static Map<String, TrustManagerFactory> trustManagerFactoryMap = new ConcurrentHashMap<String, TrustManagerFactory>();
|
138
|
+
|
130
139
|
@JRubyMethod(meta = true)
|
131
|
-
public static IRubyObject server(ThreadContext context, IRubyObject recv, IRubyObject miniSSLContext)
|
132
|
-
|
140
|
+
public static synchronized IRubyObject server(ThreadContext context, IRubyObject recv, IRubyObject miniSSLContext)
|
141
|
+
throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException, UnrecoverableKeyException {
|
142
|
+
// Create the KeyManagerFactory and TrustManagerFactory for this server
|
143
|
+
String keystoreFile = miniSSLContext.callMethod(context, "keystore").convertToString().asJavaString();
|
144
|
+
char[] password = miniSSLContext.callMethod(context, "keystore_pass").convertToString().asJavaString().toCharArray();
|
145
|
+
|
146
|
+
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
|
147
|
+
InputStream is = new FileInputStream(keystoreFile);
|
148
|
+
try {
|
149
|
+
ks.load(is, password);
|
150
|
+
} finally {
|
151
|
+
is.close();
|
152
|
+
}
|
153
|
+
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
|
154
|
+
kmf.init(ks, password);
|
155
|
+
keyManagerFactoryMap.put(keystoreFile, kmf);
|
133
156
|
|
157
|
+
KeyStore ts = KeyStore.getInstance(KeyStore.getDefaultType());
|
158
|
+
is = new FileInputStream(keystoreFile);
|
159
|
+
try {
|
160
|
+
ts.load(is, password);
|
161
|
+
} finally {
|
162
|
+
is.close();
|
163
|
+
}
|
164
|
+
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
|
165
|
+
tmf.init(ts);
|
166
|
+
trustManagerFactoryMap.put(keystoreFile, tmf);
|
167
|
+
|
168
|
+
RubyClass klass = (RubyClass) recv;
|
134
169
|
return klass.newInstance(context,
|
135
170
|
new IRubyObject[] { miniSSLContext },
|
136
171
|
Block.NULL_BLOCK);
|
@@ -138,31 +173,39 @@ public class MiniSSL extends RubyObject {
|
|
138
173
|
|
139
174
|
@JRubyMethod
|
140
175
|
public IRubyObject initialize(ThreadContext threadContext, IRubyObject miniSSLContext)
|
141
|
-
throws KeyStoreException,
|
176
|
+
throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
|
142
177
|
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
|
143
178
|
KeyStore ts = KeyStore.getInstance(KeyStore.getDefaultType());
|
144
179
|
|
145
|
-
char[] password = miniSSLContext.callMethod(threadContext, "keystore_pass").convertToString().asJavaString().toCharArray();
|
146
180
|
String keystoreFile = miniSSLContext.callMethod(threadContext, "keystore").convertToString().asJavaString();
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
|
154
|
-
tmf.init(ts);
|
181
|
+
KeyManagerFactory kmf = keyManagerFactoryMap.get(keystoreFile);
|
182
|
+
TrustManagerFactory tmf = trustManagerFactoryMap.get(keystoreFile);
|
183
|
+
if(kmf == null || tmf == null) {
|
184
|
+
throw new KeyStoreException("Could not find KeyManagerFactory/TrustManagerFactory for keystore: " + keystoreFile);
|
185
|
+
}
|
155
186
|
|
156
187
|
SSLContext sslCtx = SSLContext.getInstance("TLS");
|
157
188
|
|
158
189
|
sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
|
190
|
+
closed = false;
|
191
|
+
handshake = false;
|
159
192
|
engine = sslCtx.createSSLEngine();
|
160
193
|
|
161
|
-
String[] protocols
|
194
|
+
String[] protocols;
|
195
|
+
if(miniSSLContext.callMethod(threadContext, "no_tlsv1").isTrue()) {
|
196
|
+
protocols = new String[] { "TLSv1.1", "TLSv1.2" };
|
197
|
+
} else {
|
198
|
+
protocols = new String[] { "TLSv1", "TLSv1.1", "TLSv1.2" };
|
199
|
+
}
|
200
|
+
|
201
|
+
if(miniSSLContext.callMethod(threadContext, "no_tlsv1_1").isTrue()) {
|
202
|
+
protocols = new String[] { "TLSv1.2" };
|
203
|
+
}
|
204
|
+
|
162
205
|
engine.setEnabledProtocols(protocols);
|
163
206
|
engine.setUseClientMode(false);
|
164
207
|
|
165
|
-
long verify_mode = miniSSLContext.callMethod(threadContext, "verify_mode").convertToInteger().getLongValue();
|
208
|
+
long verify_mode = miniSSLContext.callMethod(threadContext, "verify_mode").convertToInteger("to_i").getLongValue();
|
166
209
|
if ((verify_mode & 0x1) != 0) { // 'peer'
|
167
210
|
engine.setWantClientAuth(true);
|
168
211
|
}
|
@@ -229,14 +272,21 @@ public class MiniSSL extends RubyObject {
|
|
229
272
|
// need to wait for more data to come in before we retry
|
230
273
|
retryOp = false;
|
231
274
|
break;
|
275
|
+
case CLOSED:
|
276
|
+
closed = true;
|
277
|
+
retryOp = false;
|
278
|
+
break;
|
232
279
|
default:
|
233
|
-
// other
|
280
|
+
// other case is OK. We're done here.
|
234
281
|
retryOp = false;
|
235
282
|
}
|
283
|
+
if (res.getHandshakeStatus() == HandshakeStatus.FINISHED) {
|
284
|
+
handshake = true;
|
285
|
+
}
|
236
286
|
}
|
237
287
|
|
238
288
|
// after each op, run any delegated tasks if needed
|
239
|
-
if(
|
289
|
+
if(res.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
|
240
290
|
Runnable runnable;
|
241
291
|
while ((runnable = engine.getDelegatedTask()) != null) {
|
242
292
|
runnable.run();
|
@@ -260,13 +310,14 @@ public class MiniSSL extends RubyObject {
|
|
260
310
|
|
261
311
|
HandshakeStatus handshakeStatus = engine.getHandshakeStatus();
|
262
312
|
boolean done = false;
|
313
|
+
SSLEngineResult res = null;
|
263
314
|
while (!done) {
|
264
315
|
switch (handshakeStatus) {
|
265
316
|
case NEED_WRAP:
|
266
|
-
doOp(SSLOperation.WRAP, inboundAppData, outboundNetData);
|
317
|
+
res = doOp(SSLOperation.WRAP, inboundAppData, outboundNetData);
|
267
318
|
break;
|
268
319
|
case NEED_UNWRAP:
|
269
|
-
|
320
|
+
res = doOp(SSLOperation.UNWRAP, inboundNetData, inboundAppData);
|
270
321
|
if (res.getStatus() == Status.BUFFER_UNDERFLOW) {
|
271
322
|
// need more data before we can shake more hands
|
272
323
|
done = true;
|
@@ -275,7 +326,9 @@ public class MiniSSL extends RubyObject {
|
|
275
326
|
default:
|
276
327
|
done = true;
|
277
328
|
}
|
278
|
-
|
329
|
+
if (!done) {
|
330
|
+
handshakeStatus = res.getHandshakeStatus();
|
331
|
+
}
|
279
332
|
}
|
280
333
|
|
281
334
|
if (inboundNetData.hasRemaining()) {
|
@@ -349,4 +402,21 @@ public class MiniSSL extends RubyObject {
|
|
349
402
|
return getRuntime().getNil();
|
350
403
|
}
|
351
404
|
}
|
405
|
+
|
406
|
+
@JRubyMethod(name = "init?")
|
407
|
+
public IRubyObject isInit(ThreadContext context) {
|
408
|
+
return handshake ? getRuntime().getFalse() : getRuntime().getTrue();
|
409
|
+
}
|
410
|
+
|
411
|
+
@JRubyMethod
|
412
|
+
public IRubyObject shutdown() {
|
413
|
+
if (closed || engine.isInboundDone() && engine.isOutboundDone()) {
|
414
|
+
if (engine.isOutboundDone()) {
|
415
|
+
engine.closeOutbound();
|
416
|
+
}
|
417
|
+
return getRuntime().getTrue();
|
418
|
+
} else {
|
419
|
+
return getRuntime().getFalse();
|
420
|
+
}
|
421
|
+
}
|
352
422
|
}
|